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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 83322 - (hide 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 paulb 82641 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 jfiat 83322 make as iteration_make,
17     cursor_index as index
18 paulb 82641 redefine
19 manus 83307 start, forth, after
20 paulb 82641 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 manus 83307 after: BOOLEAN
113 paulb 82641 -- <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 jfiat 83322 Precursor
138 paulb 82641 -- 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 jfiat 83322 Precursor
220 paulb 82641
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