/[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 82641 - (hide 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 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     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