/[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 83307 - (show annotations)
Tue May 25 17:31:24 2010 UTC (9 years, 7 months ago) by manus
File size: 7759 byte(s)
Made it compile with recent changes in ITERATION_CURSOR renaming of off into after.
Fixed syntax error on `attached' which cannot just accept a manifest type since it violates the validity rules, and that's a good thing since the code was actually missing the expression `a_value'.
Removed unused local.

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, after
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 after: 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 do
220 index := index + 1
221
222 l_api := sqlite_api
223 l_stmt := statement.internal_stmt
224 l_db := statement.database
225
226 -- Note the locking sequencing, to ensure access to the error messages
227 -- are not affected by other threads.
228 l_db.lock -- (+1) 1
229 l_locked := True
230
231 l_result := sqlite3_step (l_api, l_stmt)
232 l_done := l_result = {SQLITE_RESULT_CODE}.done
233 if sqlite_success (l_result) then
234 create internal_item.make (statement)
235 else
236 internal_item := Void
237 l_exception := l_db.last_exception
238 end
239
240 -- Unlock before any callback because it may need access to the DB using another thread.
241 l_locked := False
242 l_db.unlock -- (-1) 0
243
244 -- Set last result
245 last_result := l_result
246
247 if after then
248 -- Notify the statement that execution has completed.
249 statement.on_after_executed
250 end
251
252 -- Raise an exception, if there was an exception case.
253 if attached l_exception then
254 l_exception.raise
255 else
256 sqlite_raise_on_failure (l_result)
257 end
258 rescue
259 if l_locked and attached l_db then
260 l_locked := False
261 l_db.unlock
262 end
263 end
264
265 feature {NONE} -- Implementation: Internal cache
266
267 internal_item: detachable like item
268 -- Cached version of `item'.
269 -- Note: Do not use directly!
270
271 ;note
272 copyright: "Copyright (c) 1984-2010, Eiffel Software"
273 license: "GPL version 2 (see http://www.eiffel.com/licensing/gpl.txt)"
274 licensing_options: "http://www.eiffel.com/licensing"
275 copying: "[
276 This file is part of Eiffel Software's Eiffel Development Environment.
277
278 Eiffel Software's Eiffel Development Environment is free
279 software; you can redistribute it and/or modify it under
280 the terms of the GNU General Public License as published
281 by the Free Software Foundation, version 2 of the License
282 (available at the URL listed under "license" above).
283
284 Eiffel Software's Eiffel Development Environment is
285 distributed in the hope that it will be useful, but
286 WITHOUT ANY WARRANTY; without even the implied warranty
287 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
288 See the GNU General Public License for more details.
289
290 You should have received a copy of the GNU General Public
291 License along with Eiffel Software's Eiffel Development
292 Environment; if not, write to the Free Software Foundation,
293 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
294 ]"
295 source: "[
296 Eiffel Software
297 5949 Hollister Ave., Goleta, CA 93117 USA
298 Telephone 805-685-1006, Fax 805-685-6869
299 Website http://www.eiffel.com
300 Customer support http://support.eiffel.com
301 ]"
302
303 end

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23