/[eiffelstudio]/trunk/Src/framework/sqlite3/sqlite_statement_iteration_cursor.e
ViewVC logotype

Contents of /trunk/Src/framework/sqlite3/sqlite_statement_iteration_cursor.e

Parent Directory Parent Directory | Revision Log Revision Log


Revision 82641 - (show annotations)
Mon Mar 22 18:42:30 2010 UTC (9 years, 10 months ago) by paulb
File size: 7916 byte(s)
Committed non-committed code. The code still does not compile any better though (i.e. api_pointer is unknown in the backup class.

1 note
2 description: "[
3
4 ]"
5 legal: "See notice at end of class."
6 status: "See notice at end of class."
7 date: "$Date$"
8 revision: "$Revision$"
9
10 class
11 SQLITE_STATEMENT_ITERATION_CURSOR
12
13 inherit
14 ITERATION_CURSOR [SQLITE_RESULT_ROW]
15 rename
16 make as iteration_make
17 redefine
18 start, forth, off
19 end
20
21 ITERABLE [SQLITE_RESULT_ROW]
22
23 SQLITE_SHARED_API
24 export
25 {NONE} all
26 end
27
28 SQLITE_INTERNALS
29 export
30 {NONE} all
31 end
32
33 SQLITE_DATABASE_EXTERNALS
34 export
35 {NONE} all
36 end
37
38 SQLITE_STATEMENT_EXTERNALS
39 export
40 {NONE} all
41 end
42
43 SQLITE_BIND_ARG_MARSHALLER
44 export
45 {NONE} all
46 end
47
48 create
49 make,
50 make_with_bindings
51
52 feature {NONE} -- Iniitalization
53
54 make (a_statement: SQLITE_STATEMENT)
55 --
56 require
57 a_statement_attached: attached a_statement
58 a_statement_is_accessible: a_statement.is_accessible
59 a_statement_is_connected: a_statement.is_connected
60 do
61 statement := a_statement
62 iteration_make (Current)
63 last_result := {SQLITE_RESULT_CODE}.ok
64 ensure
65 statement_statement: statement = a_statement
66 last_result_is_ok: last_result = {SQLITE_RESULT_CODE}.ok
67 end
68
69 make_with_bindings (a_statement: SQLITE_STATEMENT; a_bindings: ARRAY [SQLITE_BIND_ARG [ANY]])
70 --
71 require
72 a_statement_attached: attached a_statement
73 a_statement_is_accessible: a_statement.is_accessible
74 a_statement_is_connected: a_statement.is_connected
75 a_bindings_attached: attached a_bindings
76 not_a_bindings_is_empty: not a_bindings.is_empty
77 do
78 make (a_statement)
79 bindings := a_bindings
80 ensure
81 statement_statement: statement = a_statement
82 bindings_set: bindings = a_bindings
83 last_result_is_ok: last_result = {SQLITE_RESULT_CODE}.ok
84 end
85
86 feature -- Access
87
88 statement: SQLITE_STATEMENT
89 -- SQLite statement being iterated over.
90
91 bindings: detachable ARRAY [SQLITE_BIND_ARG [ANY]]
92 -- Binding arguments to execute the statement with.
93
94 item: SQLITE_RESULT_ROW
95 -- <Precursor>
96 local
97 l_result: like internal_item
98 do
99 l_result := internal_item
100 check l_result_attached: attached l_result end
101 Result := l_result
102 end
103
104 index: INTEGER
105 -- <Precursor>
106
107 feature {NONE} -- Access
108
109 last_result: INTEGER
110 -- Last result code set by `start'/`forth'.
111
112 feature -- Status report
113
114 off: BOOLEAN
115 -- <Precursor>
116 do
117 Result := not sqlite_success (last_result) or else last_result = {SQLITE_RESULT_CODE}.done
118 --has_started and then not attached internal_item
119 end
120
121 feature {NONE} -- Status report
122
123 has_started: BOOLEAN
124 -- Indicates if the cursor has been started yet.
125
126 feature -- Cursor movement
127
128 start
129 -- <Precursor>
130 local
131 l_api: like sqlite_api
132 l_stmt: POINTER
133 l_result: INTEGER
134 i_upper, i: INTEGER
135 l_arg_variable: IMMUTABLE_STRING_8
136 l_arg_id: C_STRING
137 l_arg_index: INTEGER
138 do
139 -- Reset the iternal item
140 internal_item := Void
141
142 l_api := sqlite_api
143 l_stmt := statement.internal_stmt
144
145 -- Reset statement, for reuse.
146 l_result := sqlite3_reset (l_api, l_stmt)
147 check success: sqlite_success (l_result) end
148
149 -- Perform bindings
150 if attached bindings as l_bindings then
151 -- `sqlite3_reset' does not reset the bindings! We have to do it as a second stage.
152 -- In a future release, when we might allow bindings to be set arbitrarily we might
153 -- not want to reset them. There is a performance gain for clients, because there is
154 -- not object marshalling required for arguments that do not change. Currently we have
155 -- to pass all arguments again when executing, and they are rebound (involving copy
156 -- operations etc.)
157 l_result := sqlite3_clear_bindings (l_api, l_stmt)
158 check success: sqlite_success (l_result) end
159
160 from
161 i := l_bindings.lower
162 i_upper := l_bindings.upper
163 until
164 i > i_upper
165 loop
166 if attached l_bindings[i] as l_arg then
167 l_arg_variable := l_arg.variable
168 create l_arg_id.make (l_arg_variable)
169 l_arg_index := sqlite3_bind_parameter_index (l_api, l_stmt, l_arg_id.item)
170 if l_arg_index = 0 and then l_arg_variable[1] = '?' then
171 l_arg_variable := l_arg_variable.substring (2, l_arg_variable.count)
172 if l_arg_variable.is_integer_32 then
173 l_arg_index := l_arg_variable.to_integer_32
174 else
175 -- Contracts in SQLITE_BIND_ARG should make this impossible.
176 check should_never_happen: False end
177 end
178 end
179
180 if l_arg_index > 0 then
181 l_arg.bind_to_statement (statement, l_arg_index)
182 else
183 -- Silently ignore unknown variables.
184 end
185 end
186 i := i + 1
187 end
188 end
189
190 last_result := l_result
191
192 -- Reset index, because `forth' will increase it.
193 index := 0
194
195 -- Raise an exception, if there was an exception case.
196 sqlite_raise_on_failure (l_result)
197
198 if not after then
199 -- Notify the statement that execution has begun.
200 statement.on_before_execute
201
202 -- Go to first element.
203 forth
204 else
205 index := 1
206 end
207 end
208
209 forth
210 -- <Precursor>
211 local
212 l_api: like sqlite_api
213 l_stmt: POINTER
214 l_db: detachable SQLITE_DATABASE
215 l_exception: detachable SQLITE_EXCEPTION
216 l_result: INTEGER
217 l_done: BOOLEAN
218 l_locked: BOOLEAN
219 l_row: SQLITE_RESULT_ROW
220 i_upper, i: INTEGER
221 l_arg_variable: IMMUTABLE_STRING_8
222 l_arg_id: C_STRING
223 l_arg_index: INTEGER
224 l_total_count: NATURAL
225 do
226 index := index + 1
227
228 l_api := sqlite_api
229 l_stmt := statement.internal_stmt
230 l_db := statement.database
231
232 -- Note the locking sequencing, to ensure access to the error messages
233 -- are not affected by other threads.
234 l_db.lock -- (+1) 1
235 l_locked := True
236
237 l_result := sqlite3_step (l_api, l_stmt)
238 l_done := l_result = {SQLITE_RESULT_CODE}.done
239 if sqlite_success (l_result) then
240 create internal_item.make (statement)
241 else
242 internal_item := Void
243 l_exception := l_db.last_exception
244 end
245
246 -- Unlock before any callback because it may need access to the DB using another thread.
247 l_locked := False
248 l_db.unlock -- (-1) 0
249
250 -- Set last result
251 last_result := l_result
252
253 if after then
254 -- Notify the statement that execution has completed.
255 statement.on_after_executed
256 end
257
258 -- Raise an exception, if there was an exception case.
259 if attached l_exception then
260 l_exception.raise
261 else
262 sqlite_raise_on_failure (l_result)
263 end
264 rescue
265 if l_locked and attached l_db then
266 l_locked := False
267 l_db.unlock
268 end
269 end
270
271 feature {NONE} -- Implementation: Internal cache
272
273 internal_item: detachable like item
274 -- Cached version of `item'.
275 -- Note: Do not use directly!
276
277 ;note
278 copyright: "Copyright (c) 1984-2010, Eiffel Software"
279 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
280 licensing_options: "http://www.eiffel.com/licensing"
281 copying: "[
282 This file is part of Eiffel Software's Eiffel Development Environment.
283
284 Eiffel Software's Eiffel Development Environment is free
285 software; you can redistribute it and/or modify it under
286 the terms of the GNU General Public License as published
287 by the Free Software Foundation, version 2 of the License
288 (available at the URL listed under "license" above).
289
290 Eiffel Software's Eiffel Development Environment is
291 distributed in the hope that it will be useful, but
292 WITHOUT ANY WARRANTY; without even the implied warranty
293 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
294 See the GNU General Public License for more details.
295
296 You should have received a copy of the GNU General Public
297 License along with Eiffel Software's Eiffel Development
298 Environment; if not, write to the Free Software Foundation,
299 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
300 ]"
301 source: "[
302 Eiffel Software
303 5949 Hollister Ave., Goleta, CA 93117 USA
304 Telephone 805-685-1006, Fax 805-685-6869
305 Website http://www.eiffel.com
306 Customer support http://support.eiffel.com
307 ]"
308
309 end

Properties

Name Value
svn:eol-style native
svn:keywords Author Date ID Revision

  ViewVC Help
Powered by ViewVC 1.1.23