/[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 83307 - (hide 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 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 manus 83307 start, forth, after
19 paulb 82641 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 manus 83307 after: BOOLEAN
115 paulb 82641 -- <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