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

Properties

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

  ViewVC Help
Powered by ViewVC 1.1.23