wasCSharpSQLite – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Diagnostics; |
||
3 | using System.Text; |
||
4 | using i64 = System.Int64; |
||
5 | using u16 = System.UInt16; |
||
6 | using u32 = System.UInt32; |
||
7 | using u64 = System.UInt64; |
||
8 | using u8 = System.Byte; |
||
9 | using sqlite3_int64 = System.Int64; |
||
10 | |||
11 | namespace Community.CsharpSqlite |
||
12 | { |
||
13 | using Op = Sqlite3.VdbeOp; |
||
14 | using sqlite_int64 = System.Int64; |
||
15 | using sqlite3_stmt = Sqlite3.Vdbe; |
||
16 | using sqlite3_value = Sqlite3.Mem; |
||
17 | |||
18 | public partial class Sqlite3 |
||
19 | { |
||
20 | /* |
||
21 | ** 2004 May 26 |
||
22 | ** |
||
23 | ** The author disclaims copyright to this source code. In place of |
||
24 | ** a legal notice, here is a blessing: |
||
25 | ** |
||
26 | ** May you do good and not evil. |
||
27 | ** May you find forgiveness for yourself and forgive others. |
||
28 | ** May you share freely, never taking more than you give. |
||
29 | ** |
||
30 | ************************************************************************* |
||
31 | ** |
||
32 | ** This file contains code use to implement APIs that are part of the |
||
33 | ** VDBE. |
||
34 | ************************************************************************* |
||
35 | ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart |
||
36 | ** C#-SQLite is an independent reimplementation of the SQLite software library |
||
37 | ** |
||
38 | ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2 |
||
39 | ** |
||
40 | ************************************************************************* |
||
41 | */ |
||
42 | //#include "sqliteInt.h" |
||
43 | //#include "vdbeInt.h" |
||
44 | |||
45 | #if !SQLITE_OMIT_DEPRECATED |
||
46 | /* |
||
47 | ** Return TRUE (non-zero) of the statement supplied as an argument needs |
||
48 | ** to be recompiled. A statement needs to be recompiled whenever the |
||
49 | ** execution environment changes in a way that would alter the program |
||
50 | ** that sqlite3_prepare() generates. For example, if new functions or |
||
51 | ** collating sequences are registered or if an authorizer function is |
||
52 | ** added or changed. |
||
53 | */ |
||
54 | static int sqlite3_expired( sqlite3_stmt pStmt ) |
||
55 | { |
||
56 | Vdbe p = (Vdbe)pStmt; |
||
57 | return ( p == null || p.expired ) ? 1 : 0; |
||
58 | } |
||
59 | #endif |
||
60 | |||
61 | /* |
||
62 | ** Check on a Vdbe to make sure it has not been finalized. Log |
||
63 | ** an error and return true if it has been finalized (or is otherwise |
||
64 | ** invalid). Return false if it is ok. |
||
65 | */ |
||
66 | static bool vdbeSafety( Vdbe p ) |
||
67 | { |
||
68 | if ( p.db == null ) |
||
69 | { |
||
70 | sqlite3_log( SQLITE_MISUSE, "API called with finalized prepared statement" ); |
||
71 | return true; |
||
72 | } |
||
73 | else |
||
74 | { |
||
75 | return false; |
||
76 | } |
||
77 | } |
||
78 | static bool vdbeSafetyNotNull( Vdbe p ) |
||
79 | { |
||
80 | if ( p == null ) |
||
81 | { |
||
82 | sqlite3_log( SQLITE_MISUSE, "API called with NULL prepared statement" ); |
||
83 | return true; |
||
84 | } |
||
85 | else |
||
86 | { |
||
87 | return vdbeSafety( p ); |
||
88 | } |
||
89 | } |
||
90 | |||
91 | /* |
||
92 | ** The following routine destroys a virtual machine that is created by |
||
93 | ** the sqlite3_compile() routine. The integer returned is an SQLITE_ |
||
94 | ** success/failure code that describes the result of executing the virtual |
||
95 | ** machine. |
||
96 | ** |
||
97 | ** This routine sets the error code and string returned by |
||
98 | ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). |
||
99 | */ |
||
100 | public static int sqlite3_finalize( sqlite3_stmt pStmt ) |
||
101 | { |
||
102 | int rc; |
||
103 | if ( pStmt == null ) |
||
104 | { |
||
105 | /* IMPLEMENTATION-OF: R-57228-12904 Invoking sqlite3_finalize() on a NULL |
||
106 | ** pointer is a harmless no-op. */ |
||
107 | rc = SQLITE_OK; |
||
108 | } |
||
109 | else |
||
110 | { |
||
111 | Vdbe v = pStmt; |
||
112 | sqlite3 db = v.db; |
||
113 | #if SQLITE_THREADSAFE |
||
114 | sqlite3_mutex mutex; |
||
115 | #endif |
||
116 | if ( vdbeSafety( v ) ) |
||
117 | return SQLITE_MISUSE_BKPT(); |
||
118 | #if SQLITE_THREADSAFE |
||
119 | mutex = v.db.mutex; |
||
120 | #endif |
||
121 | sqlite3_mutex_enter( mutex ); |
||
122 | rc = sqlite3VdbeFinalize( ref v ); |
||
123 | rc = sqlite3ApiExit( db, rc ); |
||
124 | sqlite3_mutex_leave( mutex ); |
||
125 | } |
||
126 | return rc; |
||
127 | } |
||
128 | |||
129 | /* |
||
130 | ** Terminate the current execution of an SQL statement and reset it |
||
131 | ** back to its starting state so that it can be reused. A success code from |
||
132 | ** the prior execution is returned. |
||
133 | ** |
||
134 | ** This routine sets the error code and string returned by |
||
135 | ** sqlite3_errcode(), sqlite3_errmsg() and sqlite3_errmsg16(). |
||
136 | */ |
||
137 | public static int sqlite3_reset( sqlite3_stmt pStmt ) |
||
138 | { |
||
139 | int rc; |
||
140 | if ( pStmt == null ) |
||
141 | { |
||
142 | rc = SQLITE_OK; |
||
143 | } |
||
144 | else |
||
145 | { |
||
146 | Vdbe v = (Vdbe)pStmt; |
||
147 | sqlite3_mutex_enter( v.db.mutex ); |
||
148 | rc = sqlite3VdbeReset( v ); |
||
149 | sqlite3VdbeRewind( v ); |
||
150 | Debug.Assert( ( rc & ( v.db.errMask ) ) == rc ); |
||
151 | rc = sqlite3ApiExit( v.db, rc ); |
||
152 | sqlite3_mutex_leave( v.db.mutex ); |
||
153 | } |
||
154 | return rc; |
||
155 | } |
||
156 | |||
157 | /* |
||
158 | ** Set all the parameters in the compiled SQL statement to NULL. |
||
159 | */ |
||
160 | public static int sqlite3_clear_bindings( sqlite3_stmt pStmt ) |
||
161 | { |
||
162 | int i; |
||
163 | int rc = SQLITE_OK; |
||
164 | Vdbe p = (Vdbe)pStmt; |
||
165 | #if SQLITE_THREADSAFE |
||
166 | sqlite3_mutex mutex = ( (Vdbe)pStmt ).db.mutex; |
||
167 | #endif |
||
168 | sqlite3_mutex_enter( mutex ); |
||
169 | for ( i = 0; i < p.nVar; i++ ) |
||
170 | { |
||
171 | sqlite3VdbeMemRelease( p.aVar[i] ); |
||
172 | p.aVar[i].flags = MEM_Null; |
||
173 | } |
||
174 | if ( p.isPrepareV2 && p.expmask != 0 ) |
||
175 | { |
||
176 | p.expired = true; |
||
177 | } |
||
178 | sqlite3_mutex_leave( mutex ); |
||
179 | return rc; |
||
180 | } |
||
181 | |||
182 | |||
183 | /**************************** sqlite3_value_ ******************************* |
||
184 | ** The following routines extract information from a Mem or sqlite3_value |
||
185 | ** structure. |
||
186 | */ |
||
187 | public static byte[] sqlite3_value_blob( sqlite3_value pVal ) |
||
188 | { |
||
189 | Mem p = pVal; |
||
190 | if ( ( p.flags & ( MEM_Blob | MEM_Str ) ) != 0 ) |
||
191 | { |
||
192 | ////sqlite3VdbeMemExpandBlob( p ); |
||
193 | if ( p.zBLOB == null && p.z != null ) |
||
194 | { |
||
195 | if ( p.z.Length == 0 ) |
||
196 | p.zBLOB = sqlite3Malloc( 1 ); |
||
197 | else |
||
198 | { |
||
199 | p.zBLOB = sqlite3Malloc( p.z.Length ); |
||
200 | Debug.Assert( p.zBLOB.Length == p.z.Length ); |
||
201 | for ( int i = 0; i < p.zBLOB.Length; i++ ) |
||
202 | p.zBLOB[i] = (u8)p.z[i]; |
||
203 | } |
||
204 | p.z = null; |
||
205 | } |
||
206 | p.flags = (u16)( p.flags & ~MEM_Str ); |
||
207 | p.flags |= MEM_Blob; |
||
208 | //return p.n > 0 ? p.zBLOB : null; |
||
209 | return p.zBLOB; |
||
210 | } |
||
211 | else |
||
212 | { |
||
213 | return sqlite3_value_text( pVal ) == null ? null : Encoding.UTF8.GetBytes( sqlite3_value_text( pVal ) ); |
||
214 | } |
||
215 | } |
||
216 | |||
217 | public static int sqlite3_value_bytes( sqlite3_value pVal ) |
||
218 | { |
||
219 | return sqlite3ValueBytes( pVal, SQLITE_UTF8 ); |
||
220 | } |
||
221 | |||
222 | public static int sqlite3_value_bytes16( sqlite3_value pVal ) |
||
223 | { |
||
224 | return sqlite3ValueBytes( pVal, SQLITE_UTF16NATIVE ); |
||
225 | } |
||
226 | |||
227 | public static double sqlite3_value_double( sqlite3_value pVal ) |
||
228 | { |
||
229 | return sqlite3VdbeRealValue( pVal ); |
||
230 | } |
||
231 | |||
232 | public static int sqlite3_value_int( sqlite3_value pVal ) |
||
233 | { |
||
234 | return (int)sqlite3VdbeIntValue( pVal ); |
||
235 | } |
||
236 | |||
237 | public static sqlite_int64 sqlite3_value_int64( sqlite3_value pVal ) |
||
238 | { |
||
239 | return sqlite3VdbeIntValue( pVal ); |
||
240 | } |
||
241 | |||
242 | public static string sqlite3_value_text( sqlite3_value pVal ) |
||
243 | { |
||
244 | return sqlite3ValueText( pVal, SQLITE_UTF8 ); |
||
245 | } |
||
246 | |||
247 | #if !SQLITE_OMIT_UTF16 |
||
248 | public static string sqlite3_value_text16(sqlite3_value pVal){ |
||
249 | return sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); |
||
250 | } |
||
251 | public static string sqlite3_value_text16be(sqlite3_value pVal){ |
||
252 | return sqlite3ValueText(pVal, SQLITE_UTF16BE); |
||
253 | } |
||
254 | public static string sqlite3_value_text16le(sqlite3_value pVal){ |
||
255 | return sqlite3ValueText(pVal, SQLITE_UTF16LE); |
||
256 | } |
||
257 | #endif // * SQLITE_OMIT_UTF16 */ |
||
258 | |||
259 | public static int sqlite3_value_type( sqlite3_value pval ) |
||
260 | { |
||
261 | return pval.type; |
||
262 | } |
||
263 | |||
264 | /**************************** sqlite3_result_ ******************************* |
||
265 | ** The following routines are used by user-defined functions to specify |
||
266 | ** the function result. |
||
267 | ** |
||
268 | ** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the |
||
269 | ** result as a string or blob but if the string or blob is too large, it |
||
270 | ** then sets the error code to SQLITE_TOOBIG |
||
271 | */ |
||
272 | static void setResultStrOrError( |
||
273 | sqlite3_context pCtx, /* Function context */ |
||
274 | string z, /* String pointer */ |
||
275 | int o, /* offset into string */ |
||
276 | int n, /* Bytes in string, or negative */ |
||
277 | u8 enc, /* Encoding of z. 0 for BLOBs */ |
||
278 | dxDel xDel //void (*xDel)(void) /* Destructor function */ |
||
279 | ) |
||
280 | { |
||
281 | if ( sqlite3VdbeMemSetStr( pCtx.s, z, o, n, enc, xDel ) == SQLITE_TOOBIG ) |
||
282 | { |
||
283 | sqlite3_result_error_toobig( pCtx ); |
||
284 | } |
||
285 | } |
||
286 | static void setResultStrOrError( |
||
287 | sqlite3_context pCtx, /* Function context */ |
||
288 | string z, /* String pointer */ |
||
289 | int n, /* Bytes in string, or negative */ |
||
290 | u8 enc, /* Encoding of z. 0 for BLOBs */ |
||
291 | dxDel xDel //void (*xDel)(void) /* Destructor function */ |
||
292 | ) |
||
293 | { |
||
294 | if ( sqlite3VdbeMemSetStr( pCtx.s, z, n, enc, xDel ) == SQLITE_TOOBIG ) |
||
295 | { |
||
296 | sqlite3_result_error_toobig( pCtx ); |
||
297 | } |
||
298 | } |
||
299 | |||
300 | public static void sqlite3_result_blob( |
||
301 | sqlite3_context pCtx, |
||
302 | string z, |
||
303 | int n, |
||
304 | dxDel xDel |
||
305 | ) |
||
306 | { |
||
307 | Debug.Assert( n >= 0 ); |
||
308 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
309 | setResultStrOrError( pCtx, z, n, 0, xDel ); |
||
310 | } |
||
311 | |||
312 | public static void sqlite3_result_double( sqlite3_context pCtx, double rVal ) |
||
313 | { |
||
314 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
315 | sqlite3VdbeMemSetDouble( pCtx.s, rVal ); |
||
316 | } |
||
317 | |||
318 | public static void sqlite3_result_error( sqlite3_context pCtx, string z, int n ) |
||
319 | { |
||
320 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
321 | setResultStrOrError( pCtx, z, n, SQLITE_UTF8, SQLITE_TRANSIENT ); |
||
322 | pCtx.isError = SQLITE_ERROR; |
||
323 | } |
||
324 | |||
325 | #if !SQLITE_OMIT_UTF16 |
||
326 | //void sqlite3_result_error16(sqlite3_context pCtx, string z, int n){ |
||
327 | // Debug.Assert( sqlite3_mutex_held(pCtx.s.db.mutex) ); |
||
328 | // pCtx.isError = SQLITE_ERROR; |
||
329 | // sqlite3VdbeMemSetStr(pCtx.s, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); |
||
330 | //} |
||
331 | #endif |
||
332 | |||
333 | public static void sqlite3_result_int( sqlite3_context pCtx, int iVal ) |
||
334 | { |
||
335 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
336 | sqlite3VdbeMemSetInt64( pCtx.s, (i64)iVal ); |
||
337 | } |
||
338 | |||
339 | public static void sqlite3_result_int64( sqlite3_context pCtx, i64 iVal ) |
||
340 | { |
||
341 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
342 | sqlite3VdbeMemSetInt64( pCtx.s, iVal ); |
||
343 | } |
||
344 | |||
345 | public static void sqlite3_result_null( sqlite3_context pCtx ) |
||
346 | { |
||
347 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
348 | sqlite3VdbeMemSetNull( pCtx.s ); |
||
349 | } |
||
350 | |||
351 | public static void sqlite3_result_text( |
||
352 | sqlite3_context pCtx, |
||
353 | string z, |
||
354 | int o, //Offset |
||
355 | int n, |
||
356 | dxDel xDel |
||
357 | ) |
||
358 | { |
||
359 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
360 | setResultStrOrError( pCtx, z, o, n, SQLITE_UTF8, xDel ); |
||
361 | } |
||
362 | |||
363 | public static void sqlite3_result_text( |
||
364 | sqlite3_context pCtx, |
||
365 | StringBuilder z, |
||
366 | int n, |
||
367 | dxDel xDel |
||
368 | ) |
||
369 | { |
||
370 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
371 | setResultStrOrError( pCtx, z.ToString(), n, SQLITE_UTF8, xDel ); |
||
372 | } |
||
373 | |||
374 | |||
375 | public static void sqlite3_result_text( |
||
376 | sqlite3_context pCtx, |
||
377 | string z, |
||
378 | int n, |
||
379 | dxDel xDel |
||
380 | ) |
||
381 | { |
||
382 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
383 | setResultStrOrError( pCtx, z, n, SQLITE_UTF8, xDel ); |
||
384 | } |
||
385 | #if !SQLITE_OMIT_UTF16 |
||
386 | void sqlite3_result_text16( |
||
387 | sqlite3_context pCtx, |
||
388 | string z, |
||
389 | int n, |
||
390 | dxDel xDel |
||
391 | ){ |
||
392 | Debug.Assert( sqlite3_mutex_held(pCtx.s.db.mutex) ); |
||
393 | sqlite3VdbeMemSetStr(pCtx.s, z, n, SQLITE_UTF16NATIVE, xDel); |
||
394 | } |
||
395 | void sqlite3_result_text16be( |
||
396 | sqlite3_context pCtx, |
||
397 | string z, |
||
398 | int n, |
||
399 | dxDel xDel |
||
400 | ){ |
||
401 | Debug.Assert( sqlite3_mutex_held(pCtx.s.db.mutex) ); |
||
402 | sqlite3VdbeMemSetStr(pCtx.s, z, n, SQLITE_UTF16BE, xDel); |
||
403 | } |
||
404 | void sqlite3_result_text16le( |
||
405 | sqlite3_context pCtx, |
||
406 | string z, |
||
407 | int n, |
||
408 | dxDel xDel |
||
409 | ){ |
||
410 | Debug.Assert( sqlite3_mutex_held(pCtx.s.db.mutex) ); |
||
411 | sqlite3VdbeMemSetStr(pCtx.s, z, n, SQLITE_UTF16LE, xDel); |
||
412 | } |
||
413 | #endif // * SQLITE_OMIT_UTF16 */ |
||
414 | |||
415 | public static void sqlite3_result_value( sqlite3_context pCtx, sqlite3_value pValue ) |
||
416 | { |
||
417 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
418 | sqlite3VdbeMemCopy( pCtx.s, pValue ); |
||
419 | } |
||
420 | |||
421 | public static void sqlite3_result_zeroblob( sqlite3_context pCtx, int n ) |
||
422 | { |
||
423 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
424 | sqlite3VdbeMemSetZeroBlob( pCtx.s, n ); |
||
425 | } |
||
426 | |||
427 | public static void sqlite3_result_error_code( sqlite3_context pCtx, int errCode ) |
||
428 | { |
||
429 | pCtx.isError = errCode; |
||
430 | if ( ( pCtx.s.flags & MEM_Null ) != 0 ) |
||
431 | { |
||
432 | setResultStrOrError( pCtx, sqlite3ErrStr( errCode ), -1, |
||
433 | SQLITE_UTF8, SQLITE_STATIC ); |
||
434 | } |
||
435 | } |
||
436 | |||
437 | /* Force an SQLITE_TOOBIG error. */ |
||
438 | |||
439 | public static void sqlite3_result_error_toobig( sqlite3_context pCtx ) |
||
440 | { |
||
441 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
442 | pCtx.isError = SQLITE_ERROR; |
||
443 | setResultStrOrError( pCtx, "string or blob too big", -1, |
||
444 | SQLITE_UTF8, SQLITE_STATIC ); |
||
445 | } |
||
446 | |||
447 | /* An SQLITE_NOMEM error. */ |
||
448 | public static void sqlite3_result_error_nomem( sqlite3_context pCtx ) |
||
449 | { |
||
450 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
451 | sqlite3VdbeMemSetNull( pCtx.s ); |
||
452 | pCtx.isError = SQLITE_NOMEM; |
||
453 | //pCtx.s.db.mallocFailed = 1; |
||
454 | } |
||
455 | |||
456 | /* |
||
457 | ** This function is called after a transaction has been committed. It |
||
458 | ** invokes callbacks registered with sqlite3_wal_hook() as required. |
||
459 | */ |
||
460 | static int doWalCallbacks( sqlite3 db ) |
||
461 | { |
||
462 | int rc = SQLITE_OK; |
||
463 | #if !SQLITE_OMIT_WAL |
||
464 | int i; |
||
465 | for(i=0; i<db->nDb; i++){ |
||
466 | Btree *pBt = db->aDb[i].pBt; |
||
467 | if( pBt ){ |
||
468 | int nEntry = sqlite3PagerWalCallback(sqlite3BtreePager(pBt)); |
||
469 | if( db->xWalCallback && nEntry>0 && rc==SQLITE_OK ){ |
||
470 | rc = db->xWalCallback(db->pWalArg, db, db->aDb[i].zName, nEntry); |
||
471 | } |
||
472 | } |
||
473 | } |
||
474 | #endif |
||
475 | return rc; |
||
476 | } |
||
477 | /* |
||
478 | ** Execute the statement pStmt, either until a row of data is ready, the |
||
479 | ** statement is completely executed or an error occurs. |
||
480 | ** |
||
481 | ** This routine implements the bulk of the logic behind the sqlite_step() |
||
482 | ** API. The only thing omitted is the automatic recompile if a |
||
483 | ** schema change has occurred. That detail is handled by the |
||
484 | ** outer sqlite3_step() wrapper procedure. |
||
485 | */ |
||
486 | static int sqlite3Step( Vdbe p ) |
||
487 | { |
||
488 | sqlite3 db; |
||
489 | int rc; |
||
490 | |||
491 | Debug.Assert( p != null ); |
||
492 | if ( p.magic != VDBE_MAGIC_RUN ) |
||
493 | { |
||
494 | /* We used to require that sqlite3_reset() be called before retrying |
||
495 | ** sqlite3_step() after any error or after SQLITE_DONE. But beginning |
||
496 | ** with version 3.7.0, we changed this so that sqlite3_reset() would |
||
497 | ** be called automatically instead of throwing the SQLITE_MISUSE error. |
||
498 | ** This "automatic-reset" change is not technically an incompatibility, |
||
499 | ** since any application that receives an SQLITE_MISUSE is broken by |
||
500 | ** definition. |
||
501 | ** |
||
502 | ** Nevertheless, some published applications that were originally written |
||
503 | ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE |
||
504 | ** returns, and the so were broken by the automatic-reset change. As a |
||
505 | ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the |
||
506 | ** legacy behavior of returning SQLITE_MISUSE for cases where the |
||
507 | ** previous sqlite3_step() returned something other than a SQLITE_LOCKED |
||
508 | ** or SQLITE_BUSY error. |
||
509 | */ |
||
510 | #if SQLITE_OMIT_AUTORESET |
||
511 | if( p.rc==SQLITE_BUSY || p.rc==SQLITE_LOCKED ){ |
||
512 | sqlite3_reset((sqlite3_stmt)p); |
||
513 | }else{ |
||
514 | return SQLITE_MISUSE_BKPT(); |
||
515 | } |
||
516 | #else |
||
517 | sqlite3_reset( (sqlite3_stmt)p ); |
||
518 | #endif |
||
519 | } |
||
520 | |||
521 | /* Check that malloc() has not failed. If it has, return early. */ |
||
522 | db = p.db; |
||
523 | //if ( db.mallocFailed != 0 ) |
||
524 | //{ |
||
525 | //p->rc = SQLITE_NOMEM; |
||
526 | // return SQLITE_NOMEM; |
||
527 | //} |
||
528 | |||
529 | if ( p.pc <= 0 && p.expired ) |
||
530 | { |
||
531 | p.rc = SQLITE_SCHEMA; |
||
532 | rc = SQLITE_ERROR; |
||
533 | goto end_of_step; |
||
534 | } |
||
535 | if ( p.pc < 0 ) |
||
536 | { |
||
537 | /* If there are no other statements currently running, then |
||
538 | ** reset the interrupt flag. This prevents a call to sqlite3_interrupt |
||
539 | ** from interrupting a statement that has not yet started. |
||
540 | */ |
||
541 | if ( db.activeVdbeCnt == 0 ) |
||
542 | { |
||
543 | db.u1.isInterrupted = false; |
||
544 | } |
||
545 | |||
546 | Debug.Assert( db.writeVdbeCnt > 0 || db.autoCommit == 0 || db.nDeferredCons == 0 ); |
||
547 | #if !SQLITE_OMIT_TRACE |
||
548 | if ( db.xProfile != null && 0 == db.init.busy ) |
||
549 | { |
||
550 | sqlite3OsCurrentTimeInt64( db.pVfs, ref p.startTime ); |
||
551 | } |
||
552 | #endif |
||
553 | |||
554 | db.activeVdbeCnt++; |
||
555 | if ( p.readOnly == false ) |
||
556 | db.writeVdbeCnt++; |
||
557 | p.pc = 0; |
||
558 | } |
||
559 | #if !SQLITE_OMIT_EXPLAIN |
||
560 | if ( p.explain != 0 ) |
||
561 | { |
||
562 | rc = sqlite3VdbeList( p ); |
||
563 | } |
||
564 | else |
||
565 | #endif // * SQLITE_OMIT_EXPLAIN */ |
||
566 | { |
||
567 | |||
568 | db.vdbeExecCnt++; |
||
569 | rc = sqlite3VdbeExec( p ); |
||
570 | db.vdbeExecCnt--; |
||
571 | } |
||
572 | |||
573 | #if !SQLITE_OMIT_TRACE |
||
574 | /* Invoke the profile callback if there is one |
||
575 | */ |
||
576 | if ( rc != SQLITE_ROW && db.xProfile != null && 0 == db.init.busy && p.zSql != null ) |
||
577 | { |
||
578 | sqlite3_int64 iNow = 0; |
||
579 | sqlite3OsCurrentTimeInt64( db.pVfs, ref iNow ); |
||
580 | db.xProfile( db.pProfileArg, p.zSql, ( iNow - p.startTime ) * 1000000 ); |
||
581 | } |
||
582 | #endif |
||
583 | |||
584 | if ( rc == SQLITE_DONE ) |
||
585 | { |
||
586 | Debug.Assert( p.rc == SQLITE_OK ); |
||
587 | p.rc = doWalCallbacks( db ); |
||
588 | if ( p.rc != SQLITE_OK ) |
||
589 | { |
||
590 | rc = SQLITE_ERROR; |
||
591 | } |
||
592 | } |
||
593 | |||
594 | db.errCode = rc; |
||
595 | if ( SQLITE_NOMEM == sqlite3ApiExit( p.db, p.rc ) ) |
||
596 | { |
||
597 | p.rc = SQLITE_NOMEM; |
||
598 | } |
||
599 | end_of_step: |
||
600 | /* At this point local variable rc holds the value that should be |
||
601 | ** returned if this statement was compiled using the legacy |
||
602 | ** sqlite3_prepare() interface. According to the docs, this can only |
||
603 | ** be one of the values in the first Debug.Assert() below. Variable p.rc |
||
604 | ** contains the value that would be returned if sqlite3_finalize() |
||
605 | ** were called on statement p. |
||
606 | */ |
||
607 | Debug.Assert( rc == SQLITE_ROW || rc == SQLITE_DONE || rc == SQLITE_ERROR |
||
608 | || rc == SQLITE_BUSY || rc == SQLITE_MISUSE |
||
609 | ); |
||
610 | Debug.Assert( p.rc != SQLITE_ROW && p.rc != SQLITE_DONE ); |
||
611 | if ( p.isPrepareV2 && rc != SQLITE_ROW && rc != SQLITE_DONE ) |
||
612 | { |
||
613 | /* If this statement was prepared using sqlite3_prepare_v2(), and an |
||
614 | ** error has occured, then return the error code in p.rc to the |
||
615 | ** caller. Set the error code in the database handle to the same value. |
||
616 | */ |
||
617 | rc = db.errCode = p.rc; |
||
618 | } |
||
619 | return ( rc & db.errMask ); |
||
620 | } |
||
621 | |||
622 | /* |
||
623 | ** The maximum number of times that a statement will try to reparse |
||
624 | ** itself before giving up and returning SQLITE_SCHEMA. |
||
625 | */ |
||
626 | #if !SQLITE_MAX_SCHEMA_RETRY |
||
627 | //# define SQLITE_MAX_SCHEMA_RETRY 5 |
||
628 | public const int SQLITE_MAX_SCHEMA_RETRY = 5; |
||
629 | #endif |
||
630 | |||
631 | /* |
||
632 | ** This is the top-level implementation of sqlite3_step(). Call |
||
633 | ** sqlite3Step() to do most of the work. If a schema error occurs, |
||
634 | ** call sqlite3Reprepare() and try again. |
||
635 | */ |
||
636 | public static int sqlite3_step( sqlite3_stmt pStmt ) |
||
637 | { |
||
638 | int rc = SQLITE_OK; /* Result from sqlite3Step() */ |
||
639 | int rc2 = SQLITE_OK; /* Result from sqlite3Reprepare() */ |
||
640 | Vdbe v = (Vdbe)pStmt; /* the prepared statement */ |
||
641 | int cnt = 0; /* Counter to prevent infinite loop of reprepares */ |
||
642 | sqlite3 db; /* The database connection */ |
||
643 | |||
644 | if ( vdbeSafetyNotNull( v ) ) |
||
645 | { |
||
646 | return SQLITE_MISUSE_BKPT(); |
||
647 | } |
||
648 | db = v.db; |
||
649 | sqlite3_mutex_enter( db.mutex ); |
||
650 | while ( ( rc = sqlite3Step( v ) ) == SQLITE_SCHEMA |
||
651 | && cnt++ < SQLITE_MAX_SCHEMA_RETRY |
||
652 | && ( rc2 = rc = sqlite3Reprepare( v ) ) == SQLITE_OK ) |
||
653 | { |
||
654 | sqlite3_reset( pStmt ); |
||
655 | v.expired = false; |
||
656 | } |
||
657 | if ( rc2 != SQLITE_OK && ALWAYS( v.isPrepareV2 ) && ALWAYS( db.pErr != null ) ) |
||
658 | { |
||
659 | /* This case occurs after failing to recompile an sql statement. |
||
660 | ** The error message from the SQL compiler has already been loaded |
||
661 | ** into the database handle. This block copies the error message |
||
662 | ** from the database handle into the statement and sets the statement |
||
663 | ** program counter to 0 to ensure that when the statement is |
||
664 | ** finalized or reset the parser error message is available via |
||
665 | ** sqlite3_errmsg() and sqlite3_errcode(). |
||
666 | */ |
||
667 | string zErr = sqlite3_value_text( db.pErr ); |
||
668 | sqlite3DbFree( db, ref v.zErrMsg ); |
||
669 | //if ( 0 == db.mallocFailed ) |
||
670 | { |
||
671 | v.zErrMsg = zErr;// sqlite3DbStrDup(db, zErr); |
||
672 | v.rc = rc2; |
||
673 | } |
||
674 | //else |
||
675 | //{ |
||
676 | // v.zErrMsg = string.Empty; |
||
677 | // v->rc = rc = SQLITE_NOMEM; |
||
678 | //} |
||
679 | } |
||
680 | rc = sqlite3ApiExit( db, rc ); |
||
681 | sqlite3_mutex_leave( db.mutex ); |
||
682 | return rc; |
||
683 | } |
||
684 | |||
685 | /* |
||
686 | ** Extract the user data from a sqlite3_context structure and return a |
||
687 | ** pointer to it. |
||
688 | ** |
||
689 | ** IMPLEMENTATION-OF: R-46798-50301 The sqlite3_context_db_handle() interface |
||
690 | ** returns a copy of the pointer to the database connection (the 1st |
||
691 | ** parameter) of the sqlite3_create_function() and |
||
692 | ** sqlite3_create_function16() routines that originally registered the |
||
693 | ** application defined function. |
||
694 | */ |
||
695 | public static object sqlite3_user_data( sqlite3_context p ) |
||
696 | { |
||
697 | Debug.Assert( p != null && p.pFunc != null ); |
||
698 | return p.pFunc.pUserData; |
||
699 | } |
||
700 | |||
701 | /* |
||
702 | ** Extract the user data from a sqlite3_context structure and return a |
||
703 | ** pointer to it. |
||
704 | */ |
||
705 | public static sqlite3 sqlite3_context_db_handle( sqlite3_context p ) |
||
706 | { |
||
707 | Debug.Assert( p != null && p.pFunc != null ); |
||
708 | return p.s.db; |
||
709 | } |
||
710 | |||
711 | /* |
||
712 | ** The following is the implementation of an SQL function that always |
||
713 | ** fails with an error message stating that the function is used in the |
||
714 | ** wrong context. The sqlite3_overload_function() API might construct |
||
715 | ** SQL function that use this routine so that the functions will exist |
||
716 | ** for name resolution but are actually overloaded by the xFindFunction |
||
717 | ** method of virtual tables. |
||
718 | */ |
||
719 | public static void sqlite3InvalidFunction( |
||
720 | sqlite3_context context, /* The function calling context */ |
||
721 | int NotUsed, /* Number of arguments to the function */ |
||
722 | sqlite3_value[] NotUsed2 /* Value of each argument */ |
||
723 | ) |
||
724 | { |
||
725 | string zName = context.pFunc.zName; |
||
726 | string zErr; |
||
727 | UNUSED_PARAMETER2( NotUsed, NotUsed2 ); |
||
728 | zErr = sqlite3_mprintf( |
||
729 | "unable to use function %s in the requested context", zName ); |
||
730 | sqlite3_result_error( context, zErr, -1 ); |
||
731 | //sqlite3_free( ref zErr ); |
||
732 | } |
||
733 | |||
734 | /* |
||
735 | ** Allocate or return the aggregate context for a user function. A new |
||
736 | ** context is allocated on the first call. Subsequent calls return the |
||
737 | ** same context that was returned on prior calls. |
||
738 | */ |
||
739 | public static Mem sqlite3_aggregate_context( sqlite3_context p, int nByte ) |
||
740 | { |
||
741 | Mem pMem; |
||
742 | Debug.Assert( p != null && p.pFunc != null && p.pFunc.xStep != null ); |
||
743 | Debug.Assert( sqlite3_mutex_held( p.s.db.mutex ) ); |
||
744 | pMem = p.pMem; |
||
745 | testcase( nByte < 0 ); |
||
746 | if ( ( pMem.flags & MEM_Agg ) == 0 ) |
||
747 | { |
||
748 | if ( nByte <= 0 ) |
||
749 | { |
||
750 | sqlite3VdbeMemReleaseExternal( pMem ); |
||
751 | pMem.flags = 0; |
||
752 | pMem.z = null; |
||
753 | } |
||
754 | else |
||
755 | { |
||
756 | sqlite3VdbeMemGrow( pMem, nByte, 0 ); |
||
757 | pMem.flags = MEM_Agg; |
||
758 | pMem.u.pDef = p.pFunc; |
||
759 | if ( pMem.z != null ) |
||
760 | { |
||
761 | pMem.z = null; |
||
762 | } |
||
763 | pMem._Mem = sqlite3Malloc( pMem._Mem ); |
||
764 | pMem._Mem.flags = 0; |
||
765 | pMem._Mem.z = null; |
||
766 | } |
||
767 | } |
||
768 | return pMem._Mem; |
||
769 | } |
||
770 | |||
771 | /* |
||
772 | ** Return the auxillary data pointer, if any, for the iArg'th argument to |
||
773 | ** the user-function defined by pCtx. |
||
774 | */ |
||
775 | public static object sqlite3_get_auxdata( sqlite3_context pCtx, int iArg ) |
||
776 | { |
||
777 | VdbeFunc pVdbeFunc; |
||
778 | |||
779 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
780 | pVdbeFunc = pCtx.pVdbeFunc; |
||
781 | if ( null == pVdbeFunc || iArg >= pVdbeFunc.nAux || iArg < 0 ) |
||
782 | { |
||
783 | return null; |
||
784 | } |
||
785 | return pVdbeFunc.apAux[iArg].pAux; |
||
786 | } |
||
787 | |||
788 | /* |
||
789 | ** Set the auxillary data pointer and delete function, for the iArg'th |
||
790 | ** argument to the user-function defined by pCtx. Any previous value is |
||
791 | ** deleted by calling the delete function specified when it was set. |
||
792 | */ |
||
793 | public static void sqlite3_set_auxdata( |
||
794 | sqlite3_context pCtx, |
||
795 | int iArg, |
||
796 | object pAux |
||
797 | //void (*xDelete)(void) |
||
798 | ) |
||
799 | { |
||
800 | AuxData pAuxData; |
||
801 | VdbeFunc pVdbeFunc; |
||
802 | if ( iArg < 0 ) |
||
803 | goto failed; |
||
804 | |||
805 | Debug.Assert( sqlite3_mutex_held( pCtx.s.db.mutex ) ); |
||
806 | pVdbeFunc = pCtx.pVdbeFunc; |
||
807 | if ( null == pVdbeFunc || pVdbeFunc.nAux <= iArg ) |
||
808 | { |
||
809 | int nAux = ( pVdbeFunc != null ? pVdbeFunc.nAux : 0 ); |
||
810 | ////int nMalloc = iArg; |
||
811 | //VdbeFunc+ sizeof(struct AuxData)*iArg; |
||
812 | if ( pVdbeFunc == null ) |
||
813 | { |
||
814 | //pVdbeFunc = (VdbeFunc)sqlite3DbRealloc( pCtx.s.db, pVdbeFunc, nMalloc ); |
||
815 | pVdbeFunc = new VdbeFunc(); |
||
816 | if ( null == pVdbeFunc ) |
||
817 | { |
||
818 | goto failed; |
||
819 | } |
||
820 | pCtx.pVdbeFunc = pVdbeFunc; |
||
821 | } |
||
822 | pVdbeFunc.apAux[nAux] = new AuxData();//memset(pVdbeFunc.apAux[nAux], 0, sizeof(struct AuxData)*(iArg+1-nAux)); |
||
823 | pVdbeFunc.nAux = iArg + 1; |
||
824 | pVdbeFunc.pFunc = pCtx.pFunc; |
||
825 | } |
||
826 | |||
827 | pAuxData = pVdbeFunc.apAux[iArg]; |
||
828 | if ( pAuxData.pAux != null && pAuxData.pAux is IDisposable ) |
||
829 | { |
||
830 | (pAuxData.pAux as IDisposable).Dispose(); |
||
831 | } |
||
832 | pAuxData.pAux = pAux; |
||
833 | return; |
||
834 | |||
835 | failed: |
||
836 | if ( pAux != null && pAux is IDisposable) |
||
837 | { |
||
838 | (pAux as IDisposable).Dispose(); |
||
839 | } |
||
840 | } |
||
841 | |||
842 | #if !SQLITE_OMIT_DEPRECATED |
||
843 | /* |
||
844 | ** Return the number of times the Step function of a aggregate has been |
||
845 | ** called. |
||
846 | ** |
||
847 | ** This function is deprecated. Do not use it for new code. It is |
||
848 | ** provide only to avoid breaking legacy code. New aggregate function |
||
849 | ** implementations should keep their own counts within their aggregate |
||
850 | ** context. |
||
851 | */ |
||
852 | static int sqlite3_aggregate_count( sqlite3_context p ) |
||
853 | { |
||
854 | Debug.Assert( p != null && p.pMem != null && p.pFunc != null && p.pFunc.xStep != null ); |
||
855 | return p.pMem.n; |
||
856 | } |
||
857 | #endif |
||
858 | |||
859 | /* |
||
860 | ** Return the number of columns in the result set for the statement pStmt. |
||
861 | */ |
||
862 | public static int sqlite3_column_count( sqlite3_stmt pStmt ) |
||
863 | { |
||
864 | Vdbe pVm = pStmt; |
||
865 | return pVm != null ? (int)pVm.nResColumn : 0; |
||
866 | } |
||
867 | |||
868 | /* |
||
869 | ** Return the number of values available from the current row of the |
||
870 | ** currently executing statement pStmt. |
||
871 | */ |
||
872 | public static int sqlite3_data_count( sqlite3_stmt pStmt ) |
||
873 | { |
||
874 | Vdbe pVm = pStmt; |
||
875 | if ( pVm == null || pVm.pResultSet == null ) |
||
876 | return 0; |
||
877 | return pVm.nResColumn; |
||
878 | } |
||
879 | |||
880 | |||
881 | /* |
||
882 | ** Check to see if column iCol of the given statement is valid. If |
||
883 | ** it is, return a pointer to the Mem for the value of that column. |
||
884 | ** If iCol is not valid, return a pointer to a Mem which has a value |
||
885 | ** of NULL. |
||
886 | */ |
||
887 | static Mem columnMem( sqlite3_stmt pStmt, int i ) |
||
888 | { |
||
889 | Vdbe pVm; |
||
890 | Mem pOut; |
||
891 | |||
892 | pVm = (Vdbe)pStmt; |
||
893 | if ( pVm != null && pVm.pResultSet != null && i < pVm.nResColumn && i >= 0 ) |
||
894 | { |
||
895 | sqlite3_mutex_enter( pVm.db.mutex ); |
||
896 | pOut = pVm.pResultSet[i]; |
||
897 | } |
||
898 | else |
||
899 | { |
||
900 | /* If the value passed as the second argument is out of range, return |
||
901 | ** a pointer to the following public static Mem object which contains the |
||
902 | ** value SQL NULL. Even though the Mem structure contains an element |
||
903 | ** of type i64, on certain architecture (x86) with certain compiler |
||
904 | ** switches (-Os), gcc may align this Mem object on a 4-byte boundary |
||
905 | ** instead of an 8-byte one. This all works fine, except that when |
||
906 | ** running with SQLITE_DEBUG defined the SQLite code sometimes Debug.Assert()s |
||
907 | ** that a Mem structure is located on an 8-byte boundary. To prevent |
||
908 | ** this Debug.Assert() from failing, when building with SQLITE_DEBUG defined |
||
909 | ** using gcc, force nullMem to be 8-byte aligned using the magical |
||
910 | ** __attribute__((aligned(8))) macro. */ |
||
911 | // static const Mem nullMem |
||
912 | //#if defined(SQLITE_DEBUG) && defined(__GNUC__) |
||
913 | // __attribute__((aligned(8))) |
||
914 | //#endif |
||
915 | // = {0, "", (double)0, {0}, 0, MEM_Null, SQLITE_NULL, 0, |
||
916 | //#if SQLITE_DEBUG |
||
917 | // 0, 0, /* pScopyFrom, pFiller */ |
||
918 | //#endif |
||
919 | // 0, 0 }; |
||
920 | Mem nullMem = new Mem( null, string.Empty, (double)0, 0, 0, MEM_Null, SQLITE_NULL, 0 |
||
921 | #if SQLITE_DEBUG |
||
922 | , null, null /* pScopyFrom, pFiller */ |
||
923 | #endif |
||
924 | ); |
||
925 | |||
926 | if ( pVm != null && ALWAYS( pVm.db != null ) ) |
||
927 | { |
||
928 | sqlite3_mutex_enter( pVm.db.mutex ); |
||
929 | sqlite3Error( pVm.db, SQLITE_RANGE, 0 ); |
||
930 | } |
||
931 | pOut = nullMem; |
||
932 | } |
||
933 | return pOut; |
||
934 | } |
||
935 | |||
936 | /* |
||
937 | ** This function is called after invoking an sqlite3_value_XXX function on a |
||
938 | ** column value (i.e. a value returned by evaluating an SQL expression in the |
||
939 | ** select list of a SELECT statement) that may cause a malloc() failure. If |
||
940 | ** malloc() has failed, the threads mallocFailed flag is cleared and the result |
||
941 | ** code of statement pStmt set to SQLITE_NOMEM. |
||
942 | ** |
||
943 | ** Specifically, this is called from within: |
||
944 | ** |
||
945 | ** sqlite3_column_int() |
||
946 | ** sqlite3_column_int64() |
||
947 | ** sqlite3_column_text() |
||
948 | ** sqlite3_column_text16() |
||
949 | ** sqlite3_column_real() |
||
950 | ** sqlite3_column_bytes() |
||
951 | ** sqlite3_column_bytes16() |
||
952 | ** sqlite3_column_blob() |
||
953 | */ |
||
954 | static void columnMallocFailure( sqlite3_stmt pStmt ) |
||
955 | { |
||
956 | /* If malloc() failed during an encoding conversion within an |
||
957 | ** sqlite3_column_XXX API, then set the return code of the statement to |
||
958 | ** SQLITE_NOMEM. The next call to _step() (if any) will return SQLITE_ERROR |
||
959 | ** and _finalize() will return NOMEM. |
||
960 | */ |
||
961 | Vdbe p = pStmt; |
||
962 | if ( p != null ) |
||
963 | { |
||
964 | p.rc = sqlite3ApiExit( p.db, p.rc ); |
||
965 | sqlite3_mutex_leave( p.db.mutex ); |
||
966 | } |
||
967 | } |
||
968 | |||
969 | /**************************** sqlite3_column_ ******************************* |
||
970 | ** The following routines are used to access elements of the current row |
||
971 | ** in the result set. |
||
972 | */ |
||
973 | public static byte[] sqlite3_column_blob( sqlite3_stmt pStmt, int i ) |
||
974 | { |
||
975 | byte[] val; |
||
976 | val = sqlite3_value_blob( columnMem( pStmt, i ) ); |
||
977 | /* Even though there is no encoding conversion, value_blob() might |
||
978 | ** need to call malloc() to expand the result of a zeroblob() |
||
979 | ** expression. |
||
980 | */ |
||
981 | columnMallocFailure( pStmt ); |
||
982 | return val; |
||
983 | } |
||
984 | |||
985 | public static int sqlite3_column_bytes( sqlite3_stmt pStmt, int i ) |
||
986 | { |
||
987 | int val = sqlite3_value_bytes( columnMem( pStmt, i ) ); |
||
988 | columnMallocFailure( pStmt ); |
||
989 | return val; |
||
990 | } |
||
991 | |||
992 | public static int sqlite3_column_bytes16( sqlite3_stmt pStmt, int i ) |
||
993 | { |
||
994 | int val = sqlite3_value_bytes16( columnMem( pStmt, i ) ); |
||
995 | columnMallocFailure( pStmt ); |
||
996 | return val; |
||
997 | } |
||
998 | |||
999 | public static double sqlite3_column_double( sqlite3_stmt pStmt, int i ) |
||
1000 | { |
||
1001 | double val = sqlite3_value_double( columnMem( pStmt, i ) ); |
||
1002 | columnMallocFailure( pStmt ); |
||
1003 | return val; |
||
1004 | } |
||
1005 | |||
1006 | public static int sqlite3_column_int( sqlite3_stmt pStmt, int i ) |
||
1007 | { |
||
1008 | int val = sqlite3_value_int( columnMem( pStmt, i ) ); |
||
1009 | columnMallocFailure( pStmt ); |
||
1010 | return val; |
||
1011 | } |
||
1012 | |||
1013 | |||
1014 | public static sqlite_int64 sqlite3_column_int64( sqlite3_stmt pStmt, int i ) |
||
1015 | { |
||
1016 | sqlite_int64 val = sqlite3_value_int64( columnMem( pStmt, i ) ); |
||
1017 | columnMallocFailure( pStmt ); |
||
1018 | return val; |
||
1019 | } |
||
1020 | |||
1021 | public static string sqlite3_column_text( sqlite3_stmt pStmt, int i ) |
||
1022 | { |
||
1023 | string val = sqlite3_value_text( columnMem( pStmt, i ) ); |
||
1024 | columnMallocFailure( pStmt ); |
||
1025 | return val; |
||
1026 | } |
||
1027 | |||
1028 | public static sqlite3_value sqlite3_column_value( sqlite3_stmt pStmt, int i ) |
||
1029 | { |
||
1030 | Mem pOut = columnMem( pStmt, i ); |
||
1031 | if ( ( pOut.flags & MEM_Static ) != 0 ) |
||
1032 | { |
||
1033 | pOut.flags = (u16)( pOut.flags & ~MEM_Static ); |
||
1034 | pOut.flags |= MEM_Ephem; |
||
1035 | } |
||
1036 | columnMallocFailure( pStmt ); |
||
1037 | return (sqlite3_value)pOut; |
||
1038 | } |
||
1039 | #if !SQLITE_OMIT_UTF16 |
||
1040 | //const void *sqlite3_column_text16(sqlite3_stmt pStmt, int i){ |
||
1041 | // const void *val = sqlite3_value_text16( columnMem(pStmt,i) ); |
||
1042 | // columnMallocFailure(pStmt); |
||
1043 | // return val; |
||
1044 | //} |
||
1045 | #endif // * SQLITE_OMIT_UTF16 */ |
||
1046 | |||
1047 | public static int sqlite3_column_type( sqlite3_stmt pStmt, int i ) |
||
1048 | { |
||
1049 | int iType = sqlite3_value_type( columnMem( pStmt, i ) ); |
||
1050 | columnMallocFailure( pStmt ); |
||
1051 | return iType; |
||
1052 | } |
||
1053 | |||
1054 | /* The following function is experimental and subject to change or |
||
1055 | ** removal */ |
||
1056 | /*int sqlite3_column_numeric_type(sqlite3_stmt pStmt, int i){ |
||
1057 | ** return sqlite3_value_numeric_type( columnMem(pStmt,i) ); |
||
1058 | **} |
||
1059 | */ |
||
1060 | |||
1061 | /* |
||
1062 | ** Convert the N-th element of pStmt.pColName[] into a string using |
||
1063 | ** xFunc() then return that string. If N is out of range, return 0. |
||
1064 | ** |
||
1065 | ** There are up to 5 names for each column. useType determines which |
||
1066 | ** name is returned. Here are the names: |
||
1067 | ** |
||
1068 | ** 0 The column name as it should be displayed for output |
||
1069 | ** 1 The datatype name for the column |
||
1070 | ** 2 The name of the database that the column derives from |
||
1071 | ** 3 The name of the table that the column derives from |
||
1072 | ** 4 The name of the table column that the result column derives from |
||
1073 | ** |
||
1074 | ** If the result is not a simple column reference (if it is an expression |
||
1075 | ** or a constant) then useTypes 2, 3, and 4 return NULL. |
||
1076 | */ |
||
1077 | public static string columnName( |
||
1078 | sqlite3_stmt pStmt, |
||
1079 | int N, |
||
1080 | dxColname xFunc, |
||
1081 | int useType |
||
1082 | ) |
||
1083 | { |
||
1084 | string ret = null; |
||
1085 | Vdbe p = pStmt; |
||
1086 | int n; |
||
1087 | sqlite3 db = p.db; |
||
1088 | |||
1089 | Debug.Assert( db != null ); |
||
1090 | |||
1091 | n = sqlite3_column_count( pStmt ); |
||
1092 | if ( N < n && N >= 0 ) |
||
1093 | { |
||
1094 | N += useType * n; |
||
1095 | sqlite3_mutex_enter( db.mutex ); |
||
1096 | //Debug.Assert( db.mallocFailed == 0 ); |
||
1097 | ret = xFunc( p.aColName[N] ); |
||
1098 | |||
1099 | /* A malloc may have failed inside of the xFunc() call. If this |
||
1100 | ** is the case, clear the mallocFailed flag and return NULL. |
||
1101 | */ |
||
1102 | //if ( db.mallocFailed != 0 ) |
||
1103 | //{ |
||
1104 | // //db.mallocFailed = 0; |
||
1105 | // ret = null; |
||
1106 | //} |
||
1107 | sqlite3_mutex_leave( db.mutex ); |
||
1108 | } |
||
1109 | return ret; |
||
1110 | } |
||
1111 | |||
1112 | /* |
||
1113 | ** Return the name of the Nth column of the result set returned by SQL |
||
1114 | ** statement pStmt. |
||
1115 | */ |
||
1116 | public static string sqlite3_column_name( sqlite3_stmt pStmt, int N ) |
||
1117 | { |
||
1118 | return columnName( |
||
1119 | pStmt, N, sqlite3_value_text, COLNAME_NAME ); |
||
1120 | } |
||
1121 | #if !SQLITE_OMIT_UTF16 |
||
1122 | public static string sqlite3_column_name16(sqlite3_stmt pStmt, int N){ |
||
1123 | return columnName( |
||
1124 | pStmt, N, sqlite3_value_text16, COLNAME_NAME); |
||
1125 | } |
||
1126 | #endif |
||
1127 | |||
1128 | /* |
||
1129 | ** Constraint: If you have ENABLE_COLUMN_METADATA then you must |
||
1130 | ** not define OMIT_DECLTYPE. |
||
1131 | */ |
||
1132 | #if SQLITE_OMIT_DECLTYPE && SQLITE_ENABLE_COLUMN_METADATA |
||
1133 | # error "Must not define both SQLITE_OMIT_DECLTYPE and SQLITE_ENABLE_COLUMN_METADATA" |
||
1134 | #endif |
||
1135 | |||
1136 | #if !SQLITE_OMIT_DECLTYPE |
||
1137 | /* |
||
1138 | ** Return the column declaration type (if applicable) of the 'i'th column |
||
1139 | ** of the result set of SQL statement pStmt. |
||
1140 | */ |
||
1141 | public static string sqlite3_column_decltype( sqlite3_stmt pStmt, int N ) |
||
1142 | { |
||
1143 | return columnName( |
||
1144 | pStmt, N, sqlite3_value_text, COLNAME_DECLTYPE ); |
||
1145 | } |
||
1146 | #if !SQLITE_OMIT_UTF16 |
||
1147 | //const void *sqlite3_column_decltype16(sqlite3_stmt pStmt, int N){ |
||
1148 | // return columnName( |
||
1149 | // pStmt, N, (const void*()(Mem))sqlite3_value_text16, COLNAME_DECLTYPE); |
||
1150 | //} |
||
1151 | #endif // * SQLITE_OMIT_UTF16 */ |
||
1152 | #endif // * SQLITE_OMIT_DECLTYPE */ |
||
1153 | |||
1154 | #if SQLITE_ENABLE_COLUMN_METADATA |
||
1155 | |||
1156 | /* |
||
1157 | ** Return the name of the database from which a result column derives. |
||
1158 | ** NULL is returned if the result column is an expression or constant or |
||
1159 | ** anything else which is not an unabiguous reference to a database column. |
||
1160 | */ |
||
1161 | public static string sqlite3_column_database_name( sqlite3_stmt pStmt, int N ) |
||
1162 | { |
||
1163 | return columnName( |
||
1164 | pStmt, N, sqlite3_value_text, COLNAME_DATABASE ); |
||
1165 | } |
||
1166 | #if !SQLITE_OMIT_UTF16 |
||
1167 | const void *sqlite3_column_database_name16(sqlite3_stmt pStmt, int N){ |
||
1168 | return columnName( |
||
1169 | pStmt, N, (const void*()(Mem))sqlite3_value_text16, COLNAME_DATABASE); |
||
1170 | } |
||
1171 | #endif //* SQLITE_OMIT_UTF16 */ |
||
1172 | |||
1173 | /* |
||
1174 | ** Return the name of the table from which a result column derives. |
||
1175 | ** NULL is returned if the result column is an expression or constant or |
||
1176 | ** anything else which is not an unabiguous reference to a database column. |
||
1177 | */ |
||
1178 | public static string sqlite3_column_table_name( sqlite3_stmt pStmt, int N ) |
||
1179 | { |
||
1180 | return columnName( |
||
1181 | pStmt, N, sqlite3_value_text, COLNAME_TABLE ); |
||
1182 | } |
||
1183 | #if !SQLITE_OMIT_UTF16 |
||
1184 | const void *sqlite3_column_table_name16(sqlite3_stmt pStmt, int N){ |
||
1185 | return columnName( |
||
1186 | pStmt, N, (const void*()(Mem))sqlite3_value_text16, COLNAME_TABLE); |
||
1187 | } |
||
1188 | #endif //* SQLITE_OMIT_UTF16 */ |
||
1189 | |||
1190 | /* |
||
1191 | ** Return the name of the table column from which a result column derives. |
||
1192 | ** NULL is returned if the result column is an expression or constant or |
||
1193 | ** anything else which is not an unabiguous reference to a database column. |
||
1194 | */ |
||
1195 | public static string sqlite3_column_origin_name( sqlite3_stmt pStmt, int N ) |
||
1196 | { |
||
1197 | return columnName( |
||
1198 | pStmt, N, sqlite3_value_text, COLNAME_COLUMN ); |
||
1199 | } |
||
1200 | #if !SQLITE_OMIT_UTF16 |
||
1201 | const void *sqlite3_column_origin_name16(sqlite3_stmt pStmt, int N){ |
||
1202 | return columnName( |
||
1203 | pStmt, N, (const void*()(Mem))sqlite3_value_text16, COLNAME_COLUMN); |
||
1204 | } |
||
1205 | #endif ///* SQLITE_OMIT_UTF16 */ |
||
1206 | #endif // * SQLITE_ENABLE_COLUMN_METADATA */ |
||
1207 | |||
1208 | |||
1209 | /******************************* sqlite3_bind_ *************************** |
||
1210 | ** |
||
1211 | ** Routines used to attach values to wildcards in a compiled SQL statement. |
||
1212 | */ |
||
1213 | /* |
||
1214 | ** Unbind the value bound to variable i in virtual machine p. This is the |
||
1215 | ** the same as binding a NULL value to the column. If the "i" parameter is |
||
1216 | ** out of range, then SQLITE_RANGE is returned. Othewise SQLITE_OK. |
||
1217 | ** |
||
1218 | ** A successful evaluation of this routine acquires the mutex on p. |
||
1219 | ** the mutex is released if any kind of error occurs. |
||
1220 | ** |
||
1221 | ** The error code stored in database p.db is overwritten with the return |
||
1222 | ** value in any case. |
||
1223 | */ |
||
1224 | public static int vdbeUnbind( Vdbe p, int i ) |
||
1225 | { |
||
1226 | Mem pVar; |
||
1227 | if ( vdbeSafetyNotNull( p ) ) |
||
1228 | { |
||
1229 | return SQLITE_MISUSE_BKPT(); |
||
1230 | } |
||
1231 | sqlite3_mutex_enter( p.db.mutex ); |
||
1232 | if ( p.magic != VDBE_MAGIC_RUN || p.pc >= 0 ) |
||
1233 | { |
||
1234 | sqlite3Error( p.db, SQLITE_MISUSE, 0 ); |
||
1235 | sqlite3_mutex_leave( p.db.mutex ); |
||
1236 | sqlite3_log( SQLITE_MISUSE, |
||
1237 | "bind on a busy prepared statement: [%s]", p.zSql ); |
||
1238 | return SQLITE_MISUSE_BKPT(); |
||
1239 | } |
||
1240 | if ( i < 1 || i > p.nVar ) |
||
1241 | { |
||
1242 | sqlite3Error( p.db, SQLITE_RANGE, 0 ); |
||
1243 | sqlite3_mutex_leave( p.db.mutex ); |
||
1244 | return SQLITE_RANGE; |
||
1245 | } |
||
1246 | i--; |
||
1247 | pVar = p.aVar[i]; |
||
1248 | sqlite3VdbeMemRelease( pVar ); |
||
1249 | pVar.flags = MEM_Null; |
||
1250 | sqlite3Error( p.db, SQLITE_OK, 0 ); |
||
1251 | |||
1252 | /* If the bit corresponding to this variable in Vdbe.expmask is set, then |
||
1253 | ** binding a new value to this variable invalidates the current query plan. |
||
1254 | ** |
||
1255 | ** IMPLEMENTATION-OF: R-48440-37595 If the specific value bound to host |
||
1256 | ** parameter in the WHERE clause might influence the choice of query plan |
||
1257 | ** for a statement, then the statement will be automatically recompiled, |
||
1258 | ** as if there had been a schema change, on the first sqlite3_step() call |
||
1259 | ** following any change to the bindings of that parameter. |
||
1260 | */ |
||
1261 | if ( p.isPrepareV2 && |
||
1262 | ( ( i < 32 && p.expmask != 0 & ( (u32)1 << i ) != 0 ) || p.expmask == 0xffffffff ) |
||
1263 | ) |
||
1264 | { |
||
1265 | p.expired = true; |
||
1266 | } |
||
1267 | |||
1268 | return SQLITE_OK; |
||
1269 | } |
||
1270 | |||
1271 | /* |
||
1272 | ** Bind a text or BLOB value. |
||
1273 | */ |
||
1274 | static int bindBlob( |
||
1275 | sqlite3_stmt pStmt, /* The statement to bind against */ |
||
1276 | int i, /* Index of the parameter to bind */ |
||
1277 | byte[] zData, /* Pointer to the data to be bound */ |
||
1278 | int nData, /* Number of bytes of data to be bound */ |
||
1279 | dxDel xDel, /* Destructor for the data */ |
||
1280 | u8 encoding /* Encoding for the data */ |
||
1281 | ) |
||
1282 | { |
||
1283 | Vdbe p = pStmt; |
||
1284 | Mem pVar; |
||
1285 | int rc; |
||
1286 | |||
1287 | rc = vdbeUnbind( p, i ); |
||
1288 | if ( rc == SQLITE_OK ) |
||
1289 | { |
||
1290 | if ( zData != null ) |
||
1291 | { |
||
1292 | pVar = p.aVar[i - 1]; |
||
1293 | rc = sqlite3VdbeMemSetBlob( pVar, zData, nData, encoding, xDel ); |
||
1294 | if ( rc == SQLITE_OK && encoding != 0 ) |
||
1295 | { |
||
1296 | rc = sqlite3VdbeChangeEncoding( pVar, ENC( p.db ) ); |
||
1297 | } |
||
1298 | sqlite3Error( p.db, rc, 0 ); |
||
1299 | rc = sqlite3ApiExit( p.db, rc ); |
||
1300 | } |
||
1301 | sqlite3_mutex_leave( p.db.mutex ); |
||
1302 | } |
||
1303 | return rc; |
||
1304 | } |
||
1305 | |||
1306 | /* |
||
1307 | ** Bind a text value. |
||
1308 | */ |
||
1309 | public static int bindText( |
||
1310 | sqlite3_stmt pStmt, /* The statement to bind against */ |
||
1311 | int i, /* Index of the parameter to bind */ |
||
1312 | string zData, /* Pointer to the data to be bound */ |
||
1313 | int nData, /* Number of bytes of data to be bound */ |
||
1314 | dxDel xDel, /* Destructor for the data */ |
||
1315 | u8 encoding /* Encoding for the data */ |
||
1316 | ) |
||
1317 | { |
||
1318 | Vdbe p = pStmt; |
||
1319 | Mem pVar; |
||
1320 | int rc; |
||
1321 | |||
1322 | rc = vdbeUnbind( p, i ); |
||
1323 | if ( rc == SQLITE_OK ) |
||
1324 | { |
||
1325 | if ( zData != null ) |
||
1326 | { |
||
1327 | pVar = p.aVar[i - 1]; |
||
1328 | rc = sqlite3VdbeMemSetStr( pVar, zData, nData, encoding, xDel ); |
||
1329 | if ( rc == SQLITE_OK && encoding != 0 ) |
||
1330 | { |
||
1331 | rc = sqlite3VdbeChangeEncoding( pVar, ENC( p.db ) ); |
||
1332 | } |
||
1333 | sqlite3Error( p.db, rc, 0 ); |
||
1334 | rc = sqlite3ApiExit( p.db, rc ); |
||
1335 | } |
||
1336 | sqlite3_mutex_leave( p.db.mutex ); |
||
1337 | } |
||
1338 | else if ( xDel != SQLITE_STATIC && xDel != SQLITE_TRANSIENT ) |
||
1339 | { |
||
1340 | xDel( ref zData ); |
||
1341 | } |
||
1342 | return rc; |
||
1343 | } |
||
1344 | |||
1345 | public static int sqlite3_bind_double( sqlite3_stmt pStmt, int i, double rValue ) |
||
1346 | { |
||
1347 | int rc; |
||
1348 | Vdbe p = pStmt; |
||
1349 | rc = vdbeUnbind( p, i ); |
||
1350 | if ( rc == SQLITE_OK ) |
||
1351 | { |
||
1352 | sqlite3VdbeMemSetDouble( p.aVar[i - 1], rValue ); |
||
1353 | sqlite3_mutex_leave( p.db.mutex ); |
||
1354 | } |
||
1355 | return rc; |
||
1356 | } |
||
1357 | |||
1358 | public static int sqlite3_bind_int( sqlite3_stmt p, int i, int iValue ) |
||
1359 | { |
||
1360 | return sqlite3_bind_int64( p, i, (i64)iValue ); |
||
1361 | } |
||
1362 | |||
1363 | public static int sqlite3_bind_int64( sqlite3_stmt pStmt, int i, sqlite_int64 iValue ) |
||
1364 | { |
||
1365 | int rc; |
||
1366 | Vdbe p = pStmt; |
||
1367 | rc = vdbeUnbind( p, i ); |
||
1368 | if ( rc == SQLITE_OK ) |
||
1369 | { |
||
1370 | sqlite3VdbeMemSetInt64( p.aVar[i - 1], iValue ); |
||
1371 | sqlite3_mutex_leave( p.db.mutex ); |
||
1372 | } |
||
1373 | return rc; |
||
1374 | } |
||
1375 | |||
1376 | public static int sqlite3_bind_null( sqlite3_stmt pStmt, int i ) |
||
1377 | { |
||
1378 | int rc; |
||
1379 | Vdbe p = (Vdbe)pStmt; |
||
1380 | rc = vdbeUnbind( p, i ); |
||
1381 | if ( rc == SQLITE_OK ) |
||
1382 | { |
||
1383 | sqlite3_mutex_leave( p.db.mutex ); |
||
1384 | } |
||
1385 | return rc; |
||
1386 | } |
||
1387 | |||
1388 | public static int sqlite3_bind_text( |
||
1389 | sqlite3_stmt pStmt, |
||
1390 | int i, |
||
1391 | string zData, |
||
1392 | int nData, |
||
1393 | dxDel xDel |
||
1394 | ) |
||
1395 | { |
||
1396 | return bindText( pStmt, i, zData, nData, xDel, SQLITE_UTF8 ); |
||
1397 | } |
||
1398 | |||
1399 | public static int sqlite3_bind_blob( |
||
1400 | sqlite3_stmt pStmt, |
||
1401 | int i, |
||
1402 | byte[] zData, |
||
1403 | int nData, |
||
1404 | dxDel xDel |
||
1405 | ) |
||
1406 | { |
||
1407 | return bindBlob( pStmt, i, zData, nData >= 0 ? nData : zData.Length, xDel, 0 ); |
||
1408 | } |
||
1409 | |||
1410 | #if !SQLITE_OMIT_UTF16 |
||
1411 | static int sqlite3_bind_text16( |
||
1412 | sqlite3_stmt pStmt, |
||
1413 | int i, |
||
1414 | string zData, |
||
1415 | int nData, |
||
1416 | dxDel xDel |
||
1417 | ){ |
||
1418 | return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF16NATIVE); |
||
1419 | } |
||
1420 | #endif // * SQLITE_OMIT_UTF16 */ |
||
1421 | |||
1422 | public static int sqlite3_bind_value( sqlite3_stmt pStmt, int i, sqlite3_value pValue ) |
||
1423 | { |
||
1424 | int rc; |
||
1425 | switch ( pValue.type ) |
||
1426 | { |
||
1427 | case SQLITE_INTEGER: |
||
1428 | { |
||
1429 | rc = sqlite3_bind_int64( pStmt, i, pValue.u.i ); |
||
1430 | break; |
||
1431 | } |
||
1432 | case SQLITE_FLOAT: |
||
1433 | { |
||
1434 | rc = sqlite3_bind_double( pStmt, i, pValue.r ); |
||
1435 | break; |
||
1436 | } |
||
1437 | case SQLITE_BLOB: |
||
1438 | { |
||
1439 | if ( ( pValue.flags & MEM_Zero ) != 0 ) |
||
1440 | { |
||
1441 | rc = sqlite3_bind_zeroblob( pStmt, i, pValue.u.nZero ); |
||
1442 | } |
||
1443 | else |
||
1444 | { |
||
1445 | rc = sqlite3_bind_blob( pStmt, i, pValue.zBLOB, pValue.n, SQLITE_TRANSIENT ); |
||
1446 | } |
||
1447 | break; |
||
1448 | } |
||
1449 | case SQLITE_TEXT: |
||
1450 | { |
||
1451 | rc = bindText( pStmt, i, pValue.z, pValue.n, SQLITE_TRANSIENT, |
||
1452 | pValue.enc ); |
||
1453 | break; |
||
1454 | } |
||
1455 | default: |
||
1456 | { |
||
1457 | rc = sqlite3_bind_null( pStmt, i ); |
||
1458 | break; |
||
1459 | } |
||
1460 | } |
||
1461 | return rc; |
||
1462 | } |
||
1463 | |||
1464 | public static int sqlite3_bind_zeroblob( sqlite3_stmt pStmt, int i, int n ) |
||
1465 | { |
||
1466 | int rc; |
||
1467 | Vdbe p = pStmt; |
||
1468 | rc = vdbeUnbind( p, i ); |
||
1469 | if ( rc == SQLITE_OK ) |
||
1470 | { |
||
1471 | sqlite3VdbeMemSetZeroBlob( p.aVar[i - 1], n ); |
||
1472 | sqlite3_mutex_leave( p.db.mutex ); |
||
1473 | } |
||
1474 | return rc; |
||
1475 | } |
||
1476 | |||
1477 | /* |
||
1478 | ** Return the number of wildcards that can be potentially bound to. |
||
1479 | ** This routine is added to support DBD::SQLite. |
||
1480 | */ |
||
1481 | public static int sqlite3_bind_parameter_count( sqlite3_stmt pStmt ) |
||
1482 | { |
||
1483 | Vdbe p = (Vdbe)pStmt; |
||
1484 | return ( p != null ) ? (int)p.nVar : 0; |
||
1485 | } |
||
1486 | |||
1487 | /* |
||
1488 | ** Return the name of a wildcard parameter. Return NULL if the index |
||
1489 | ** is out of range or if the wildcard is unnamed. |
||
1490 | ** |
||
1491 | ** The result is always UTF-8. |
||
1492 | */ |
||
1493 | public static string sqlite3_bind_parameter_name( sqlite3_stmt pStmt, int i ) |
||
1494 | { |
||
1495 | Vdbe p = (Vdbe)pStmt; |
||
1496 | if ( p == null || i < 1 || i > p.nzVar ) |
||
1497 | { |
||
1498 | return string.Empty; |
||
1499 | } |
||
1500 | return p.azVar[i - 1]; |
||
1501 | } |
||
1502 | |||
1503 | /* |
||
1504 | ** Given a wildcard parameter name, return the index of the variable |
||
1505 | ** with that name. If there is no variable with the given name, |
||
1506 | ** return 0. |
||
1507 | */ |
||
1508 | public static int sqlite3VdbeParameterIndex( Vdbe p, string zName, int nName ) |
||
1509 | { |
||
1510 | int i; |
||
1511 | if ( p == null ) |
||
1512 | { |
||
1513 | return 0; |
||
1514 | } |
||
1515 | if ( !string.IsNullOrEmpty( zName ) ) |
||
1516 | { |
||
1517 | for ( i = 0; i < p.nzVar; i++ ) |
||
1518 | { |
||
1519 | string z = p.azVar[i]; |
||
1520 | if ( z != null && z == zName )//&& memcmp(z,zName,nName)==0 && z[nName]==0) |
||
1521 | { |
||
1522 | return i + 1; |
||
1523 | } |
||
1524 | } |
||
1525 | } |
||
1526 | return 0; |
||
1527 | } |
||
1528 | |||
1529 | public static int sqlite3_bind_parameter_index( sqlite3_stmt pStmt, string zName ) |
||
1530 | { |
||
1531 | return sqlite3VdbeParameterIndex( (Vdbe)pStmt, zName, sqlite3Strlen30( zName ) ); |
||
1532 | } |
||
1533 | |||
1534 | /* |
||
1535 | ** Transfer all bindings from the first statement over to the second. |
||
1536 | */ |
||
1537 | public static int sqlite3TransferBindings( sqlite3_stmt pFromStmt, sqlite3_stmt pToStmt ) |
||
1538 | { |
||
1539 | Vdbe pFrom = (Vdbe)pFromStmt; |
||
1540 | Vdbe pTo = (Vdbe)pToStmt; |
||
1541 | int i; |
||
1542 | Debug.Assert( pTo.db == pFrom.db ); |
||
1543 | Debug.Assert( pTo.nVar == pFrom.nVar ); |
||
1544 | sqlite3_mutex_enter( pTo.db.mutex ); |
||
1545 | for ( i = 0; i < pFrom.nVar; i++ ) |
||
1546 | { |
||
1547 | sqlite3VdbeMemMove( pTo.aVar[i], pFrom.aVar[i] ); |
||
1548 | } |
||
1549 | sqlite3_mutex_leave( pTo.db.mutex ); |
||
1550 | return SQLITE_OK; |
||
1551 | } |
||
1552 | |||
1553 | #if !SQLITE_OMIT_DEPRECATED |
||
1554 | /* |
||
1555 | ** Deprecated external interface. Internal/core SQLite code |
||
1556 | ** should call sqlite3TransferBindings. |
||
1557 | ** |
||
1558 | ** Is is misuse to call this routine with statements from different |
||
1559 | ** database connections. But as this is a deprecated interface, we |
||
1560 | ** will not bother to check for that condition. |
||
1561 | ** |
||
1562 | ** If the two statements contain a different number of bindings, then |
||
1563 | ** an SQLITE_ERROR is returned. Nothing else can go wrong, so otherwise |
||
1564 | ** SQLITE_OK is returned. |
||
1565 | */ |
||
1566 | static int sqlite3_transfer_bindings( sqlite3_stmt pFromStmt, sqlite3_stmt pToStmt ) |
||
1567 | { |
||
1568 | Vdbe pFrom = (Vdbe)pFromStmt; |
||
1569 | Vdbe pTo = (Vdbe)pToStmt; |
||
1570 | if ( pFrom.nVar != pTo.nVar ) |
||
1571 | { |
||
1572 | return SQLITE_ERROR; |
||
1573 | } |
||
1574 | if( pTo.isPrepareV2 && pTo.expmask ){ |
||
1575 | pTo.expired = 1; |
||
1576 | } |
||
1577 | if( pFrom.isPrepareV2 && pFrom.expmask ){ |
||
1578 | pFrom.expired = 1; |
||
1579 | } |
||
1580 | return sqlite3TransferBindings( pFromStmt, pToStmt ); |
||
1581 | } |
||
1582 | #endif |
||
1583 | |||
1584 | /* |
||
1585 | ** Return the sqlite3* database handle to which the prepared statement given |
||
1586 | ** in the argument belongs. This is the same database handle that was |
||
1587 | ** the first argument to the sqlite3_prepare() that was used to create |
||
1588 | ** the statement in the first place. |
||
1589 | */ |
||
1590 | public static sqlite3 sqlite3_db_handle( sqlite3_stmt pStmt ) |
||
1591 | { |
||
1592 | return pStmt != null ? ( (Vdbe)pStmt ).db : null; |
||
1593 | } |
||
1594 | |||
1595 | |||
1596 | /* |
||
1597 | ** Return true if the prepared statement is guaranteed to not modify the |
||
1598 | ** database. |
||
1599 | */ |
||
1600 | static bool sqlite3_stmt_readonly( sqlite3_stmt pStmt ) |
||
1601 | { |
||
1602 | return pStmt != null ? ( (Vdbe)pStmt ).readOnly : true; |
||
1603 | } |
||
1604 | |||
1605 | /* |
||
1606 | ** Return a pointer to the next prepared statement after pStmt associated |
||
1607 | ** with database connection pDb. If pStmt is NULL, return the first |
||
1608 | ** prepared statement for the database connection. Return NULL if there |
||
1609 | ** are no more. |
||
1610 | */ |
||
1611 | |||
1612 | public static sqlite3_stmt sqlite3_next_stmt( sqlite3 pDb, sqlite3_stmt pStmt ) |
||
1613 | { |
||
1614 | sqlite3_stmt pNext; |
||
1615 | sqlite3_mutex_enter( pDb.mutex ); |
||
1616 | if ( pStmt == null ) |
||
1617 | { |
||
1618 | pNext = (sqlite3_stmt)pDb.pVdbe; |
||
1619 | } |
||
1620 | else |
||
1621 | { |
||
1622 | pNext = (sqlite3_stmt)( (Vdbe)pStmt ).pNext; |
||
1623 | } |
||
1624 | sqlite3_mutex_leave( pDb.mutex ); |
||
1625 | return pNext; |
||
1626 | } |
||
1627 | /* |
||
1628 | ** Return the value of a status counter for a prepared statement |
||
1629 | */ |
||
1630 | public static int sqlite3_stmt_status( sqlite3_stmt pStmt, int op, int resetFlag ) |
||
1631 | { |
||
1632 | Vdbe pVdbe = (Vdbe)pStmt; |
||
1633 | int v = pVdbe.aCounter[op - 1]; |
||
1634 | if ( resetFlag != 0 ) |
||
1635 | pVdbe.aCounter[op - 1] = 0; |
||
1636 | return v; |
||
1637 | } |
||
1638 | } |
||
1639 | } |