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 | |||
5 | using i64 = System.Int64; |
||
6 | using u32 = System.UInt32; |
||
7 | namespace Community.CsharpSqlite |
||
8 | { |
||
9 | #if TCLSH |
||
10 | using tcl.lang; |
||
11 | using ClientData = System.Object; |
||
12 | using sqlite3_int64 = System.Int64; |
||
13 | using sqlite3_stmt = Sqlite3.Vdbe; |
||
14 | using sqlite3_u3264 = System.UInt64; |
||
15 | using sqlite3_value = Sqlite3.Mem; |
||
16 | using Tcl_Interp = tcl.lang.Interp; |
||
17 | using Tcl_Obj = tcl.lang.TclObject; |
||
18 | |||
19 | public partial class Sqlite3 |
||
20 | { |
||
21 | /* |
||
22 | ** 2001 September 15 |
||
23 | ** |
||
24 | ** The author disclaims copyright to this source code. In place of |
||
25 | ** a legal notice, here is a blessing: |
||
26 | ** |
||
27 | ** May you do good and not evil. |
||
28 | ** May you find forgiveness for yourself and forgive others. |
||
29 | ** May you share freely, never taking more than you give. |
||
30 | ** |
||
31 | ************************************************************************* |
||
32 | ** Code for testing all sorts of SQLite interfaces. This code |
||
33 | ** is not included in the SQLite library. It is used for automated |
||
34 | ** testing of the SQLite library. |
||
35 | ************************************************************************* |
||
36 | ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart |
||
37 | ** C#-SQLite is an independent reimplementation of the SQLite software library |
||
38 | ** |
||
39 | ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2 |
||
40 | ** |
||
41 | ************************************************************************* |
||
42 | */ |
||
43 | //#include "sqliteInt.h" |
||
44 | //#include "tcl.h" |
||
45 | //#include <stdlib.h> |
||
46 | //#include <string.h> |
||
47 | |||
48 | /* |
||
49 | ** This is a copy of the first part of the SqliteDb structure in |
||
50 | ** tclsqlite.c. We need it here so that the get_sqlite_pointer routine |
||
51 | ** can extract the sqlite3* pointer from an existing Tcl SQLite |
||
52 | ** connection. |
||
53 | */ |
||
54 | //struct SqliteDb { |
||
55 | // sqlite3 db=null; |
||
56 | //}; |
||
57 | |||
58 | /* |
||
59 | ** Convert text generated by the "%p" conversion format back into |
||
60 | ** a pointer. |
||
61 | */ |
||
62 | static int testHexToInt( int h ) |
||
63 | { |
||
64 | if ( h >= '0' && h <= '9' ) |
||
65 | { |
||
66 | return h - '0'; |
||
67 | } |
||
68 | else if ( h >= 'a' && h <= 'f' ) |
||
69 | { |
||
70 | return h - 'a' + 10; |
||
71 | } |
||
72 | else |
||
73 | { |
||
74 | Debug.Assert( h >= 'A' && h <= 'F' ); |
||
75 | return h - 'A' + 10; |
||
76 | } |
||
77 | } |
||
78 | static object sqlite3TestTextToPtr( Tcl_Interp interp, string z ) |
||
79 | { |
||
80 | //object p ; |
||
81 | //var v = new u64[1]; |
||
82 | //u32 v2; |
||
83 | //int zIndex = 0; |
||
84 | //if ( z[0] == '0' && z[1] == 'x' ) |
||
85 | //{ |
||
86 | // zIndex += 2; |
||
87 | //} |
||
88 | //v[0] = 0; |
||
89 | //while ( zIndex < z.Length )* z ) |
||
90 | //{ |
||
91 | // v[0] = ( v[0] << 4 ) + (ulong)testHexToInt( z[zIndex] ); |
||
92 | // zIndex++; |
||
93 | //} |
||
94 | //if ( sizeof( object ) == sizeof( u64 ) ) |
||
95 | //{ |
||
96 | // Marshal.Copy( v, 0, (IntPtr)p, 1 );// memcpy( &p, v, sizeof( p ) ); |
||
97 | //} |
||
98 | //else |
||
99 | //{ |
||
100 | // Debug.Assert( sizeof( p ) == sizeof( v2 ) ); |
||
101 | // v2 = (u32)v; |
||
102 | // memcpy( &p, v2, sizeof( p ) ); |
||
103 | //} |
||
104 | WrappedCommand cmdInfo = new WrappedCommand(); |
||
105 | if ( TCL.Tcl_GetCommandInfo( interp, z, out cmdInfo ) || cmdInfo == null ) |
||
106 | { |
||
107 | return null; |
||
108 | } |
||
109 | else |
||
110 | { |
||
111 | return cmdInfo.objClientData; |
||
112 | } |
||
113 | } |
||
114 | |||
115 | |||
116 | /* |
||
117 | ** A TCL command that returns the address of the sqlite* pointer |
||
118 | ** for an sqlite connection instance. Bad things happen if the |
||
119 | ** input is not an sqlite connection. |
||
120 | */ |
||
121 | static int get_sqlite_pointer( |
||
122 | object clientdata, |
||
123 | Tcl_Interp interp, |
||
124 | int objc, |
||
125 | Tcl_Obj[] objv |
||
126 | ) |
||
127 | { |
||
128 | SqliteDb p; |
||
129 | WrappedCommand cmdInfo = null; |
||
130 | //string zBuf ;//[100]; |
||
131 | if ( objc != 2 ) |
||
132 | { |
||
133 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "SQLITE-CONNECTION" ); |
||
134 | return TCL.TCL_ERROR; |
||
135 | } |
||
136 | if ( TCL.Tcl_GetCommandInfo( interp, objv[1].ToString(), out cmdInfo ) ) |
||
137 | { |
||
138 | TCL.Tcl_AppendResult( interp, "command not found: ", |
||
139 | TCL.Tcl_GetString( objv[1] ), null ); |
||
140 | return TCL.TCL_ERROR; |
||
141 | } |
||
142 | //p = (SqliteDb)cmdInfo.objclientdata; |
||
143 | //zBuf = p.db.GetHashCode().ToString(); |
||
144 | //sqlite3_snprintf( zBuf, "%p", p.db ); |
||
145 | //if( strncmp(zBuf,"0x",2) ){ |
||
146 | // sqlite3_snprintf(zBuf, "0x%p", p.db); |
||
147 | //} |
||
148 | //TCL.Tcl_AppendResult(interp, zBuf,null ); |
||
149 | TCL.Tcl_AppendResult( interp, objv[1].ToString() ); |
||
150 | return TCL.TCL_OK; |
||
151 | } |
||
152 | |||
153 | /* |
||
154 | ** Decode a pointer to an sqlite3 object. |
||
155 | */ |
||
156 | static int getDbPointer( Tcl_Interp interp, string zA, out sqlite3 ppDb ) |
||
157 | { |
||
158 | SqliteDb p; |
||
159 | WrappedCommand cmdInfo = new WrappedCommand(); |
||
160 | if ( !TCL.Tcl_GetCommandInfo( interp, zA, out cmdInfo ) ) |
||
161 | { |
||
162 | if ( cmdInfo == null ) |
||
163 | { |
||
164 | ppDb = new sqlite3(); |
||
165 | } |
||
166 | else |
||
167 | { |
||
168 | p = (SqliteDb)cmdInfo.objClientData; |
||
169 | ppDb = p.db; |
||
170 | } |
||
171 | } |
||
172 | else |
||
173 | { |
||
174 | ppDb = null; |
||
175 | } |
||
176 | return TCL.TCL_OK; |
||
177 | } |
||
178 | |||
179 | |||
180 | static string sqlite3TestErrorName( int rc ) |
||
181 | { |
||
182 | string zName = ""; |
||
183 | switch ( rc ) |
||
184 | { |
||
185 | case SQLITE_OK: |
||
186 | zName = "SQLITE_OK"; |
||
187 | break; |
||
188 | case SQLITE_ERROR: |
||
189 | zName = "SQLITE_ERROR"; |
||
190 | break; |
||
191 | case SQLITE_INTERNAL: |
||
192 | zName = "SQLITE_INTERNAL"; |
||
193 | break; |
||
194 | case SQLITE_PERM: |
||
195 | zName = "SQLITE_PERM"; |
||
196 | break; |
||
197 | case SQLITE_ABORT: |
||
198 | zName = "SQLITE_ABORT"; |
||
199 | break; |
||
200 | case SQLITE_BUSY: |
||
201 | zName = "SQLITE_BUSY"; |
||
202 | break; |
||
203 | case SQLITE_LOCKED: |
||
204 | zName = "SQLITE_LOCKED"; |
||
205 | break; |
||
206 | case SQLITE_LOCKED_SHAREDCACHE: |
||
207 | zName = "SQLITE_LOCKED_SHAREDCACHE"; |
||
208 | break; |
||
209 | case SQLITE_NOMEM: |
||
210 | zName = "SQLITE_NOMEM"; |
||
211 | break; |
||
212 | case SQLITE_READONLY: |
||
213 | zName = "SQLITE_READONLY"; |
||
214 | break; |
||
215 | case SQLITE_INTERRUPT: |
||
216 | zName = "SQLITE_INTERRUPT"; |
||
217 | break; |
||
218 | case SQLITE_IOERR: |
||
219 | zName = "SQLITE_IOERR"; |
||
220 | break; |
||
221 | case SQLITE_CORRUPT: |
||
222 | zName = "SQLITE_CORRUPT"; |
||
223 | break; |
||
224 | case SQLITE_NOTFOUND: |
||
225 | zName = "SQLITE_NOTFOUND"; |
||
226 | break; |
||
227 | case SQLITE_FULL: |
||
228 | zName = "SQLITE_FULL"; |
||
229 | break; |
||
230 | case SQLITE_CANTOPEN: |
||
231 | zName = "SQLITE_CANTOPEN"; |
||
232 | break; |
||
233 | case SQLITE_PROTOCOL: |
||
234 | zName = "SQLITE_PROTOCOL"; |
||
235 | break; |
||
236 | case SQLITE_EMPTY: |
||
237 | zName = "SQLITE_EMPTY"; |
||
238 | break; |
||
239 | case SQLITE_SCHEMA: |
||
240 | zName = "SQLITE_SCHEMA"; |
||
241 | break; |
||
242 | case SQLITE_TOOBIG: |
||
243 | zName = "SQLITE_TOOBIG"; |
||
244 | break; |
||
245 | case SQLITE_CONSTRAINT: |
||
246 | zName = "SQLITE_CONSTRAINT"; |
||
247 | break; |
||
248 | case SQLITE_MISMATCH: |
||
249 | zName = "SQLITE_MISMATCH"; |
||
250 | break; |
||
251 | case SQLITE_MISUSE: |
||
252 | zName = "SQLITE_MISUSE"; |
||
253 | break; |
||
254 | case SQLITE_NOLFS: |
||
255 | zName = "SQLITE_NOLFS"; |
||
256 | break; |
||
257 | case SQLITE_AUTH: |
||
258 | zName = "SQLITE_AUTH"; |
||
259 | break; |
||
260 | case SQLITE_FORMAT: |
||
261 | zName = "SQLITE_FORMAT"; |
||
262 | break; |
||
263 | case SQLITE_RANGE: |
||
264 | zName = "SQLITE_RANGE"; |
||
265 | break; |
||
266 | case SQLITE_NOTADB: |
||
267 | zName = "SQLITE_NOTADB"; |
||
268 | break; |
||
269 | case SQLITE_ROW: |
||
270 | zName = "SQLITE_ROW"; |
||
271 | break; |
||
272 | case SQLITE_DONE: |
||
273 | zName = "SQLITE_DONE"; |
||
274 | break; |
||
275 | case SQLITE_IOERR_READ: |
||
276 | zName = "SQLITE_IOERR_READ"; |
||
277 | break; |
||
278 | case SQLITE_IOERR_SHORT_READ: |
||
279 | zName = "SQLITE_IOERR_SHORT_READ"; |
||
280 | break; |
||
281 | case SQLITE_IOERR_WRITE: |
||
282 | zName = "SQLITE_IOERR_WRITE"; |
||
283 | break; |
||
284 | case SQLITE_IOERR_FSYNC: |
||
285 | zName = "SQLITE_IOERR_FSYNC"; |
||
286 | break; |
||
287 | case SQLITE_IOERR_DIR_FSYNC: |
||
288 | zName = "SQLITE_IOERR_DIR_FSYNC"; |
||
289 | break; |
||
290 | case SQLITE_IOERR_TRUNCATE: |
||
291 | zName = "SQLITE_IOERR_TRUNCATE"; |
||
292 | break; |
||
293 | case SQLITE_IOERR_FSTAT: |
||
294 | zName = "SQLITE_IOERR_FSTAT"; |
||
295 | break; |
||
296 | case SQLITE_IOERR_UNLOCK: |
||
297 | zName = "SQLITE_IOERR_UNLOCK"; |
||
298 | break; |
||
299 | case SQLITE_IOERR_RDLOCK: |
||
300 | zName = "SQLITE_IOERR_RDLOCK"; |
||
301 | break; |
||
302 | case SQLITE_IOERR_DELETE: |
||
303 | zName = "SQLITE_IOERR_DELETE"; |
||
304 | break; |
||
305 | case SQLITE_IOERR_BLOCKED: |
||
306 | zName = "SQLITE_IOERR_BLOCKED"; |
||
307 | break; |
||
308 | case SQLITE_IOERR_NOMEM: |
||
309 | zName = "SQLITE_IOERR_NOMEM"; |
||
310 | break; |
||
311 | case SQLITE_IOERR_ACCESS: |
||
312 | zName = "SQLITE_IOERR_ACCESS"; |
||
313 | break; |
||
314 | case SQLITE_IOERR_CHECKRESERVEDLOCK: |
||
315 | zName = "SQLITE_IOERR_CHECKRESERVEDLOCK"; |
||
316 | break; |
||
317 | case SQLITE_IOERR_LOCK: |
||
318 | zName = "SQLITE_IOERR_LOCK"; |
||
319 | break; |
||
320 | case SQLITE_CORRUPT_VTAB: |
||
321 | zName = "SQLITE_CORRUPT_VTAB"; |
||
322 | break; |
||
323 | case SQLITE_READONLY_RECOVERY: |
||
324 | zName = "SQLITE_READONLY_RECOVERY"; |
||
325 | break; |
||
326 | case SQLITE_READONLY_CANTLOCK: |
||
327 | zName = "SQLITE_READONLY_CANTLOCK"; |
||
328 | break; |
||
329 | default: |
||
330 | zName = "SQLITE_Unknown"; |
||
331 | break; |
||
332 | } |
||
333 | return zName; |
||
334 | } |
||
335 | //#define t1ErrorName sqlite3TestErrorName |
||
336 | static string t1ErrorName( int i ) |
||
337 | { |
||
338 | return sqlite3TestErrorName( i ); |
||
339 | } |
||
340 | /* |
||
341 | ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the |
||
342 | ** fact that the sqlite3* is the first field in the Vdbe structure. |
||
343 | */ |
||
344 | //#define StmtToDb(X) sqlite3_db_handle(X) |
||
345 | static sqlite3 StmtToDb( Vdbe v ) |
||
346 | { |
||
347 | return sqlite3_db_handle( v ); |
||
348 | } |
||
349 | |||
350 | /* |
||
351 | ** Check a return value to make sure it agrees with the results |
||
352 | ** from sqlite3_errcode. |
||
353 | */ |
||
354 | static int sqlite3TestErrCode( Tcl_Interp interp, sqlite3 db, int rc ) |
||
355 | { |
||
356 | if ( sqlite3_threadsafe() == 0 && rc != SQLITE_MISUSE && rc != SQLITE_OK |
||
357 | && sqlite3_errcode( db ) != rc ) |
||
358 | { |
||
359 | StringBuilder zBuf = new StringBuilder( 200 );//char zBuf[200]; |
||
360 | int r2 = sqlite3_errcode( db ); |
||
361 | sqlite3_snprintf( 200, zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)", |
||
362 | sqlite3TestErrorName( rc ), rc, sqlite3TestErrorName( r2 ), r2 );//t1ErrorName( rc ), rc, t1ErrorName( r2 ), r2 ); |
||
363 | TCL.Tcl_ResetResult( interp ); |
||
364 | TCL.Tcl_AppendResult( interp, zBuf.ToString() ); |
||
365 | return 1; |
||
366 | } |
||
367 | return 0; |
||
368 | } |
||
369 | |||
370 | /* |
||
371 | ** Decode a pointer to an sqlite3_stmt object. |
||
372 | */ |
||
373 | static int getStmtPointer( |
||
374 | Tcl_Interp interp, |
||
375 | string zArg, |
||
376 | out sqlite3_stmt ppStmt |
||
377 | ) |
||
378 | { |
||
379 | ppStmt = (sqlite3_stmt)sqlite3TestTextToPtr( interp, zArg ); |
||
380 | WrappedCommand cmdInfo = new WrappedCommand(); |
||
381 | TCL.Tcl_GetCommandInfo( interp, zArg, out cmdInfo ); |
||
382 | ppStmt = cmdInfo == null ? null : (sqlite3_stmt)cmdInfo.objClientData; |
||
383 | |||
384 | return TCL.TCL_OK; |
||
385 | } |
||
386 | |||
387 | /* |
||
388 | ** Generate a text representation of a pointer that can be understood |
||
389 | ** by the getDbPointer and getVmPointer routines above. |
||
390 | ** |
||
391 | ** The problem is, on some machines (Solaris) if you do a printf with |
||
392 | ** "%p" you cannot turn around and do a scanf with the same "%p" and |
||
393 | ** get your pointer back. You have to prepend a "0x" before it will |
||
394 | ** work. Or at least that is what is reported to me (drh). But this |
||
395 | ** behavior varies from machine to machine. The solution used her is |
||
396 | ** to test the string right after it is generated to see if it can be |
||
397 | ** understood by scanf, and if not, try prepending an "0x" to see if |
||
398 | ** that helps. If nothing works, a fatal error is generated. |
||
399 | */ |
||
400 | /* |
||
401 | ** Decode a pointer to an sqlite3_stmt object. |
||
402 | */ |
||
403 | |||
404 | |||
405 | static int sqlite3TestMakePointerStr( Tcl_Interp interp, StringBuilder zPtr, object p ) |
||
406 | { |
||
407 | sqlite3_snprintf( 100, zPtr, "->%p", p ); |
||
408 | if ( TCL.Tcl_CreateCommandPointer( interp, zPtr, p ) ) |
||
409 | { |
||
410 | return TCL.TCL_ERROR; |
||
411 | } |
||
412 | return TCL.TCL_OK; |
||
413 | } |
||
414 | |||
415 | /* |
||
416 | ** The callback routine for sqlite3_exec_printf(). |
||
417 | */ |
||
418 | static int exec_printf_cb( object pArg, sqlite3_int64 argc, object p2, object p3 ) |
||
419 | { |
||
420 | string[] name = (string[])p3; |
||
421 | string[] argv = (string[])p2; |
||
422 | TclObject str = (TclObject)pArg; |
||
423 | int i; |
||
424 | |||
425 | if ( TCL.Tcl_DStringLength( str ) == 0 ) |
||
426 | { |
||
427 | for ( i = 0; i < argc; i++ ) |
||
428 | { |
||
429 | TCL.Tcl_DStringAppendElement( str, name[i] != null ? name[i] + " " : "NULL " ); |
||
430 | } |
||
431 | } |
||
432 | string beginbrace = "", endbrace = ""; |
||
433 | for ( i = 0; i < argc; i++ ) |
||
434 | { |
||
435 | if ( argc > 1 ) |
||
436 | { |
||
437 | if ( Util.scanElement( null, argv[i].ToString() ) != 0 ) |
||
438 | { |
||
439 | beginbrace = "{"; |
||
440 | endbrace = "}"; |
||
441 | } |
||
442 | else |
||
443 | { |
||
444 | beginbrace = ""; |
||
445 | endbrace = ""; |
||
446 | } |
||
447 | } |
||
448 | TCL.Tcl_DStringAppendElement( str, argv[i] != null ? beginbrace + argv[i] + endbrace + ( i < argc - 1 ? " " : "" ) : "NULL" ); |
||
449 | } |
||
450 | return 0; |
||
451 | } |
||
452 | |||
453 | /* |
||
454 | ** The I/O tracing callback. |
||
455 | */ |
||
456 | #if !(SQLITE_OMIT_TRACE) && TRACE |
||
457 | //static FILE *iotrace_file = 0; |
||
458 | //static void io_trace_callback(string zFormat, ...){ |
||
459 | // va_list ap; |
||
460 | // va_start(ap, zFormat); |
||
461 | // vfprintf(iotrace_file, zFormat, ap); |
||
462 | // va_end(ap); |
||
463 | // fflush(iotrace_file); |
||
464 | //} |
||
465 | #endif |
||
466 | |||
467 | /* |
||
468 | ** Usage: io_trace FILENAME |
||
469 | ** |
||
470 | ** Turn I/O tracing on or off. If FILENAME is not an empty string, |
||
471 | ** I/O tracing begins going into FILENAME. If FILENAME is an empty |
||
472 | ** string, I/O tracing is turned off. |
||
473 | */ |
||
474 | //static int test_io_trace( |
||
475 | // object NotUsed, |
||
476 | // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
477 | // int argc, /* Number of arguments */ |
||
478 | // Tcl_Obj[] argv /* Text of each argument */ |
||
479 | //){ |
||
480 | #if !(SQLITE_OMIT_TRACE) && (TRACE) |
||
481 | // if( argc!=2 ){ |
||
482 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
||
483 | // " FILENAME\"", 0); |
||
484 | // return TCL.TCL_ERROR; |
||
485 | // } |
||
486 | // if( iotrace_file ){ |
||
487 | // if( iotrace_file!=stdout && iotrace_file!=stderr ){ |
||
488 | // fclose(iotrace_file); |
||
489 | // } |
||
490 | // iotrace_file = 0; |
||
491 | // sqlite3IoTrace = 0; |
||
492 | // } |
||
493 | // if( argv[1][0] ){ |
||
494 | // if( strcmp(argv[1],"stdout")==0 ){ |
||
495 | // iotrace_file = stdout; |
||
496 | // }else if( strcmp(argv[1],"stderr")==0 ){ |
||
497 | // iotrace_file = stderr; |
||
498 | // }else{ |
||
499 | // iotrace_file = fopen(argv[1], "w"); |
||
500 | // } |
||
501 | // sqlite3IoTrace = io_trace_callback; |
||
502 | // } |
||
503 | #endif |
||
504 | // return TCL.TCL_OK; |
||
505 | //} |
||
506 | |||
507 | |||
508 | /* |
||
509 | ** Usage: sqlite3_exec_printf DB FORMAT STRING |
||
510 | ** |
||
511 | ** Invoke the sqlite3_exec_printf() interface using the open database |
||
512 | ** DB. The SQL is the string FORMAT. The format string should contain |
||
513 | ** one %s or %q. STRING is the value inserted into %s or %q. |
||
514 | */ |
||
515 | static int test_exec_printf( |
||
516 | object NotUsed, |
||
517 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
518 | int argc, /* Number of arguments */ |
||
519 | Tcl_Obj[] argv /* Text of each argument */ |
||
520 | ) |
||
521 | { |
||
522 | sqlite3 db = null; |
||
523 | TclObject str = null; |
||
524 | int rc; |
||
525 | string zErr = ""; |
||
526 | string zSql = ""; |
||
527 | StringBuilder zBuf = new StringBuilder( 30 ); |
||
528 | if ( argc != 4 ) |
||
529 | { |
||
530 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
531 | " DB FORMAT STRING" ); |
||
532 | return TCL.TCL_ERROR; |
||
533 | } |
||
534 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
535 | return TCL.TCL_ERROR; |
||
536 | TCL.Tcl_DStringInit( out str ); |
||
537 | zSql = sqlite3_mprintf( argv[2].ToString(), argv[3].ToString() ); |
||
538 | rc = sqlite3_exec( db, zSql, (dxCallback)exec_printf_cb, str, ref zErr ); |
||
539 | sqlite3DbFree( db, ref zSql ); |
||
540 | sqlite3_snprintf( 30, zBuf, "%d", rc ); |
||
541 | TCL.Tcl_AppendElement( interp, zBuf ); |
||
542 | TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr ); //TCL.Tcl_DStringValue(ref str) |
||
543 | TCL.Tcl_DStringFree( ref str ); |
||
544 | if ( zErr != null ) |
||
545 | sqlite3DbFree( db, ref zErr ); |
||
546 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
547 | return TCL.TCL_ERROR; |
||
548 | return TCL.TCL_OK; |
||
549 | } |
||
550 | |||
551 | /* |
||
552 | ** Usage: sqlite3_exec_hex DB HEX |
||
553 | ** |
||
554 | ** Invoke the sqlite3_exec() on a string that is obtained by translating |
||
555 | ** HEX into ASCII. Most characters are translated as is. %HH becomes |
||
556 | ** a hex character. |
||
557 | */ |
||
558 | static int test_exec_hex( |
||
559 | object NotUsed, |
||
560 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
561 | int argc, /* Number of arguments */ |
||
562 | Tcl_Obj[] argv /* Text of each argument */ |
||
563 | ) |
||
564 | { |
||
565 | sqlite3 db = null; |
||
566 | TclObject str = null; |
||
567 | int rc, i, j; |
||
568 | string zErr = ""; |
||
569 | string zHex; |
||
570 | StringBuilder zSql = new StringBuilder( 500 ); |
||
571 | string zBuf = ""; |
||
572 | if ( argc != 3 ) |
||
573 | { |
||
574 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
575 | " DB HEX" ); |
||
576 | return TCL.TCL_ERROR; |
||
577 | } |
||
578 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
579 | return TCL.TCL_ERROR; |
||
580 | zHex = argv[2].ToString(); |
||
581 | for ( i = j = 0; j < zHex.Length && zHex[j] != 0; i++, j++ ) |
||
582 | { |
||
583 | if ( zHex[j] == '%' && zHex[j + 2] != 0 && zHex[j + 2] != 0 ) |
||
584 | { |
||
585 | zSql.Append( (char)( ( testHexToInt( zHex[j + 1] ) << 4 ) + testHexToInt( zHex[j + 2] ) ) ); |
||
586 | j += 2; |
||
587 | } |
||
588 | else |
||
589 | { |
||
590 | zSql.Append( zHex[j] ); |
||
591 | } |
||
592 | } |
||
593 | //zSql[i] = '\0'; |
||
594 | TCL.Tcl_DStringInit( out str ); |
||
595 | rc = sqlite3_exec( db, zSql.ToString(), (dxCallback)exec_printf_cb, str, ref zErr ); |
||
596 | zBuf = rc.ToString();// sprintf( zBuf, "%d", rc ); |
||
597 | TCL.Tcl_AppendElement( interp, zBuf ); |
||
598 | TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr ); |
||
599 | TCL.Tcl_DStringFree( ref str ); |
||
600 | // //sqlite3_free(ref zErr); |
||
601 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
602 | return TCL.TCL_ERROR; |
||
603 | return TCL.TCL_OK; |
||
604 | } |
||
605 | |||
606 | |||
607 | /* |
||
608 | ** Usage: db_enter DB |
||
609 | ** db_leave DB |
||
610 | ** |
||
611 | ** Enter or leave the mutex on a database connection. |
||
612 | */ |
||
613 | static int db_enter( |
||
614 | object NotUsed, |
||
615 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
616 | int argc, /* Number of arguments */ |
||
617 | Tcl_Obj[] argv /* Text of each argument */ |
||
618 | ) |
||
619 | { |
||
620 | sqlite3 db = null; |
||
621 | if ( argc != 2 ) |
||
622 | { |
||
623 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
624 | " DB" ); |
||
625 | return TCL.TCL_ERROR; |
||
626 | } |
||
627 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
628 | return TCL.TCL_ERROR; |
||
629 | sqlite3_mutex_enter( db.mutex ); |
||
630 | return TCL.TCL_OK; |
||
631 | } |
||
632 | static int db_leave( |
||
633 | object NotUsed, |
||
634 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
635 | int argc, /* Number of arguments */ |
||
636 | Tcl_Obj[] argv /* Text of each argument */ |
||
637 | ) |
||
638 | { |
||
639 | sqlite3 db = null; |
||
640 | if ( argc != 2 ) |
||
641 | { |
||
642 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
643 | " DB" ); |
||
644 | return TCL.TCL_ERROR; |
||
645 | } |
||
646 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
647 | return TCL.TCL_ERROR; |
||
648 | sqlite3_mutex_leave( db.mutex ); |
||
649 | return TCL.TCL_OK; |
||
650 | } |
||
651 | |||
652 | /* |
||
653 | ** Usage: sqlite3_exec DB SQL |
||
654 | ** |
||
655 | ** Invoke the sqlite3_exec interface using the open database DB |
||
656 | */ |
||
657 | static int test_exec( |
||
658 | object NotUsed, |
||
659 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
660 | int argc, /* Number of arguments */ |
||
661 | Tcl_Obj[] argv /* Text of each argument */ |
||
662 | ) |
||
663 | { |
||
664 | sqlite3 db = null; |
||
665 | TclObject str = TclString.newInstance( "" ); |
||
666 | int rc; |
||
667 | string zErr = ""; |
||
668 | string zSql; |
||
669 | int i, j; |
||
670 | StringBuilder zBuf = new StringBuilder( 30 ); |
||
671 | if ( argc != 3 ) |
||
672 | { |
||
673 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
674 | " DB SQL" ); |
||
675 | return TCL.TCL_ERROR; |
||
676 | } |
||
677 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
678 | return TCL.TCL_ERROR; |
||
679 | TCL.Tcl_DStringInit( out str ); |
||
680 | zSql = sqlite3_mprintf( "%s", argv[2].ToString() ); |
||
681 | StringBuilder sb = new StringBuilder( zSql.Length ); |
||
682 | for ( i = 0; i < zSql.Length; i++ ) |
||
683 | { |
||
684 | if ( zSql[i] == '%' ) |
||
685 | { |
||
686 | sb.Append( (char)( ( testHexToInt( zSql[i + 1] ) << 4 ) + testHexToInt( zSql[i + 2] ) ) ); |
||
687 | i += 2; |
||
688 | } |
||
689 | else |
||
690 | sb.Append( zSql[i] ); |
||
691 | } |
||
692 | ////zSql[j] = 0; |
||
693 | rc = sqlite3_exec( db, sb.ToString(), exec_printf_cb, str, ref zErr ); |
||
694 | sqlite3DbFree( db, ref zSql ); |
||
695 | sqlite3_snprintf( 30, zBuf, "%d", rc ); |
||
696 | TCL.Tcl_AppendElement( interp, zBuf ); |
||
697 | TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr ); |
||
698 | //TCL.Tcl_DStringFree(&str); |
||
699 | if ( zErr != "" ) |
||
700 | sqlite3DbFree( db, ref zErr ); |
||
701 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
702 | return TCL.TCL_ERROR; |
||
703 | return TCL.TCL_OK; |
||
704 | } |
||
705 | |||
706 | /* |
||
707 | ** Usage: sqlite3_exec_nr DB SQL |
||
708 | ** |
||
709 | ** Invoke the sqlite3_exec interface using the open database DB. Discard |
||
710 | ** all results |
||
711 | */ |
||
712 | static int test_exec_nr( |
||
713 | object NotUsed, |
||
714 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
715 | int argc, /* Number of arguments */ |
||
716 | Tcl_Obj[] argv /* Text of each argument */ |
||
717 | ) |
||
718 | { |
||
719 | sqlite3 db = null; |
||
720 | int rc; |
||
721 | string zErr = ""; |
||
722 | if ( argc != 3 ) |
||
723 | { |
||
724 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
725 | " DB SQL" ); |
||
726 | return TCL.TCL_ERROR; |
||
727 | } |
||
728 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
729 | return TCL.TCL_ERROR; |
||
730 | rc = sqlite3_exec( db, argv[2].ToString(), null, null, ref zErr ); |
||
731 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
732 | return TCL.TCL_ERROR; |
||
733 | return TCL.TCL_OK; |
||
734 | } |
||
735 | |||
736 | /* |
||
737 | ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ... |
||
738 | ** |
||
739 | ** Test the %z format of sqlite_mprintf(). Use multiple mprintf() calls to |
||
740 | ** concatenate arg0 through argn using separator as the separator. |
||
741 | ** Return the result. |
||
742 | */ |
||
743 | static int test_mprintf_z( |
||
744 | object NotUsed, |
||
745 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
746 | int argc, /* Number of arguments */ |
||
747 | Tcl_Obj[] argv /* Text of each argument */ |
||
748 | ) |
||
749 | { |
||
750 | string zResult = ""; |
||
751 | int i; |
||
752 | |||
753 | for ( i = 2; i < argc && ( i == 2 || zResult != "" ); i++ ) |
||
754 | { |
||
755 | zResult = sqlite3_mprintf( "%z%s%s", zResult, argv[1].ToString(), argv[i].ToString() ); |
||
756 | } |
||
757 | TCL.Tcl_AppendResult( interp, zResult ); |
||
758 | //sqlite3DbFree( db, zResult ); |
||
759 | return TCL.TCL_OK; |
||
760 | } |
||
761 | |||
762 | /* |
||
763 | ** Usage: sqlite3_mprintf_n_test STRING |
||
764 | ** |
||
765 | ** Test the %n format of sqlite_mprintf(). Return the length of the |
||
766 | ** input string. |
||
767 | */ |
||
768 | static int test_mprintf_n( |
||
769 | object NotUsed, |
||
770 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
771 | int argc, /* Number of arguments */ |
||
772 | Tcl_Obj[] argv /* Text of each argument */ |
||
773 | ) |
||
774 | { |
||
775 | string zStr; |
||
776 | int n = 0; |
||
777 | zStr = sqlite3_mprintf( "%s%n", argv[1].ToString() ); |
||
778 | n = zStr.Length; |
||
779 | //sqlite3DbFree( db, zStr ); |
||
780 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( n ) ); |
||
781 | return TCL.TCL_OK; |
||
782 | } |
||
783 | |||
784 | /* |
||
785 | ** Usage: sqlite3_snprintf_int SIZE FORMAT INT |
||
786 | ** |
||
787 | ** Test the of sqlite3_snprintf() routine. SIZE is the size of the |
||
788 | ** output buffer in bytes. The maximum size is 100. FORMAT is the |
||
789 | ** format string. INT is a single integer argument. The FORMAT |
||
790 | ** string must require no more than this one integer argument. If |
||
791 | ** You pass in a format string that requires more than one argument, |
||
792 | ** bad things will happen. |
||
793 | */ |
||
794 | static int test_snprintf_int( |
||
795 | object NotUsed, |
||
796 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
797 | int argc, /* Number of arguments */ |
||
798 | Tcl_Obj[] argv /* Text of each argument */ |
||
799 | ) |
||
800 | { |
||
801 | StringBuilder zStr = new StringBuilder( 100 ); |
||
802 | int n = atoi( argv[1].ToString() ); |
||
803 | string zFormat = argv[2].ToString(); |
||
804 | int a1 = atoi( argv[3].ToString() ); |
||
805 | if ( n > zStr.Capacity ) |
||
806 | n = zStr.Capacity;// sizeof( zStr ); |
||
807 | zStr = new StringBuilder( "abcdefghijklmnopqrstuvwxyz" ); |
||
808 | sqlite3_snprintf( n, zStr, zFormat, a1 ); |
||
809 | TCL.Tcl_AppendResult( interp, zStr ); |
||
810 | return TCL.TCL_OK; |
||
811 | } |
||
812 | |||
813 | #if !SQLITE_OMIT_GET_TABLE |
||
814 | /* |
||
815 | ** Usage: sqlite3_get_table_printf DB FORMAT STRING ?--no-counts? |
||
816 | ** |
||
817 | ** Invoke the sqlite3_get_table_printf() interface using the open database |
||
818 | ** DB. The SQL is the string FORMAT. The format string should contain |
||
819 | ** one %s or %q. STRING is the value inserted into %s or %q. |
||
820 | */ |
||
821 | static int test_get_table_printf( |
||
822 | object NotUsed, |
||
823 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
824 | int argc, /* Number of arguments */ |
||
825 | Tcl_Obj[] argv /* Text of each argument */ |
||
826 | ){ |
||
827 | sqlite3 db=null; |
||
828 | TCL.Tcl_DString str; |
||
829 | int rc; |
||
830 | string zErr = 0; |
||
831 | int nRow, nCol; |
||
832 | char **aResult; |
||
833 | int i; |
||
834 | char zBuf[30]; |
||
835 | string zSql; |
||
836 | int resCount = -1; |
||
837 | if( argc==5 ){ |
||
838 | if( TCL.Tcl_GetInt(interp, argv[4], out resCount) ) return TCL.TCL_ERROR; |
||
839 | } |
||
840 | if( argc!=4 && argc!=5 ){ |
||
841 | TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
||
842 | " DB FORMAT STRING ?COUNT?", 0); |
||
843 | return TCL.TCL_ERROR; |
||
844 | } |
||
845 | if( getDbPointer(interp, argv[1].ToString(), out db) !=0) return TCL.TCL_ERROR; |
||
846 | TCL.Tcl_DStringInit(&str); |
||
847 | zSql = sqlite3_mprintf(argv[2],argv[3]); |
||
848 | if( argc==5 ){ |
||
849 | rc = sqlite3_get_table(db, zSql, aResult, 0, 0, zErr); |
||
850 | }else{ |
||
851 | rc = sqlite3_get_table(db, zSql, aResult, nRow, nCol, zErr); |
||
852 | resCount = (nRow+1)*nCol; |
||
853 | } |
||
854 | sqlite3DbFree(db,zSql); |
||
855 | sqlite3_snprintf(zBuf, "%d", rc); |
||
856 | TCL.Tcl_AppendElement(interp, zBuf); |
||
857 | if( rc==SQLITE_OK ){ |
||
858 | if( argc==4 ){ |
||
859 | sqlite3_snprintf(zBuf, "%d", nRow); |
||
860 | TCL.Tcl_AppendElement(interp, zBuf); |
||
861 | sqlite3_snprintf(zBuf, "%d", nCol); |
||
862 | TCL.Tcl_AppendElement(interp, zBuf); |
||
863 | } |
||
864 | for(i=0; i<resCount; i++){ |
||
865 | TCL.Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL"); |
||
866 | } |
||
867 | }else{ |
||
868 | TCL.Tcl_AppendElement(interp, zErr); |
||
869 | } |
||
870 | //sqlite3_free_table(aResult); |
||
871 | if( zErr ) sqlite3DbFree(db,zErr); |
||
872 | if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
||
873 | return TCL.TCL_OK; |
||
874 | } |
||
875 | #endif //* SQLITE_OMIT_GET_TABLE*/ |
||
876 | |||
877 | /* |
||
878 | ** Usage: sqlite3_last_insert_rowid DB |
||
879 | ** |
||
880 | ** Returns the integer ROWID of the most recent insert. |
||
881 | */ |
||
882 | //static int test_last_rowid( |
||
883 | // object NotUsed, |
||
884 | // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
885 | // int argc, /* Number of arguments */ |
||
886 | // Tcl_Obj[] argv /* Text of each argument */ |
||
887 | //){ |
||
888 | // sqlite3 db=null; |
||
889 | // char zBuf[30]; |
||
890 | |||
891 | // if( argc!=2 ){ |
||
892 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\""); |
||
893 | // return TCL.TCL_ERROR; |
||
894 | // } |
||
895 | // if( getDbPointer(interp, argv[1].ToString(), out db) !=0) return TCL.TCL_ERROR; |
||
896 | // sqlite3_snprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db)); |
||
897 | // TCL.Tcl_AppendResult(interp, zBuf); |
||
898 | // return SQLITE_OK; |
||
899 | //} |
||
900 | |||
901 | /* |
||
902 | ** Usage: sqlite3_key DB KEY |
||
903 | ** |
||
904 | ** Set the codec key. |
||
905 | */ |
||
906 | static int test_key( |
||
907 | object NotUsed, |
||
908 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
909 | int argc, /* Number of arguments */ |
||
910 | Tcl_Obj[] argv /* Text of each argument */ |
||
911 | ) |
||
912 | { |
||
913 | sqlite3 db = null; |
||
914 | string zKey; |
||
915 | int nKey; |
||
916 | if ( argc != 3 ) |
||
917 | { |
||
918 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
919 | " FILENAME\"" ); |
||
920 | return TCL.TCL_ERROR; |
||
921 | } |
||
922 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
923 | return TCL.TCL_ERROR; |
||
924 | zKey = argv[2].ToString(); |
||
925 | nKey = zKey.Length; |
||
926 | #if SQLITE_HAS_CODEC |
||
927 | sqlite3_key( db, zKey, nKey ); |
||
928 | #endif |
||
929 | return TCL.TCL_OK; |
||
930 | } |
||
931 | |||
932 | /* |
||
933 | ** Usage: sqlite3_rekey DB KEY |
||
934 | ** |
||
935 | ** Change the codec key. |
||
936 | */ |
||
937 | static int test_rekey( |
||
938 | object NotUsed, |
||
939 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
940 | int argc, /* Number of arguments */ |
||
941 | Tcl_Obj[] argv /* Text of each argument */ |
||
942 | ) |
||
943 | { |
||
944 | sqlite3 db = null; |
||
945 | string zKey; |
||
946 | int nKey; |
||
947 | if ( argc != 3 ) |
||
948 | { |
||
949 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
950 | " FILENAME\"" ); |
||
951 | return TCL.TCL_ERROR; |
||
952 | } |
||
953 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
954 | return TCL.TCL_ERROR; |
||
955 | zKey = argv[2].ToString(); |
||
956 | nKey = zKey.Length; |
||
957 | #if SQLITE_HAS_CODEC |
||
958 | sqlite3_rekey( db, zKey, nKey ); |
||
959 | #endif |
||
960 | return TCL.TCL_OK; |
||
961 | } |
||
962 | |||
963 | /* |
||
964 | ** Usage: sqlite3_close DB |
||
965 | ** |
||
966 | ** Closes the database opened by sqlite3_open. |
||
967 | */ |
||
968 | static int sqlite_test_close( |
||
969 | object NotUsed, |
||
970 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
971 | int argc, /* Number of arguments */ |
||
972 | Tcl_Obj[] argv /* Text of each argument */ |
||
973 | ) |
||
974 | { |
||
975 | sqlite3 db = null; |
||
976 | int rc; |
||
977 | if ( argc != 2 ) |
||
978 | { |
||
979 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
980 | " FILENAME\"" ); |
||
981 | return TCL.TCL_ERROR; |
||
982 | } |
||
983 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
984 | return TCL.TCL_ERROR; |
||
985 | rc = sqlite3_close( db ); |
||
986 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
||
987 | return TCL.TCL_OK; |
||
988 | } |
||
989 | |||
990 | /* |
||
991 | ** Implementation of the x_coalesce() function. |
||
992 | ** Return the first argument non-NULL argument. |
||
993 | */ |
||
994 | static void t1_ifnullFunc( |
||
995 | sqlite3_context context, |
||
996 | int argc, |
||
997 | sqlite3_value[] argv |
||
998 | ) |
||
999 | { |
||
1000 | int i; |
||
1001 | for ( i = 0; i < argc; i++ ) |
||
1002 | { |
||
1003 | if ( SQLITE_NULL != sqlite3_value_type( argv[i] ) ) |
||
1004 | { |
||
1005 | int n = sqlite3_value_bytes( argv[i] ); |
||
1006 | sqlite3_result_text( context, sqlite3_value_text( argv[i] ), |
||
1007 | n, SQLITE_TRANSIENT ); |
||
1008 | break; |
||
1009 | } |
||
1010 | } |
||
1011 | } |
||
1012 | |||
1013 | /* |
||
1014 | ** These are test functions. hex8() interprets its argument as |
||
1015 | ** UTF8 and returns a hex encoding. hex16le() interprets its argument |
||
1016 | ** as UTF16le and returns a hex encoding. |
||
1017 | */ |
||
1018 | static void hex8Func( sqlite3_context p, int argc, sqlite3_value[] argv ) |
||
1019 | { |
||
1020 | string z; |
||
1021 | int i; |
||
1022 | StringBuilder zBuf = new StringBuilder( 200 ); |
||
1023 | z = sqlite3_value_text( argv[0] ); |
||
1024 | StringBuilder zTemp = new StringBuilder( 200 ); |
||
1025 | for ( i = 0; i < zBuf.Capacity / 2 - 2 && i < argv[0].n; i++ ) |
||
1026 | { |
||
1027 | sqlite3_snprintf( 4, zTemp, "%02x", z[i] & 0xff ); |
||
1028 | zBuf.Append( zTemp ); |
||
1029 | } |
||
1030 | //zBuf[i*2] = 0; |
||
1031 | sqlite3_result_text( p, zBuf, -1, SQLITE_TRANSIENT ); |
||
1032 | } |
||
1033 | #if !SQLITE_OMIT_UTF16 |
||
1034 | static void hex16Func(sqlite3_context p, int argc, sqlite3_value[] argv){ |
||
1035 | Debugger.Break (); //TODO -- |
||
1036 | // const unsigned short int *z; |
||
1037 | // int i; |
||
1038 | // char zBuf[400]; |
||
1039 | // z = sqlite3_value_text16(argv[0]); |
||
1040 | // for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){ |
||
1041 | // sqlite3_snprintf(&zBuf[i*4], "%04x", z[i]&0xff); |
||
1042 | // } |
||
1043 | // zBuf[i*4] = 0; |
||
1044 | // sqlite3_result_text(p, (char)zBuf, -1, SQLITE_TRANSIENT); |
||
1045 | } |
||
1046 | #endif |
||
1047 | |||
1048 | /* |
||
1049 | ** A structure into which to accumulate text. |
||
1050 | */ |
||
1051 | struct dstr |
||
1052 | { |
||
1053 | public int nAlloc; /* Space allocated */ |
||
1054 | public int nUsed; /* Space used */ |
||
1055 | public StringBuilder z; /* The space */ |
||
1056 | }; |
||
1057 | |||
1058 | /* |
||
1059 | ** Append text to a dstr |
||
1060 | */ |
||
1061 | static void dstrAppend( dstr p, string z, int divider ) |
||
1062 | { |
||
1063 | int n = z.Length;// strlen( z ); |
||
1064 | // if( p.nUsed + n + 2 > p.nAlloc ){ |
||
1065 | // string zNew; |
||
1066 | p.nAlloc = p.nAlloc * 2 + n + 200; |
||
1067 | p.z.Capacity = p.nAlloc; |
||
1068 | // zNew = sqlite3_realloc(p.z, p.nAlloc); |
||
1069 | // if( zNew==0 ){ |
||
1070 | // sqlite3DbFree(db,p.z); |
||
1071 | // memset(p, 0, sizeof(*p)); |
||
1072 | // return; |
||
1073 | // } |
||
1074 | // p.z = zNew; |
||
1075 | // } |
||
1076 | // if( divider && p.nUsed>0 ){ |
||
1077 | // p.z[p.nUsed++] = divider; |
||
1078 | // } |
||
1079 | // memcpy(p.z[p.nUsed], z, n+1); |
||
1080 | p.nUsed += n; |
||
1081 | p.z.Append( divider + z ); |
||
1082 | } |
||
1083 | |||
1084 | /* |
||
1085 | ** Invoked for each callback from sqlite3ExecFunc |
||
1086 | */ |
||
1087 | static int execFuncCallback( object pData, sqlite3_int64 argc, object _argv, object NotUsed ) |
||
1088 | { |
||
1089 | Tcl_Obj[] argv = (Tcl_Obj[])_argv; |
||
1090 | dstr p = (dstr)pData; |
||
1091 | int i; |
||
1092 | for ( i = 0; i < argc; i++ ) |
||
1093 | { |
||
1094 | if ( argv[i] == null ) |
||
1095 | { |
||
1096 | dstrAppend( p, "NULL", ' ' ); |
||
1097 | } |
||
1098 | else |
||
1099 | { |
||
1100 | dstrAppend( p, argv[i].ToString(), ' ' ); |
||
1101 | } |
||
1102 | } |
||
1103 | return 0; |
||
1104 | } |
||
1105 | |||
1106 | /* |
||
1107 | ** Implementation of the x_sqlite_exec() function. This function takes |
||
1108 | ** a single argument and attempts to execute that argument as SQL code. |
||
1109 | ** This is illegal and should set the SQLITE_MISUSE flag on the database. |
||
1110 | ** |
||
1111 | ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec() |
||
1112 | ** from within a function call. |
||
1113 | ** |
||
1114 | ** This routine simulates the effect of having two threads attempt to |
||
1115 | ** use the same database at the same time. |
||
1116 | */ |
||
1117 | static void sqlite3ExecFunc( |
||
1118 | sqlite3_context context, |
||
1119 | int argc, |
||
1120 | sqlite3_value[] argv |
||
1121 | ) |
||
1122 | { |
||
1123 | dstr x = new dstr(); |
||
1124 | //memset(&x, 0, sizeof(x)); |
||
1125 | string sDummy = ""; |
||
1126 | sqlite3_exec( (sqlite3)sqlite3_context_db_handle( context ), |
||
1127 | sqlite3_value_text( argv[0] ), |
||
1128 | (dxCallback)execFuncCallback, (object)x, ref sDummy ); |
||
1129 | sqlite3_result_text( context, x.z, x.nUsed, SQLITE_TRANSIENT ); |
||
1130 | x.z = null;// sqlite3DbFree( db, ref x.z ); |
||
1131 | } |
||
1132 | |||
1133 | /* |
||
1134 | ** Implementation of tkt2213func(), a scalar function that takes exactly |
||
1135 | ** one argument. It has two interesting features: |
||
1136 | ** |
||
1137 | ** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*. |
||
1138 | ** If the three pointers returned are not the same an SQL error is raised. |
||
1139 | ** |
||
1140 | ** * Otherwise it returns a copy of the text representation of its |
||
1141 | ** argument in such a way as the VDBE representation is a Mem* cell |
||
1142 | ** with the MEM_Term flag clear. |
||
1143 | ** |
||
1144 | ** Ticket #2213 can therefore be tested by evaluating the following |
||
1145 | ** SQL expression: |
||
1146 | ** |
||
1147 | ** tkt2213func(tkt2213func('a string')); |
||
1148 | */ |
||
1149 | static void tkt2213Function( |
||
1150 | sqlite3_context context, |
||
1151 | int argc, |
||
1152 | sqlite3_value[] argv |
||
1153 | ) |
||
1154 | { |
||
1155 | int nText; |
||
1156 | string zText1; |
||
1157 | string zText2; |
||
1158 | string zText3; |
||
1159 | |||
1160 | nText = sqlite3_value_bytes( argv[0] ); |
||
1161 | zText1 = sqlite3_value_text( argv[0] ); |
||
1162 | zText2 = sqlite3_value_text( argv[0] ); |
||
1163 | zText3 = sqlite3_value_text( argv[0] ); |
||
1164 | |||
1165 | if ( zText1 != zText2 || zText2 != zText3 ) |
||
1166 | { |
||
1167 | sqlite3_result_error( context, "tkt2213 is not fixed", -1 ); |
||
1168 | } |
||
1169 | else |
||
1170 | { |
||
1171 | //string zCopy = (char )sqlite3Malloc(nText); |
||
1172 | //memcpy(zCopy, zText1, nText); |
||
1173 | sqlite3_result_text( context, zText1, nText, null ); //sqlite3_free ); |
||
1174 | } |
||
1175 | } |
||
1176 | |||
1177 | /* |
||
1178 | ** The following SQL function takes 4 arguments. The 2nd and |
||
1179 | ** 4th argument must be one of these strings: 'text', 'text16', |
||
1180 | ** or 'blob' corresponding to API functions |
||
1181 | ** |
||
1182 | ** sqlite3_value_text() |
||
1183 | ** sqlite3_value_text16() |
||
1184 | ** sqlite3_value_blob() |
||
1185 | ** |
||
1186 | ** The third argument is a string, either 'bytes' or 'bytes16' or 'noop', |
||
1187 | ** corresponding to APIs: |
||
1188 | ** |
||
1189 | ** sqlite3_value_bytes() |
||
1190 | ** sqlite3_value_bytes16() |
||
1191 | ** noop |
||
1192 | ** |
||
1193 | ** The APIs designated by the 2nd through 4th arguments are applied |
||
1194 | ** to the first argument in order. If the pointers returned by the |
||
1195 | ** second and fourth are different, this routine returns 1. Otherwise, |
||
1196 | ** this routine returns 0. |
||
1197 | ** |
||
1198 | ** This function is used to test to see when returned pointers from |
||
1199 | ** the _text(), _text16() and _blob() APIs become invalidated. |
||
1200 | */ |
||
1201 | static void ptrChngFunction( |
||
1202 | sqlite3_context context, |
||
1203 | int argc, |
||
1204 | sqlite3_value[] argv |
||
1205 | ) |
||
1206 | { |
||
1207 | sqlite3_result_int( context, 0 ); |
||
1208 | return; |
||
1209 | //Debugger.Break(); //TODO -- |
||
1210 | //string p1 = "", p2 = ""; |
||
1211 | //string zCmd; |
||
1212 | //if ( argc != 4 ) |
||
1213 | // return; |
||
1214 | //zCmd = sqlite3_value_text( argv[1] ); |
||
1215 | //if ( zCmd == null ) |
||
1216 | // return; |
||
1217 | // if( strcmp(zCmd,"text")==0 ){ |
||
1218 | // p1 = (const void)sqlite3_value_text(argv[0]); |
||
1219 | //#if !SQLITE_OMIT_UTF16 |
||
1220 | // }else if( strcmp(zCmd, "text16")==0 ){ |
||
1221 | // p1 = (const void)sqlite3_value_text16(argv[0]); |
||
1222 | //#endif |
||
1223 | // }else if( strcmp(zCmd, "blob")==0 ){ |
||
1224 | // p1 = (const void)sqlite3_value_blob(argv[0]); |
||
1225 | // }else{ |
||
1226 | // return; |
||
1227 | // } |
||
1228 | // zCmd = (const char)sqlite3_value_text(argv[2]); |
||
1229 | // if( zCmd==0 ) return; |
||
1230 | // if( strcmp(zCmd,"bytes")==0 ){ |
||
1231 | // sqlite3_value_bytes(argv[0]); |
||
1232 | //#if !SQLITE_OMIT_UTF16 |
||
1233 | // }else if( strcmp(zCmd, "bytes16")==0 ){ |
||
1234 | // sqlite3_value_bytes16(argv[0]); |
||
1235 | //#endif |
||
1236 | // }else if( strcmp(zCmd, "noop")==0 ){ |
||
1237 | // /* do nothing */ |
||
1238 | // }else{ |
||
1239 | // return; |
||
1240 | // } |
||
1241 | // zCmd = (const char)sqlite3_value_text(argv[3]); |
||
1242 | // if( zCmd==0 ) return; |
||
1243 | // if( strcmp(zCmd,"text")==0 ){ |
||
1244 | // p2 = (const void)sqlite3_value_text(argv[0]); |
||
1245 | //#if !SQLITE_OMIT_UTF16 |
||
1246 | // }else if( strcmp(zCmd, "text16")==0 ){ |
||
1247 | // p2 = (const void)sqlite3_value_text16(argv[0]); |
||
1248 | //#endif |
||
1249 | // }else if( strcmp(zCmd, "blob")==0 ){ |
||
1250 | // p2 = (const void)sqlite3_value_blob(argv[0]); |
||
1251 | // }else{ |
||
1252 | // return; |
||
1253 | // } |
||
1254 | //sqlite3_result_int( context, p1 != p2 ? 1 : 0 ); |
||
1255 | } |
||
1256 | |||
1257 | |||
1258 | /* |
||
1259 | ** Usage: sqlite_test_create_function DB |
||
1260 | ** |
||
1261 | ** Call the sqlite3_create_function API on the given database in order |
||
1262 | ** to create a function named "x_coalesce". This function does the same thing |
||
1263 | ** as the "coalesce" function. This function also registers an SQL function |
||
1264 | ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec() |
||
1265 | ** in this way is illegal recursion and should raise an SQLITE_MISUSE error. |
||
1266 | ** The effect is similar to trying to use the same database connection from |
||
1267 | ** two threads at the same time. |
||
1268 | ** |
||
1269 | ** The original motivation for this routine was to be able to call the |
||
1270 | ** sqlite3_create_function function while a query is in progress in order |
||
1271 | ** to test the SQLITE_MISUSE detection logic. |
||
1272 | */ |
||
1273 | static int test_create_function( |
||
1274 | object NotUsed, |
||
1275 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1276 | int argc, /* Number of arguments */ |
||
1277 | Tcl_Obj[] argv /* Text of each argument */ |
||
1278 | ) |
||
1279 | { |
||
1280 | int rc; |
||
1281 | sqlite3 db = null; |
||
1282 | |||
1283 | if ( argc != 2 ) |
||
1284 | { |
||
1285 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1286 | " DB\"" ); |
||
1287 | return TCL.TCL_ERROR; |
||
1288 | } |
||
1289 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
1290 | return TCL.TCL_ERROR; |
||
1291 | rc = sqlite3_create_function( db, "x_coalesce", -1, SQLITE_ANY, 0, |
||
1292 | t1_ifnullFunc, null, null ); |
||
1293 | if ( rc == SQLITE_OK ) |
||
1294 | { |
||
1295 | rc = sqlite3_create_function( db, "hex8", 1, SQLITE_ANY, 0, |
||
1296 | hex8Func, null, null ); |
||
1297 | } |
||
1298 | #if !SQLITE_OMIT_UTF16 |
||
1299 | if( rc==SQLITE_OK ){ |
||
1300 | rc = sqlite3_create_function(db, "hex16", 1, SQLITE_ANY, null, hex16Func, null,null); |
||
1301 | } |
||
1302 | #endif |
||
1303 | if ( rc == SQLITE_OK ) |
||
1304 | { |
||
1305 | rc = sqlite3_create_function( db, "tkt2213func", 1, SQLITE_ANY, 0, |
||
1306 | tkt2213Function, null, null ); |
||
1307 | } |
||
1308 | if ( rc == SQLITE_OK ) |
||
1309 | { |
||
1310 | rc = sqlite3_create_function( db, "pointer_change", 4, SQLITE_ANY, 0, |
||
1311 | ptrChngFunction, null, null ); |
||
1312 | } |
||
1313 | |||
1314 | #if !SQLITE_OMIT_UTF16 |
||
1315 | /* Use the sqlite3_create_function16() API here. Mainly for fun, but also |
||
1316 | ** because it is not tested anywhere else. */ |
||
1317 | if( rc==SQLITE_OK ){ |
||
1318 | string zUtf16; |
||
1319 | sqlite3_value pVal; |
||
1320 | sqlite3_mutex_enter(db.mutex); |
||
1321 | pVal = sqlite3ValueNew(db); |
||
1322 | sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC); |
||
1323 | zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); |
||
1324 | if( db.mallocFailed !=0{ |
||
1325 | rc = SQLITE_NOMEM; |
||
1326 | }else{ |
||
1327 | rc = sqlite3_create_function16(db, zUtf16, 1, SQLITE_UTF16, db, sqlite3ExecFunc,null,null ); |
||
1328 | } |
||
1329 | sqlite3ValueFree(ref pVal); |
||
1330 | sqlite3_mutex_leave(db.mutex); |
||
1331 | } |
||
1332 | #endif |
||
1333 | |||
1334 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
1335 | return TCL.TCL_ERROR; |
||
1336 | TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), 0 ); |
||
1337 | return TCL.TCL_OK; |
||
1338 | } |
||
1339 | |||
1340 | /* |
||
1341 | ** Routines to implement the x_count() aggregate function. |
||
1342 | ** |
||
1343 | ** x_count() counts the number of non-null arguments. But there are |
||
1344 | ** some twists for testing purposes. |
||
1345 | ** |
||
1346 | ** If the argument to x_count() is 40 then a UTF-8 error is reported |
||
1347 | ** on the step function. If x_count(41) is seen, then a UTF-16 error |
||
1348 | ** is reported on the step function. If the total count is 42, then |
||
1349 | ** a UTF-8 error is reported on the finalize function. |
||
1350 | */ |
||
1351 | //typedef struct t1CountCtx t1CountCtx; |
||
1352 | |||
1353 | static void t1CountStep( |
||
1354 | sqlite3_context context, |
||
1355 | int argc, |
||
1356 | sqlite3_value[] argv |
||
1357 | ) |
||
1358 | { |
||
1359 | SumCtx p; |
||
1360 | Mem pMem = sqlite3_aggregate_context( context, 1 );//sizeof(*p)); |
||
1361 | if ( pMem._SumCtx == null ) |
||
1362 | pMem._SumCtx = new SumCtx(); |
||
1363 | p = pMem._SumCtx; |
||
1364 | if ( p.Context == null ) |
||
1365 | p.Context = pMem; |
||
1366 | if ( ( argc == 0 || SQLITE_NULL != sqlite3_value_type( argv[0] ) ) && p != null ) |
||
1367 | { |
||
1368 | p.cnt++; |
||
1369 | } |
||
1370 | if ( argc > 0 ) |
||
1371 | { |
||
1372 | int v = sqlite3_value_int( argv[0] ); |
||
1373 | if ( v == 40 ) |
||
1374 | { |
||
1375 | sqlite3_result_error( context, "value of 40 handed to x_count", -1 ); |
||
1376 | #if !SQLITE_OMIT_UTF16 |
||
1377 | }else if( v==41 ){ |
||
1378 | Debugger.Break (); // TODO -- |
||
1379 | //const char zUtf16ErrMsg[] = { 0, 0x61, 0, 0x62, 0, 0x63, 0, 0, 0}; |
||
1380 | //sqlite3_result_error16(context, zUtf16ErrMsg[1-SQLITE_BIGENDIAN], -1); |
||
1381 | #endif |
||
1382 | } |
||
1383 | } |
||
1384 | } |
||
1385 | static void t1CountFinalize( sqlite3_context context ) |
||
1386 | { |
||
1387 | SumCtx p; |
||
1388 | Mem pMem = sqlite3_aggregate_context( context, 0 );//sizeof(*p)); |
||
1389 | p = pMem._SumCtx; |
||
1390 | if ( p != null ) |
||
1391 | { |
||
1392 | if ( p.cnt == 42 ) |
||
1393 | { |
||
1394 | sqlite3_result_error( context, "x_count totals to 42", -1 ); |
||
1395 | } |
||
1396 | else |
||
1397 | { |
||
1398 | sqlite3_result_int( context, p != null ? (int)p.cnt : 0 ); |
||
1399 | } |
||
1400 | } |
||
1401 | } |
||
1402 | |||
1403 | #if !SQLITE_OMIT_DEPRECATED |
||
1404 | static void legacyCountStep( |
||
1405 | sqlite3_context context, |
||
1406 | int argc, |
||
1407 | sqlite3_value[] argv |
||
1408 | ) |
||
1409 | { |
||
1410 | /* no-op */ |
||
1411 | } |
||
1412 | static void legacyCountFinalize( sqlite3_context context ) |
||
1413 | { |
||
1414 | sqlite3_result_int( context, sqlite3_aggregate_count( context ) ); |
||
1415 | } |
||
1416 | #endif |
||
1417 | /* |
||
1418 | ** Usage: sqlite3_create_aggregate DB |
||
1419 | ** |
||
1420 | ** Call the sqlite3_create_function API on the given database in order |
||
1421 | ** to create a function named "x_count". This function is similar |
||
1422 | ** to the built-in count() function, with a few special quirks |
||
1423 | ** for testing the sqlite3_result_error() APIs. |
||
1424 | ** |
||
1425 | ** The original motivation for this routine was to be able to call the |
||
1426 | ** sqlite3_create_aggregate function while a query is in progress in order |
||
1427 | ** to test the SQLITE_MISUSE detection logic. See misuse.test. |
||
1428 | ** |
||
1429 | ** This routine was later extended to test the use of sqlite3_result_error() |
||
1430 | ** within aggregate functions. |
||
1431 | ** |
||
1432 | ** Later: It is now also extended to register the aggregate function |
||
1433 | ** "legacy_count()" with the supplied database handle. This is used |
||
1434 | ** to test the deprecated sqlite3_aggregate_count() API. |
||
1435 | */ |
||
1436 | static int test_create_aggregate( |
||
1437 | object NotUsed, |
||
1438 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1439 | int argc, /* Number of arguments */ |
||
1440 | Tcl_Obj[] argv /* Text of each argument */ |
||
1441 | ) |
||
1442 | { |
||
1443 | sqlite3 db = new sqlite3(); |
||
1444 | int rc; |
||
1445 | if ( argc != 2 ) |
||
1446 | { |
||
1447 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(), |
||
1448 | " FILENAME\"" ); |
||
1449 | return TCL.TCL_ERROR; |
||
1450 | } |
||
1451 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
1452 | return TCL.TCL_ERROR; |
||
1453 | rc = sqlite3_create_function( db, "x_count", 0, SQLITE_UTF8, 0, null, |
||
1454 | t1CountStep, t1CountFinalize ); |
||
1455 | if ( rc == SQLITE_OK ) |
||
1456 | { |
||
1457 | rc = sqlite3_create_function( db, "x_count", 1, SQLITE_UTF8, 0, null, |
||
1458 | t1CountStep, t1CountFinalize ); |
||
1459 | } |
||
1460 | #if !SQLITE_OMIT_DEPRECATED |
||
1461 | if ( rc == SQLITE_OK ) |
||
1462 | { |
||
1463 | rc = sqlite3_create_function( db, "legacy_count", 0, SQLITE_ANY, 0, null, |
||
1464 | legacyCountStep, legacyCountFinalize |
||
1465 | ); |
||
1466 | } |
||
1467 | #endif |
||
1468 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
1469 | return TCL.TCL_ERROR; |
||
1470 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), 0 ); |
||
1471 | return TCL.TCL_OK; |
||
1472 | } |
||
1473 | |||
1474 | /* |
||
1475 | ** Usage: printf TEXT |
||
1476 | ** |
||
1477 | ** Send output to printf. Use this rather than puts to merge the output |
||
1478 | ** in the correct sequence with debugging printfs inserted into C code. |
||
1479 | ** Puts uses a separate buffer and debugging statements will be out of |
||
1480 | ** sequence if it is used. |
||
1481 | */ |
||
1482 | //static int test_printf( |
||
1483 | // object NotUsed, |
||
1484 | // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1485 | // int argc, /* Number of arguments */ |
||
1486 | // Tcl_Obj[] argv /* Text of each argument */ |
||
1487 | //){ |
||
1488 | // if( argc!=2 ){ |
||
1489 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
||
1490 | // " TEXT\""); |
||
1491 | // return TCL.TCL_ERROR; |
||
1492 | // } |
||
1493 | // printf("%s\n", argv[1]); |
||
1494 | // return TCL.TCL_OK; |
||
1495 | //} |
||
1496 | |||
1497 | |||
1498 | |||
1499 | /* |
||
1500 | ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER |
||
1501 | ** |
||
1502 | ** Call mprintf with three integer arguments |
||
1503 | */ |
||
1504 | static int sqlite3_mprintf_int( |
||
1505 | object NotUsed, |
||
1506 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1507 | int argc, /* Number of arguments */ |
||
1508 | Tcl_Obj[] argv /* Text of each argument */ |
||
1509 | ) |
||
1510 | { |
||
1511 | long[] a = new long[3]; |
||
1512 | int i; |
||
1513 | string z; |
||
1514 | if ( argc != 5 ) |
||
1515 | { |
||
1516 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1517 | " FORMAT INT INT INT\"" ); |
||
1518 | return TCL.TCL_ERROR; |
||
1519 | } |
||
1520 | for ( i = 2; i < 5; i++ ) |
||
1521 | { |
||
1522 | if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 2] ) ) |
||
1523 | return TCL.TCL_ERROR; |
||
1524 | } |
||
1525 | z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] ); |
||
1526 | TCL.Tcl_AppendResult( interp, z ); |
||
1527 | //sqlite3DbFree(db,z); |
||
1528 | return TCL.TCL_OK; |
||
1529 | } |
||
1530 | |||
1531 | /* |
||
1532 | ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER |
||
1533 | ** |
||
1534 | ** Call mprintf with three 64-bit integer arguments |
||
1535 | */ |
||
1536 | static int sqlite3_mprintf_int64( |
||
1537 | object NotUsed, |
||
1538 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1539 | int argc, /* Number of arguments */ |
||
1540 | Tcl_Obj[] argv /* Text of each argument */ |
||
1541 | ) |
||
1542 | { |
||
1543 | int i; |
||
1544 | sqlite3_int64[] a = new sqlite3_int64[3]; |
||
1545 | string z; |
||
1546 | if ( argc != 5 ) |
||
1547 | { |
||
1548 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1549 | " FORMAT INT INT INT\"" ); |
||
1550 | return TCL.TCL_ERROR; |
||
1551 | } |
||
1552 | for ( i = 2; i < 5; i++ ) |
||
1553 | { |
||
1554 | if ( sqlite3Atoi64( argv[i].ToString(), ref a[i - 2], argv[i].ToString().Length, SQLITE_UTF8 ) != 0 ) |
||
1555 | { |
||
1556 | TCL.Tcl_AppendResult( interp, "argument is not a valid 64-bit integer" ); |
||
1557 | return TCL.TCL_ERROR; |
||
1558 | } |
||
1559 | } |
||
1560 | z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] ); |
||
1561 | TCL.Tcl_AppendResult( interp, z ); |
||
1562 | //sqlite3DbFree(db,z); |
||
1563 | return TCL.TCL_OK; |
||
1564 | } |
||
1565 | |||
1566 | |||
1567 | /* |
||
1568 | ** Usage: sqlite3_mprintf_long FORMAT INTEGER INTEGER INTEGER |
||
1569 | ** |
||
1570 | ** Call mprintf with three long integer arguments. This might be the |
||
1571 | ** same as sqlite3_mprintf_int or sqlite3_mprintf_int64, depending on |
||
1572 | ** platform. |
||
1573 | */ |
||
1574 | static int sqlite3_mprintf_long( |
||
1575 | object NotUsed, |
||
1576 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1577 | int argc, /* Number of arguments */ |
||
1578 | Tcl_Obj[] argv /* Text of each argument */ |
||
1579 | ) |
||
1580 | { |
||
1581 | int i; |
||
1582 | long[] a = new long[3]; |
||
1583 | long[] b = new long[3]; |
||
1584 | string z; |
||
1585 | if ( argc != 5 ) |
||
1586 | { |
||
1587 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1588 | " FORMAT INT INT INT\"" ); |
||
1589 | return TCL.TCL_ERROR; |
||
1590 | } |
||
1591 | for ( i = 2; i < 5; i++ ) |
||
1592 | { |
||
1593 | if ( TCL.Tcl_GetLong( interp, argv[i], out b[i - 2] ) ) |
||
1594 | return TCL.TCL_ERROR; |
||
1595 | a[i - 2] = b[i - 2]; |
||
1596 | //a[i-2] &= (((u64)1)<<(sizeof(int)*8))-1; |
||
1597 | } |
||
1598 | z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] ); |
||
1599 | TCL.Tcl_AppendResult( interp, z ); |
||
1600 | ////sqlite3_free(z); |
||
1601 | return TCL.TCL_OK; |
||
1602 | } |
||
1603 | |||
1604 | /* |
||
1605 | ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING |
||
1606 | ** |
||
1607 | ** Call mprintf with two integer arguments and one string argument |
||
1608 | */ |
||
1609 | static int sqlite3_mprintf_str( |
||
1610 | object NotUsed, |
||
1611 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1612 | int argc, /* Number of arguments */ |
||
1613 | Tcl_Obj[] argv /* Text of each argument */ |
||
1614 | ) |
||
1615 | { |
||
1616 | long[] a = new long[3]; |
||
1617 | int i; |
||
1618 | string z; |
||
1619 | if ( argc < 4 || argc > 5 ) |
||
1620 | { |
||
1621 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1622 | " FORMAT INT INT ?STRING?\"" ); |
||
1623 | return TCL.TCL_ERROR; |
||
1624 | } |
||
1625 | for ( i = 2; i < 4; i++ ) |
||
1626 | { |
||
1627 | if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 2] ) ) |
||
1628 | return TCL.TCL_ERROR; |
||
1629 | } |
||
1630 | z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], argc > 4 ? argv[4].ToString() : null ); |
||
1631 | TCL.Tcl_AppendResult( interp, z ); |
||
1632 | //sqlite3DbFree(db,z); |
||
1633 | return TCL.TCL_OK; |
||
1634 | } |
||
1635 | |||
1636 | /* |
||
1637 | ** Usage: sqlite3_snprintf_str INTEGER FORMAT INTEGER INTEGER STRING |
||
1638 | ** |
||
1639 | ** Call mprintf with two integer arguments and one string argument |
||
1640 | */ |
||
1641 | static int sqlite3_snprintf_str( |
||
1642 | object NotUsed, |
||
1643 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1644 | int argc, /* Number of arguments */ |
||
1645 | Tcl_Obj[] argv /* Text of each argument */ |
||
1646 | ) |
||
1647 | { |
||
1648 | long[] a = new long[3]; |
||
1649 | int i; |
||
1650 | int n = 0; |
||
1651 | StringBuilder z; |
||
1652 | if ( argc < 5 || argc > 6 ) |
||
1653 | { |
||
1654 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1655 | " INT FORMAT INT INT ?STRING?\"" ); |
||
1656 | return TCL.TCL_ERROR; |
||
1657 | } |
||
1658 | if ( TCL.Tcl_GetInt( interp, argv[1], out n ) ) |
||
1659 | return TCL.TCL_ERROR; |
||
1660 | if ( n < 0 ) |
||
1661 | { |
||
1662 | TCL.Tcl_AppendResult( interp, "N must be non-negative" ); |
||
1663 | return TCL.TCL_ERROR; |
||
1664 | } |
||
1665 | for ( i = 3; i < 5; i++ ) |
||
1666 | { |
||
1667 | if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 3] ) ) |
||
1668 | return TCL.TCL_ERROR; |
||
1669 | } |
||
1670 | z = new StringBuilder( n + 1 );//sqlite3Malloc( n+1 ); |
||
1671 | sqlite3_snprintf( n, z, argv[2].ToString(), a[0], a[1], argc > 4 ? argv[5].ToString() : null ); |
||
1672 | TCL.Tcl_AppendResult( interp, z ); |
||
1673 | //sqlite3DbFree(db,z); |
||
1674 | return TCL.TCL_OK; |
||
1675 | } |
||
1676 | |||
1677 | /* |
||
1678 | ** Usage: sqlite3_mprintf_double FORMAT INTEGER INTEGER DOUBLE |
||
1679 | ** |
||
1680 | ** Call mprintf with two integer arguments and one double argument |
||
1681 | */ |
||
1682 | static int sqlite3_mprintf_double( |
||
1683 | object NotUsed, |
||
1684 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1685 | int argc, /* Number of arguments */ |
||
1686 | Tcl_Obj[] argv /* Text of each argument */ |
||
1687 | ) |
||
1688 | { |
||
1689 | long[] a = new long[3]; |
||
1690 | int i; |
||
1691 | double r = 0; |
||
1692 | string z; |
||
1693 | if ( argc != 5 ) |
||
1694 | { |
||
1695 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1696 | " FORMAT INT INT DOUBLE\"" ); |
||
1697 | return TCL.TCL_ERROR; |
||
1698 | } |
||
1699 | for ( i = 2; i < 4; i++ ) |
||
1700 | { |
||
1701 | if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 2] ) ) |
||
1702 | return TCL.TCL_ERROR; |
||
1703 | } |
||
1704 | if ( TCL.Tcl_GetDouble( interp, argv[4], out r ) ) |
||
1705 | return TCL.TCL_ERROR; |
||
1706 | z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], r ); |
||
1707 | TCL.Tcl_AppendResult( interp, z ); |
||
1708 | //sqlite3DbFree(db,z); |
||
1709 | return TCL.TCL_OK; |
||
1710 | } |
||
1711 | |||
1712 | /* |
||
1713 | ** Usage: sqlite3_mprintf_scaled FORMAT DOUBLE DOUBLE |
||
1714 | ** |
||
1715 | ** Call mprintf with a single double argument which is the product of the |
||
1716 | ** two arguments given above. This is used to generate overflow and underflow |
||
1717 | ** doubles to test that they are converted properly. |
||
1718 | */ |
||
1719 | static int sqlite3_mprintf_scaled( |
||
1720 | object NotUsed, |
||
1721 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1722 | int argc, /* Number of arguments */ |
||
1723 | Tcl_Obj[] argv /* Text of each argument */ |
||
1724 | ) |
||
1725 | { |
||
1726 | int i; |
||
1727 | double[] r = new double[2]; |
||
1728 | string z; |
||
1729 | if ( argc != 4 ) |
||
1730 | { |
||
1731 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1732 | " FORMAT DOUBLE DOUBLE\"" ); |
||
1733 | return TCL.TCL_ERROR; |
||
1734 | } |
||
1735 | for ( i = 2; i < 4; i++ ) |
||
1736 | { |
||
1737 | if ( TCL.Tcl_GetDouble( interp, argv[i], out r[i - 2] ) ) |
||
1738 | return TCL.TCL_ERROR; |
||
1739 | } |
||
1740 | z = sqlite3_mprintf( argv[1].ToString(), r[0] * r[1] ); |
||
1741 | TCL.Tcl_AppendResult( interp, z ); |
||
1742 | //sqlite3DbFree(db,z); |
||
1743 | return TCL.TCL_OK; |
||
1744 | } |
||
1745 | |||
1746 | /* |
||
1747 | ** Usage: sqlite3_mprintf_stronly FORMAT STRING |
||
1748 | ** |
||
1749 | ** Call mprintf with a single double argument which is the product of the |
||
1750 | ** two arguments given above. This is used to generate overflow and underflow |
||
1751 | ** doubles to test that they are converted properly. |
||
1752 | */ |
||
1753 | static int sqlite3_mprintf_stronly( |
||
1754 | object NotUsed, |
||
1755 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1756 | int argc, /* Number of arguments */ |
||
1757 | Tcl_Obj[] argv /* Text of each argument */ |
||
1758 | ) |
||
1759 | { |
||
1760 | string z; |
||
1761 | if ( argc != 3 ) |
||
1762 | { |
||
1763 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1764 | " FORMAT STRING\"" ); |
||
1765 | return TCL.TCL_ERROR; |
||
1766 | } |
||
1767 | z = sqlite3_mprintf( argv[1].ToString(), argv[2].ToString() ); |
||
1768 | TCL.Tcl_AppendResult( interp, z ); |
||
1769 | //sqlite3DbFree( db, z ); |
||
1770 | return TCL.TCL_OK; |
||
1771 | } |
||
1772 | |||
1773 | /* |
||
1774 | ** Usage: sqlite3_mprintf_hexdouble FORMAT HEX |
||
1775 | ** |
||
1776 | ** Call mprintf with a single double argument which is derived from the |
||
1777 | ** hexadecimal encoding of an IEEE double. |
||
1778 | */ |
||
1779 | static int sqlite3_mprintf_hexdouble( |
||
1780 | object NotUsed, |
||
1781 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1782 | int argc, /* Number of arguments */ |
||
1783 | Tcl_Obj[] argv /* Text of each argument */ |
||
1784 | ) |
||
1785 | { |
||
1786 | string z; |
||
1787 | double r; |
||
1788 | u32 x1, x2; |
||
1789 | i64 d = 0; |
||
1790 | if ( argc != 3 ) |
||
1791 | { |
||
1792 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
1793 | " FORMAT STRING\"" ); |
||
1794 | return TCL.TCL_ERROR; |
||
1795 | } |
||
1796 | //if( sscanf(argv[2].ToString(), "%08x%08x", ref x2, ref x1)!=2 ){ |
||
1797 | if ( argv[2].ToString().Length != 16 |
||
1798 | || !u32.TryParse( argv[2].ToString().Substring( 0, 8 ), System.Globalization.NumberStyles.HexNumber, null, out x2 ) |
||
1799 | || !u32.TryParse( argv[2].ToString().Substring( 8, 8 ), System.Globalization.NumberStyles.HexNumber, null, out x1 ) |
||
1800 | ) |
||
1801 | { |
||
1802 | TCL.Tcl_AppendResult( interp, "2nd argument should be 16-characters of hex" ); |
||
1803 | return TCL.TCL_ERROR; |
||
1804 | } |
||
1805 | d = x2; |
||
1806 | d = ( d << 32 ) + x1; |
||
1807 | #if WINDOWS_PHONE |
||
1808 | r = BitConverter.ToDouble(BitConverter.GetBytes((long)d), 0); |
||
1809 | #else |
||
1810 | r = BitConverter.Int64BitsToDouble( d );// memcpy( &r, d, sizeof( r ) ); |
||
1811 | #endif |
||
1812 | z = sqlite3_mprintf( argv[1].ToString(), r ); |
||
1813 | TCL.Tcl_AppendResult( interp, z ); |
||
1814 | //sqlite3DbFree(db,z); |
||
1815 | return TCL.TCL_OK; |
||
1816 | } |
||
1817 | |||
1818 | /* |
||
1819 | ** Usage: sqlite3_enable_shared_cache ?BOOLEAN? |
||
1820 | ** |
||
1821 | */ |
||
1822 | #if !SQLITE_OMIT_SHARED_CACHE |
||
1823 | static int test_enable_shared( |
||
1824 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
1825 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1826 | int objc, /* Number of arguments */ |
||
1827 | Tcl_Obj[] objv /* Command arguments */ |
||
1828 | ) |
||
1829 | { |
||
1830 | int rc; |
||
1831 | bool enable = false; |
||
1832 | int ret = 0; |
||
1833 | |||
1834 | if ( objc != 2 && objc != 1 ) |
||
1835 | { |
||
1836 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "?BOOLEAN?" ); |
||
1837 | return TCL.TCL_ERROR; |
||
1838 | } |
||
1839 | ret = sqlite3GlobalConfig.sharedCacheEnabled ? 1 : 0; |
||
1840 | |||
1841 | if ( objc == 2 ) |
||
1842 | { |
||
1843 | if ( TCL.Tcl_GetBooleanFromObj( interp, objv[1], out enable ) ) |
||
1844 | { |
||
1845 | return TCL.TCL_ERROR; |
||
1846 | } |
||
1847 | rc = sqlite3_enable_shared_cache( enable ); |
||
1848 | if ( rc != SQLITE_OK ) |
||
1849 | { |
||
1850 | TCL.Tcl_SetResult( interp, sqlite3ErrStr( rc ), TCL.TCL_STATIC ); |
||
1851 | return TCL.TCL_ERROR; |
||
1852 | } |
||
1853 | } |
||
1854 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( ret ) ); |
||
1855 | return TCL.TCL_OK; |
||
1856 | } |
||
1857 | #endif |
||
1858 | |||
1859 | |||
1860 | |||
1861 | /* |
||
1862 | ** Usage: sqlite3_extended_result_codes DB BOOLEAN |
||
1863 | ** |
||
1864 | */ |
||
1865 | static int test_extended_result_codes( |
||
1866 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
1867 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1868 | int objc, /* Number of arguments */ |
||
1869 | Tcl_Obj[] objv /* Command arguments */ |
||
1870 | ) |
||
1871 | { |
||
1872 | bool enable = false; |
||
1873 | sqlite3 db = null; |
||
1874 | |||
1875 | if ( objc != 3 ) |
||
1876 | { |
||
1877 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB BOOLEAN" ); |
||
1878 | return TCL.TCL_ERROR; |
||
1879 | } |
||
1880 | if ( getDbPointer( interp, objv[1].ToString(), out db ) != 0 ) |
||
1881 | return TCL.TCL_ERROR; |
||
1882 | if ( TCL.Tcl_GetBooleanFromObj( interp, objv[2], out enable ) ) |
||
1883 | return TCL.TCL_ERROR; |
||
1884 | sqlite3_extended_result_codes( db, enable ); |
||
1885 | return TCL.TCL_OK; |
||
1886 | } |
||
1887 | |||
1888 | /* |
||
1889 | ** Usage: sqlite3_libversion_number |
||
1890 | ** |
||
1891 | */ |
||
1892 | static int test_libversion_number( |
||
1893 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
1894 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1895 | int objc, /* Number of arguments */ |
||
1896 | Tcl_Obj[] objv /* Command arguments */ |
||
1897 | ) |
||
1898 | { |
||
1899 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_libversion_number() ) ); |
||
1900 | return TCL.TCL_OK; |
||
1901 | } |
||
1902 | |||
1903 | /* |
||
1904 | ** Usage: sqlite3_table_column_metadata DB dbname tblname colname |
||
1905 | ** |
||
1906 | */ |
||
1907 | #if SQLITE_ENABLE_COLUMN_METADATA |
||
1908 | static int test_table_column_metadata( |
||
1909 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
1910 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1911 | int objc, /* Number of arguments */ |
||
1912 | Tcl_Obj[] objv /* Command arguments */ |
||
1913 | ) |
||
1914 | { |
||
1915 | sqlite3 db = null; |
||
1916 | string zDb = null; |
||
1917 | string zTbl = null; |
||
1918 | string zCol = null; |
||
1919 | int rc; |
||
1920 | Tcl_Obj pRet; |
||
1921 | |||
1922 | string zDatatype = null; |
||
1923 | string zCollseq = null; |
||
1924 | int notnull = 0; |
||
1925 | int primarykey = 0; |
||
1926 | int autoincrement = 0; |
||
1927 | |||
1928 | if ( objc != 5 ) |
||
1929 | { |
||
1930 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB dbname tblname colname" ); |
||
1931 | return TCL.TCL_ERROR; |
||
1932 | } |
||
1933 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
1934 | return TCL.TCL_ERROR; |
||
1935 | zDb = TCL.Tcl_GetString( objv[2] ); |
||
1936 | zTbl = TCL.Tcl_GetString( objv[3] ); |
||
1937 | zCol = TCL.Tcl_GetString( objv[4] ); |
||
1938 | |||
1939 | if ( zDb.Length == 0 ) |
||
1940 | zDb = null; |
||
1941 | |||
1942 | rc = sqlite3_table_column_metadata( db, zDb, zTbl, zCol, |
||
1943 | ref zDatatype, ref zCollseq, ref notnull, ref primarykey, ref autoincrement ); |
||
1944 | |||
1945 | if ( rc != SQLITE_OK ) |
||
1946 | { |
||
1947 | TCL.Tcl_AppendResult( interp, sqlite3_errmsg( db ) ); |
||
1948 | return TCL.TCL_ERROR; |
||
1949 | } |
||
1950 | |||
1951 | pRet = TCL.Tcl_NewObj(); |
||
1952 | TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewStringObj( zDatatype, -1 ) ); |
||
1953 | TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewStringObj( zCollseq, -1 ) ); |
||
1954 | TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewIntObj( notnull ) ); |
||
1955 | TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewIntObj( primarykey ) ); |
||
1956 | TCL.Tcl_ListObjAppendElement( null, pRet, TCL.Tcl_NewIntObj( autoincrement ) ); |
||
1957 | TCL.Tcl_SetObjResult( interp, pRet ); |
||
1958 | |||
1959 | return TCL.TCL_OK; |
||
1960 | } |
||
1961 | #endif |
||
1962 | |||
1963 | #if !SQLITE_OMIT_INCRBLOB |
||
1964 | static int blobHandleFromObj( |
||
1965 | Tcl_Interp interp, |
||
1966 | Tcl_Obj *pObj, |
||
1967 | sqlite3_blob **ppBlob |
||
1968 | ){ |
||
1969 | string z; |
||
1970 | int n; |
||
1971 | |||
1972 | z = TCL.Tcl_GetStringFromObj(pObj, &n); |
||
1973 | if( n==0 ){ |
||
1974 | *ppBlob = 0; |
||
1975 | }else{ |
||
1976 | int notUsed; |
||
1977 | TCL.Tcl_Channel channel; |
||
1978 | ClientData instanceData; |
||
1979 | |||
1980 | channel = TCL.Tcl_GetChannel(interp, z, ¬Used); |
||
1981 | if( null==channel ) return TCL.TCL_ERROR; |
||
1982 | |||
1983 | TCL.Tcl_Flush(channel); |
||
1984 | TCL.Tcl_Seek(channel, 0, SEEK_SET); |
||
1985 | |||
1986 | instanceData = TCL.Tcl_GetChannelInstanceData(channel); |
||
1987 | *ppBlob = *((sqlite3_blob *)instanceData); |
||
1988 | } |
||
1989 | |||
1990 | return TCL.TCL_OK; |
||
1991 | } |
||
1992 | |||
1993 | /* |
||
1994 | ** sqlite3_blob_bytes CHANNEL |
||
1995 | */ |
||
1996 | static int test_blob_bytes( |
||
1997 | ClientData clientData, /* Not used */ |
||
1998 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
1999 | int objc, /* Number of arguments */ |
||
2000 | Tcl_Obj[] objv /* Command arguments */ |
||
2001 | ){ |
||
2002 | sqlite3_blob *pBlob; |
||
2003 | int nByte; |
||
2004 | |||
2005 | if( objc!=2 ){ |
||
2006 | TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); |
||
2007 | return TCL.TCL_ERROR; |
||
2008 | } |
||
2009 | |||
2010 | if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
||
2011 | nByte = sqlite3_blob_bytes(pBlob); |
||
2012 | TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(nByte)); |
||
2013 | |||
2014 | return TCL.TCL_OK; |
||
2015 | } |
||
2016 | |||
2017 | /* |
||
2018 | ** sqlite3_blob_close CHANNEL |
||
2019 | */ |
||
2020 | static int test_blob_close( |
||
2021 | ClientData clientData, /* Not used */ |
||
2022 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2023 | int objc, /* Number of arguments */ |
||
2024 | Tcl_Obj[] objv /* Command arguments */ |
||
2025 | ){ |
||
2026 | sqlite3_blob *pBlob; |
||
2027 | |||
2028 | if( objc!=2 ){ |
||
2029 | TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL"); |
||
2030 | return TCL.TCL_ERROR; |
||
2031 | } |
||
2032 | |||
2033 | if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
||
2034 | sqlite3_blob_close(pBlob); |
||
2035 | |||
2036 | return TCL.TCL_OK; |
||
2037 | } |
||
2038 | |||
2039 | /* |
||
2040 | ** sqlite3_blob_read CHANNEL OFFSET N |
||
2041 | ** |
||
2042 | ** This command is used to test the sqlite3_blob_read() in ways that |
||
2043 | ** the Tcl channel interface does not. The first argument should |
||
2044 | ** be the name of a valid channel created by the [incrblob] method |
||
2045 | ** of a database handle. This function calls sqlite3_blob_read() |
||
2046 | ** to read N bytes from offset OFFSET from the underlying SQLite |
||
2047 | ** blob handle. |
||
2048 | ** |
||
2049 | ** On success, a byte-array object containing the read data is |
||
2050 | ** returned. On failure, the interpreter result is set to the |
||
2051 | ** text representation of the returned error code (i.e. "SQLITE_NOMEM") |
||
2052 | ** and a Tcl exception is thrown. |
||
2053 | */ |
||
2054 | static int test_blob_read( |
||
2055 | ClientData clientData, /* Not used */ |
||
2056 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2057 | int objc, /* Number of arguments */ |
||
2058 | Tcl_Obj[] objv /* Command arguments */ |
||
2059 | ){ |
||
2060 | sqlite3_blob *pBlob; |
||
2061 | int nByte; |
||
2062 | int iOffset; |
||
2063 | unsigned string zBuf = 0; |
||
2064 | int rc; |
||
2065 | |||
2066 | if( objc!=4 ){ |
||
2067 | TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET N"); |
||
2068 | return TCL.TCL_ERROR; |
||
2069 | } |
||
2070 | |||
2071 | if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
||
2072 | if( TCL_OK!=TCL.Tcl_GetIntFromObj(interp, objv[2], &iOffset) |
||
2073 | || TCL_OK!=TCL.Tcl_GetIntFromObj(interp, objv[3], &nByte) |
||
2074 | ){ |
||
2075 | return TCL.TCL_ERROR; |
||
2076 | } |
||
2077 | |||
2078 | if( nByte>0 ){ |
||
2079 | zBuf = (unsigned char )TCL.Tcl_Alloc(nByte); |
||
2080 | } |
||
2081 | rc = sqlite3_blob_read(pBlob, zBuf, nByte, iOffset); |
||
2082 | if( rc==SQLITE_OK ){ |
||
2083 | TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewByteArrayObj(zBuf, nByte)); |
||
2084 | }else{ |
||
2085 | TCL.Tcl_SetResult(interp, (char )sqlite3TestErrorName(rc), TCL.TCL_VOLATILE); |
||
2086 | } |
||
2087 | TCL.Tcl_Free((char )zBuf); |
||
2088 | |||
2089 | return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
||
2090 | } |
||
2091 | |||
2092 | /* |
||
2093 | ** sqlite3_blob_write CHANNEL OFFSET DATA ?NDATA? |
||
2094 | ** |
||
2095 | ** This command is used to test the sqlite3_blob_write() in ways that |
||
2096 | ** the Tcl channel interface does not. The first argument should |
||
2097 | ** be the name of a valid channel created by the [incrblob] method |
||
2098 | ** of a database handle. This function calls sqlite3_blob_write() |
||
2099 | ** to write the DATA byte-array to the underlying SQLite blob handle. |
||
2100 | ** at offset OFFSET. |
||
2101 | ** |
||
2102 | ** On success, an empty string is returned. On failure, the interpreter |
||
2103 | ** result is set to the text representation of the returned error code |
||
2104 | ** (i.e. "SQLITE_NOMEM") and a Tcl exception is thrown. |
||
2105 | */ |
||
2106 | static int test_blob_write( |
||
2107 | ClientData clientData, /* Not used */ |
||
2108 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2109 | int objc, /* Number of arguments */ |
||
2110 | Tcl_Obj[] objv /* Command arguments */ |
||
2111 | ){ |
||
2112 | sqlite3_blob *pBlob; |
||
2113 | int iOffset; |
||
2114 | int rc; |
||
2115 | |||
2116 | unsigned string zBuf; |
||
2117 | int nBuf; |
||
2118 | |||
2119 | if( objc!=4 && objc!=5 ){ |
||
2120 | TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL OFFSET DATA ?NDATA?"); |
||
2121 | return TCL.TCL_ERROR; |
||
2122 | } |
||
2123 | |||
2124 | if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
||
2125 | if( TCL_OK!=TCL.Tcl_GetIntFromObj(interp, objv[2], &iOffset) ){ |
||
2126 | return TCL.TCL_ERROR; |
||
2127 | } |
||
2128 | |||
2129 | zBuf = TCL.Tcl_GetByteArrayFromObj(objv[3], &nBuf); |
||
2130 | if( objc==5 && TCL.Tcl_GetIntFromObj(interp, objv[4], &nBuf) ){ |
||
2131 | return TCL.TCL_ERROR; |
||
2132 | } |
||
2133 | rc = sqlite3_blob_write(pBlob, zBuf, nBuf, iOffset); |
||
2134 | if( rc!=SQLITE_OK ){ |
||
2135 | TCL.Tcl_SetResult(interp, (char )sqlite3TestErrorName(rc), TCL.TCL_VOLATILE); |
||
2136 | } |
||
2137 | |||
2138 | return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
||
2139 | } |
||
2140 | |||
2141 | static int test_blob_reopen( |
||
2142 | ClientData clientData, /* Not used */ |
||
2143 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2144 | int objc, /* Number of arguments */ |
||
2145 | Tcl_Obj[] objv /* Command arguments */ |
||
2146 | ){ |
||
2147 | TCL.Tcl_WideInt iRowid; |
||
2148 | sqlite3_blob *pBlob; |
||
2149 | int rc; |
||
2150 | |||
2151 | if( objc!=3 ){ |
||
2152 | TCL.Tcl_WrongNumArgs(interp, 1, objv, "CHANNEL ROWID"); |
||
2153 | return TCL.TCL_ERROR; |
||
2154 | } |
||
2155 | |||
2156 | if( blobHandleFromObj(interp, objv[1], &pBlob) ) return TCL.TCL_ERROR; |
||
2157 | if( TCL.Tcl_GetWideIntFromObj(interp, objv[2], &iRowid) ) return TCL.TCL_ERROR; |
||
2158 | |||
2159 | rc = sqlite3_blob_reopen(pBlob, iRowid); |
||
2160 | if( rc!=SQLITE_OK ){ |
||
2161 | TCL.Tcl_SetResult(interp, (char )sqlite3TestErrorName(rc), TCL.TCL_VOLATILE); |
||
2162 | } |
||
2163 | |||
2164 | return (rc==SQLITE_OK ? TCL_OK : TCL_ERROR); |
||
2165 | } |
||
2166 | #endif |
||
2167 | |||
2168 | /* |
||
2169 | ** Usage: sqlite3_create_collation_v2 DB-HANDLE NAME CMP-PROC DEL-PROC |
||
2170 | ** |
||
2171 | ** This Tcl proc is used for testing the experimental |
||
2172 | ** sqlite3_create_collation_v2() interface. |
||
2173 | */ |
||
2174 | public struct TestCollationX |
||
2175 | { |
||
2176 | public Tcl_Interp interp; |
||
2177 | public Tcl_Obj pCmp; |
||
2178 | public Tcl_Obj pDel; |
||
2179 | }; |
||
2180 | //typedef struct TestCollationX TestCollationX; |
||
2181 | static void testCreateCollationDel( ref object pCtx ) |
||
2182 | { |
||
2183 | TestCollationX p = (TestCollationX)pCtx; |
||
2184 | |||
2185 | int rc = TCL.Tcl_EvalObjEx( p.interp, p.pDel, TCL.TCL_EVAL_DIRECT | TCL.TCL_EVAL_GLOBAL ); |
||
2186 | if ( rc != TCL.TCL_OK ) |
||
2187 | { |
||
2188 | TCL.Tcl_BackgroundError( p.interp ); |
||
2189 | } |
||
2190 | |||
2191 | TCL.Tcl_DecrRefCount( ref p.pCmp ); |
||
2192 | TCL.Tcl_DecrRefCount( ref p.pDel ); |
||
2193 | //sqlite3Free(ref p); |
||
2194 | } |
||
2195 | static int testCreateCollationCmp( |
||
2196 | object pCtx, |
||
2197 | int nLeft, |
||
2198 | string zLeft, |
||
2199 | int nRight, |
||
2200 | string zRight |
||
2201 | ) |
||
2202 | { |
||
2203 | TestCollationX p = (TestCollationX)pCtx; |
||
2204 | Tcl_Obj pScript = TCL.Tcl_DuplicateObj( p.pCmp ); |
||
2205 | int iRes = 0; |
||
2206 | |||
2207 | TCL.Tcl_IncrRefCount( pScript ); |
||
2208 | TCL.Tcl_ListObjAppendElement( null, pScript, TCL.Tcl_NewStringObj( zLeft, nLeft ) ); |
||
2209 | TCL.Tcl_ListObjAppendElement( null, pScript, TCL.Tcl_NewStringObj( zRight, nRight ) ); |
||
2210 | |||
2211 | if ( TCL.TCL_OK != TCL.Tcl_EvalObjEx( p.interp, pScript, TCL.TCL_EVAL_DIRECT | TCL.TCL_EVAL_GLOBAL ) |
||
2212 | || ( TCL.Tcl_GetIntFromObj( p.interp, TCL.Tcl_GetObjResult( p.interp ), out iRes ) != TCL.TCL_OK ) |
||
2213 | ) |
||
2214 | { |
||
2215 | TCL.Tcl_BackgroundError( p.interp ); |
||
2216 | } |
||
2217 | TCL.Tcl_DecrRefCount( ref pScript ); |
||
2218 | |||
2219 | return iRes; |
||
2220 | } |
||
2221 | static int test_create_collation_v2( |
||
2222 | object clientdata, /* Not used */ |
||
2223 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2224 | int objc, /* Number of arguments */ |
||
2225 | Tcl_Obj[] objv /* Command arguments */ |
||
2226 | ) |
||
2227 | { |
||
2228 | TestCollationX p; |
||
2229 | sqlite3 db = null; |
||
2230 | int rc; |
||
2231 | |||
2232 | if ( objc != 5 ) |
||
2233 | { |
||
2234 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB-HANDLE NAME CMP-PROC DEL-PROC" ); |
||
2235 | return TCL.TCL_ERROR; |
||
2236 | } |
||
2237 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
2238 | return TCL.TCL_ERROR; |
||
2239 | |||
2240 | p = new TestCollationX(); //(TestCollationX )sqlite3Malloc(sizeof(TestCollationX)); |
||
2241 | p.pCmp = objv[3]; |
||
2242 | p.pDel = objv[4]; |
||
2243 | p.interp = interp; |
||
2244 | TCL.Tcl_IncrRefCount( p.pCmp ); |
||
2245 | TCL.Tcl_IncrRefCount( p.pDel ); |
||
2246 | |||
2247 | rc = sqlite3_create_collation_v2( db, TCL.Tcl_GetString( objv[2] ), 16, |
||
2248 | p, (dxCompare)testCreateCollationCmp, testCreateCollationDel |
||
2249 | ); |
||
2250 | if ( rc != SQLITE_MISUSE ) |
||
2251 | { |
||
2252 | TCL.Tcl_AppendResult( interp, "sqlite3_create_collate_v2() failed to detect " + |
||
2253 | "an invalid encoding" ); |
||
2254 | return TCL.TCL_ERROR; |
||
2255 | } |
||
2256 | rc = sqlite3_create_collation_v2( db, TCL.Tcl_GetString( objv[2] ), SQLITE_UTF8, |
||
2257 | p, (dxCompare)testCreateCollationCmp, testCreateCollationDel |
||
2258 | ); |
||
2259 | return TCL.TCL_OK; |
||
2260 | } |
||
2261 | |||
2262 | /* |
||
2263 | ** USAGE: sqlite3_create_function_v2 DB NAME NARG ENC ?SWITCHES? |
||
2264 | ** |
||
2265 | ** Available switches are: |
||
2266 | ** |
||
2267 | ** -func SCRIPT |
||
2268 | ** -step SCRIPT |
||
2269 | ** -final SCRIPT |
||
2270 | ** -destroy SCRIPT |
||
2271 | */ |
||
2272 | //typedef struct CreateFunctionV2 CreateFunctionV2; |
||
2273 | public class CreateFunctionV2 |
||
2274 | { |
||
2275 | public Tcl_Interp interp; |
||
2276 | public Tcl_Obj pFunc; /* Script for function invocation */ |
||
2277 | public Tcl_Obj pStep; /* Script for agg. step invocation */ |
||
2278 | public Tcl_Obj pFinal; /* Script for agg. finalization invocation */ |
||
2279 | public Tcl_Obj pDestroy; /* Destructor script */ |
||
2280 | }; |
||
2281 | static void cf2Func( sqlite3_context ctx, int nArg, sqlite3_value[] aArg ) |
||
2282 | { |
||
2283 | } |
||
2284 | static void cf2Step( sqlite3_context ctx, int nArg, sqlite3_value[] aArg ) |
||
2285 | { |
||
2286 | } |
||
2287 | static void cf2Final( sqlite3_context ctx ) |
||
2288 | { |
||
2289 | } |
||
2290 | static void cf2Destroy( object pUser ) |
||
2291 | { |
||
2292 | CreateFunctionV2 p = (CreateFunctionV2)pUser; |
||
2293 | |||
2294 | if ( p.interp != null && p.pDestroy != null ) |
||
2295 | { |
||
2296 | int rc = TCL.Tcl_EvalObjEx( p.interp, p.pDestroy, 0 ); |
||
2297 | if ( rc != TCL.TCL_OK ) |
||
2298 | TCL.Tcl_BackgroundError( p.interp ); |
||
2299 | } |
||
2300 | |||
2301 | if ( p.pFunc != null ) |
||
2302 | TCL.Tcl_DecrRefCount( ref p.pFunc ); |
||
2303 | if ( p.pStep != null ) |
||
2304 | TCL.Tcl_DecrRefCount( ref p.pStep ); |
||
2305 | if ( p.pFinal != null ) |
||
2306 | TCL.Tcl_DecrRefCount( ref p.pFinal ); |
||
2307 | if ( p.pDestroy != null ) |
||
2308 | TCL.Tcl_DecrRefCount( ref p.pDestroy ); |
||
2309 | //sqlite3_free( p); |
||
2310 | } |
||
2311 | |||
2312 | public class EncTable |
||
2313 | { |
||
2314 | public string zEnc; |
||
2315 | public int enc; |
||
2316 | |||
2317 | public EncTable( string zEnc, int enc ) |
||
2318 | { |
||
2319 | this.zEnc = zEnc; |
||
2320 | this.enc = enc; |
||
2321 | } |
||
2322 | } |
||
2323 | |||
2324 | static int test_create_function_v2( |
||
2325 | ClientData clientData, /* Not used */ |
||
2326 | Tcl_Interp interp, /* The invoking TCL interpreter */ |
||
2327 | int objc, /* Number of arguments */ |
||
2328 | Tcl_Obj[] objv /* Command arguments */ |
||
2329 | ) |
||
2330 | { |
||
2331 | sqlite3 db = null; |
||
2332 | string zFunc; |
||
2333 | int nArg = 0; |
||
2334 | int enc = 0; |
||
2335 | CreateFunctionV2 p; |
||
2336 | int i; |
||
2337 | int rc; |
||
2338 | |||
2339 | EncTable[] aEnc = { |
||
2340 | new EncTable("utf8", SQLITE_UTF8 ), |
||
2341 | new EncTable("utf16", SQLITE_UTF16 ), |
||
2342 | new EncTable("utf16le", SQLITE_UTF16LE ), |
||
2343 | new EncTable("utf16be", SQLITE_UTF16BE ), |
||
2344 | new EncTable("any", SQLITE_ANY ), |
||
2345 | new EncTable("0", 0 ) |
||
2346 | }; |
||
2347 | |||
2348 | if ( objc < 5 || ( objc % 2 ) == 0 ) |
||
2349 | { |
||
2350 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB NAME NARG ENC SWITCHES..." ); |
||
2351 | return TCL.TCL_ERROR; |
||
2352 | } |
||
2353 | |||
2354 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
2355 | return TCL.TCL_ERROR; |
||
2356 | zFunc = TCL.Tcl_GetString( objv[2] ); |
||
2357 | if ( TCL.Tcl_GetIntFromObj( interp, objv[3], out nArg ) != 0 ) |
||
2358 | return TCL.TCL_ERROR; |
||
2359 | //if ( TCL.Tcl_GetIndexFromObjStruct( interp, objv[4], aEnc,//sizeof(aEnc[0]), |
||
2360 | // "encoding", 0, ref enc) |
||
2361 | //) |
||
2362 | int iEnc; |
||
2363 | for ( iEnc = 0; iEnc < aEnc.Length && ( aEnc[iEnc].zEnc != objv[4].ToString() ); iEnc++ ) |
||
2364 | { |
||
2365 | } |
||
2366 | if ( iEnc >= aEnc.Length ) |
||
2367 | return TCL.TCL_ERROR; |
||
2368 | enc = aEnc[iEnc].enc; |
||
2369 | |||
2370 | p = new CreateFunctionV2();//sqlite3_malloc( sizeof( CreateFunctionV2 ) ); |
||
2371 | //Debug.Assert( p ); |
||
2372 | //memset(p, 0, sizeof(CreateFunctionV2)); |
||
2373 | p.interp = interp; |
||
2374 | |||
2375 | for ( i = 5; i < objc; i += 2 ) |
||
2376 | { |
||
2377 | int iSwitch = 0; |
||
2378 | string[] azSwitch = { "-func", "-step", "-final", "-destroy", "" }; |
||
2379 | if ( TCL.Tcl_GetIndexFromObj( interp, objv[i], azSwitch, "switch", 0, out iSwitch ) ) |
||
2380 | { |
||
2381 | //sqlite3_free(p); |
||
2382 | return TCL.TCL_ERROR; |
||
2383 | } |
||
2384 | |||
2385 | switch ( iSwitch ) |
||
2386 | { |
||
2387 | case 0: |
||
2388 | p.pFunc = objv[i + 1]; |
||
2389 | break; |
||
2390 | case 1: |
||
2391 | p.pStep = objv[i + 1]; |
||
2392 | break; |
||
2393 | case 2: |
||
2394 | p.pFinal = objv[i + 1]; |
||
2395 | break; |
||
2396 | case 3: |
||
2397 | p.pDestroy = objv[i + 1]; |
||
2398 | break; |
||
2399 | } |
||
2400 | } |
||
2401 | if ( p.pFunc != null ) |
||
2402 | p.pFunc = TCL.Tcl_DuplicateObj( p.pFunc ); |
||
2403 | if ( p.pStep != null ) |
||
2404 | p.pStep = TCL.Tcl_DuplicateObj( p.pStep ); |
||
2405 | if ( p.pFinal != null ) |
||
2406 | p.pFinal = TCL.Tcl_DuplicateObj( p.pFinal ); |
||
2407 | if ( p.pDestroy != null ) |
||
2408 | p.pDestroy = TCL.Tcl_DuplicateObj( p.pDestroy ); |
||
2409 | |||
2410 | if ( p.pFunc != null ) |
||
2411 | TCL.Tcl_IncrRefCount( p.pFunc ); |
||
2412 | if ( p.pStep != null ) |
||
2413 | TCL.Tcl_IncrRefCount( p.pStep ); |
||
2414 | if ( p.pFinal != null ) |
||
2415 | TCL.Tcl_IncrRefCount( p.pFinal ); |
||
2416 | if ( p.pDestroy != null ) |
||
2417 | TCL.Tcl_IncrRefCount( p.pDestroy ); |
||
2418 | |||
2419 | rc = sqlite3_create_function_v2( db, zFunc, nArg, enc, p, |
||
2420 | ( p.pFunc != null ? (dxFunc)cf2Func : (dxFunc)null ), |
||
2421 | ( p.pStep != null ? (dxStep)cf2Step : (dxStep)null ), |
||
2422 | ( p.pFinal != null ? (dxFinal)cf2Final : (dxFinal)null ), |
||
2423 | (dxFDestroy)cf2Destroy |
||
2424 | ); |
||
2425 | if ( rc != SQLITE_OK ) |
||
2426 | { |
||
2427 | TCL.Tcl_ResetResult( interp ); |
||
2428 | TCL.Tcl_AppendResult( interp, sqlite3TestErrorName( rc ) ); |
||
2429 | return TCL.TCL_ERROR; |
||
2430 | } |
||
2431 | return TCL.TCL_OK; |
||
2432 | } |
||
2433 | |||
2434 | /* |
||
2435 | ** Usage: sqlite3_load_extension DB-HANDLE FILE ?PROC? |
||
2436 | */ |
||
2437 | //static int test_load_extension( |
||
2438 | // object clientdata, /* Not used */ |
||
2439 | // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2440 | // int objc, /* Number of arguments */ |
||
2441 | // Tcl_Obj[] objv /* Command arguments */ |
||
2442 | //){ |
||
2443 | // TCL.Tcl_CmdInfo cmdInfo; |
||
2444 | // sqlite3 db=null; |
||
2445 | // int rc; |
||
2446 | // string zDb; |
||
2447 | // string zFile; |
||
2448 | // string zProc = 0; |
||
2449 | // string zErr = 0; |
||
2450 | |||
2451 | // if( objc!=4 && objc!=3 ){ |
||
2452 | // TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE FILE ?PROC?"); |
||
2453 | // return TCL.TCL_ERROR; |
||
2454 | // } |
||
2455 | // zDb = TCL.Tcl_GetString(objv[1]); |
||
2456 | // zFile = TCL.Tcl_GetString(objv[2]); |
||
2457 | // if( objc==4 ){ |
||
2458 | // zProc = TCL.Tcl_GetString(objv[3]); |
||
2459 | // } |
||
2460 | |||
2461 | // /* Extract the C database handle from the Tcl command name */ |
||
2462 | // if( null==TCL.Tcl_GetCommandInfo(interp, zDb, cmdInfo) ){ |
||
2463 | // TCL.Tcl_AppendResult(interp, "command not found: ", zDb); |
||
2464 | // return TCL.TCL_ERROR; |
||
2465 | // } |
||
2466 | // db = ((struct SqliteDb)cmdInfo.objclientdata).db; |
||
2467 | // Debug.Assert(db); |
||
2468 | |||
2469 | // /* Call the underlying C function. If an error occurs, set rc to |
||
2470 | // ** TCL.TCL_ERROR and load any error string into the interpreter. If no |
||
2471 | // ** error occurs, set rc to TCL.TCL_OK. |
||
2472 | // */ |
||
2473 | #if SQLITE_OMIT_LOAD_EXTENSION |
||
2474 | // rc = SQLITE_ERROR; |
||
2475 | // zErr = sqlite3_mprintf("this build omits sqlite3_load_extension()"); |
||
2476 | #else |
||
2477 | // rc = sqlite3_load_extension(db, zFile, zProc, zErr); |
||
2478 | #endif |
||
2479 | // if( rc!=SQLITE_OK ){ |
||
2480 | // TCL.Tcl_SetResult(interp, zErr ? zErr : "", TCL.Tcl_VOLATILE); |
||
2481 | // rc = TCL.TCL_ERROR; |
||
2482 | // }else{ |
||
2483 | // rc = TCL.TCL_OK; |
||
2484 | // } |
||
2485 | // sqlite3DbFree(db,zErr); |
||
2486 | |||
2487 | // return rc; |
||
2488 | //} |
||
2489 | |||
2490 | /* |
||
2491 | ** Usage: sqlite3_enable_load_extension DB-HANDLE ONOFF |
||
2492 | */ |
||
2493 | //static int test_enable_load( |
||
2494 | // object clientdata, /* Not used */ |
||
2495 | // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2496 | // int objc, /* Number of arguments */ |
||
2497 | // Tcl_Obj[] objv /* Command arguments */ |
||
2498 | //){ |
||
2499 | // TCL.Tcl_CmdInfo cmdInfo; |
||
2500 | // sqlite3 db=null; |
||
2501 | // string zDb; |
||
2502 | // int onoff; |
||
2503 | |||
2504 | // if( objc!=3 ){ |
||
2505 | // TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB-HANDLE ONOFF"); |
||
2506 | // return TCL.TCL_ERROR; |
||
2507 | // } |
||
2508 | // zDb = TCL.Tcl_GetString(objv[1]); |
||
2509 | |||
2510 | // /* Extract the C database handle from the Tcl command name */ |
||
2511 | // if( null==TCL.Tcl_GetCommandInfo(interp, zDb, cmdInfo) ){ |
||
2512 | // TCL.Tcl_AppendResult(interp, "command not found: ", zDb); |
||
2513 | // return TCL.TCL_ERROR; |
||
2514 | // } |
||
2515 | // db = ((struct SqliteDb)cmdInfo.objclientdata).db; |
||
2516 | // Debug.Assert(db); |
||
2517 | |||
2518 | // /* Get the onoff parameter */ |
||
2519 | // if( TCL.Tcl_GetBooleanFromObj(interp, objv[2], out onoff) ){ |
||
2520 | // return TCL.TCL_ERROR; |
||
2521 | // } |
||
2522 | |||
2523 | #if SQLITE_OMIT_LOAD_EXTENSION |
||
2524 | // TCL.Tcl_AppendResult(interp, "this build omits sqlite3_load_extension()"); |
||
2525 | // return TCL.TCL_ERROR; |
||
2526 | #else |
||
2527 | // sqlite3_enable_load_extension(db, onoff); |
||
2528 | // return TCL.TCL_OK; |
||
2529 | #endif |
||
2530 | //} |
||
2531 | |||
2532 | /* |
||
2533 | ** Usage: sqlite_abort |
||
2534 | ** |
||
2535 | ** Shutdown the process immediately. This is not a clean shutdown. |
||
2536 | ** This command is used to test the recoverability of a database in |
||
2537 | ** the event of a program crash. |
||
2538 | */ |
||
2539 | //static int sqlite_abort( |
||
2540 | // object NotUsed, |
||
2541 | // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2542 | // int argc, /* Number of arguments */ |
||
2543 | // Tcl_Obj[] argv /* Text of each argument */ |
||
2544 | //){ |
||
2545 | //#if defined(_MSC_VER) |
||
2546 | // /* We do this, otherwise the test will halt with a popup message |
||
2547 | // * that we have to click away before the test will continue. |
||
2548 | // */ |
||
2549 | // _set_abort_behavior( 0, _CALL_REPORTFAULT ); |
||
2550 | //#endif |
||
2551 | // exit(255); |
||
2552 | // Debug.Assert( interp==0 ); /* This will always fail */ |
||
2553 | // return TCL.TCL_OK; |
||
2554 | //} |
||
2555 | |||
2556 | /* |
||
2557 | ** The following routine is a user-defined SQL function whose purpose |
||
2558 | ** is to test the sqlite_set_result() API. |
||
2559 | */ |
||
2560 | static void testFunc( sqlite3_context context, int argc, sqlite3_value[] argv ) |
||
2561 | { |
||
2562 | int ARGV = 0; |
||
2563 | while ( argc >= 2 ) |
||
2564 | { |
||
2565 | string zArg0 = sqlite3_value_text( argv[ARGV] ); |
||
2566 | if ( zArg0 != null ) |
||
2567 | { |
||
2568 | if ( zArg0.Equals( "int", StringComparison.InvariantCultureIgnoreCase ) ) |
||
2569 | { |
||
2570 | sqlite3_result_int( context, sqlite3_value_int( argv[ARGV + 1] ) ); |
||
2571 | } |
||
2572 | else if ( zArg0.Equals( "int64", StringComparison.InvariantCultureIgnoreCase ) ) |
||
2573 | { |
||
2574 | sqlite3_result_int64( context, sqlite3_value_int64( argv[ARGV + 1] ) ); |
||
2575 | } |
||
2576 | else if ( zArg0.Equals( "string", StringComparison.InvariantCultureIgnoreCase ) ) |
||
2577 | { |
||
2578 | sqlite3_result_text( context, sqlite3_value_text( argv[ARGV + 1] ), -1, |
||
2579 | SQLITE_TRANSIENT ); |
||
2580 | } |
||
2581 | else if ( zArg0.Equals( "double", StringComparison.InvariantCultureIgnoreCase ) ) |
||
2582 | { |
||
2583 | sqlite3_result_double( context, sqlite3_value_double( argv[ARGV + 1] ) ); |
||
2584 | } |
||
2585 | else if ( zArg0.Equals( "null", StringComparison.InvariantCultureIgnoreCase ) ) |
||
2586 | { |
||
2587 | sqlite3_result_null( context ); |
||
2588 | } |
||
2589 | else if ( zArg0.Equals( "value", StringComparison.InvariantCultureIgnoreCase ) ) |
||
2590 | { |
||
2591 | sqlite3_result_value( context, argv[sqlite3_value_int( argv[ARGV + 1] )] ); |
||
2592 | } |
||
2593 | else |
||
2594 | { |
||
2595 | goto error_out; |
||
2596 | } |
||
2597 | } |
||
2598 | else |
||
2599 | { |
||
2600 | goto error_out; |
||
2601 | } |
||
2602 | argc -= 2; |
||
2603 | ARGV += 2; |
||
2604 | } |
||
2605 | return; |
||
2606 | |||
2607 | error_out: |
||
2608 | sqlite3_result_error( context, "first argument should be one of: " + |
||
2609 | "int int64 string double null value", -1 ); |
||
2610 | } |
||
2611 | |||
2612 | /* |
||
2613 | ** Usage: sqlite_register_test_function DB NAME |
||
2614 | ** |
||
2615 | ** Register the test SQL function on the database DB under the name NAME. |
||
2616 | */ |
||
2617 | static int test_register_func( |
||
2618 | object NotUsed, |
||
2619 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2620 | int argc, /* Number of arguments */ |
||
2621 | Tcl_Obj[] argv /* Text of each argument */ |
||
2622 | ) |
||
2623 | { |
||
2624 | sqlite3 db = null; |
||
2625 | int rc; |
||
2626 | if ( argc != 3 ) |
||
2627 | { |
||
2628 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
2629 | " DB FUNCTION-NAME" ); |
||
2630 | return TCL.TCL_ERROR; |
||
2631 | } |
||
2632 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
2633 | return TCL.TCL_ERROR; |
||
2634 | rc = sqlite3_create_function( db, argv[2].ToString(), -1, SQLITE_UTF8, 0, |
||
2635 | testFunc, null, null ); |
||
2636 | if ( rc != 0 ) |
||
2637 | { |
||
2638 | TCL.Tcl_AppendResult( interp, sqlite3ErrStr( rc ) ); |
||
2639 | return TCL.TCL_ERROR; |
||
2640 | } |
||
2641 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
2642 | return TCL.TCL_ERROR; |
||
2643 | return TCL.TCL_OK; |
||
2644 | } |
||
2645 | |||
2646 | /* |
||
2647 | ** Usage: sqlite3_finalize STMT |
||
2648 | ** |
||
2649 | ** Finalize a statement handle. |
||
2650 | */ |
||
2651 | static int test_finalize( |
||
2652 | object clientdata, |
||
2653 | Tcl_Interp interp, |
||
2654 | int objc, |
||
2655 | Tcl_Obj[] objv |
||
2656 | ) |
||
2657 | { |
||
2658 | sqlite3_stmt pStmt = null; |
||
2659 | int rc; |
||
2660 | sqlite3 db = null; |
||
2661 | |||
2662 | if ( objc != 2 ) |
||
2663 | { |
||
2664 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
2665 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " <STMT>" ); |
||
2666 | return TCL.TCL_ERROR; |
||
2667 | } |
||
2668 | |||
2669 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
2670 | return TCL.TCL_ERROR; |
||
2671 | |||
2672 | if ( pStmt != null ) |
||
2673 | { |
||
2674 | db = sqlite3_db_handle( pStmt );// StmtToDb( pStmt ); |
||
2675 | } |
||
2676 | rc = sqlite3_finalize( pStmt ); |
||
2677 | TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), TCL.TCL_STATIC );//t1ErrorName( rc ), TCL.TCL_STATIC ); |
||
2678 | if ( db != null && sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
2679 | return TCL.TCL_ERROR; |
||
2680 | return TCL.TCL_OK; |
||
2681 | } |
||
2682 | |||
2683 | /* |
||
2684 | ** Usage: sqlite3_stmt_status STMT CODE RESETFLAG |
||
2685 | ** |
||
2686 | ** Get the value of a status counter from a statement. |
||
2687 | */ |
||
2688 | static int test_stmt_status( |
||
2689 | object clientdata, |
||
2690 | Tcl_Interp interp, |
||
2691 | int objc, |
||
2692 | Tcl_Obj[] objv |
||
2693 | ) |
||
2694 | { |
||
2695 | int iValue; |
||
2696 | int i, op = 0; |
||
2697 | bool resetFlag = false; |
||
2698 | string zOpName; |
||
2699 | sqlite3_stmt pStmt = null; |
||
2700 | |||
2701 | //struct _aOp{ |
||
2702 | // string zName; |
||
2703 | // int op; |
||
2704 | //} |
||
2705 | _aOp[] aOp = { |
||
2706 | new _aOp( "SQLITE_STMTSTATUS_FULLSCAN_STEP", SQLITE_STMTSTATUS_FULLSCAN_STEP ), |
||
2707 | new _aOp( "SQLITE_STMTSTATUS_SORT", SQLITE_STMTSTATUS_SORT ), |
||
2708 | new _aOp( "SQLITE_STMTSTATUS_AUTOINDEX", SQLITE_STMTSTATUS_AUTOINDEX ) |
||
2709 | }; |
||
2710 | |||
2711 | if ( objc != 4 ) |
||
2712 | { |
||
2713 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT PARAMETER RESETFLAG" ); |
||
2714 | return TCL.TCL_ERROR; |
||
2715 | } |
||
2716 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
2717 | return TCL.TCL_ERROR; |
||
2718 | zOpName = TCL.Tcl_GetString( objv[2] ); |
||
2719 | for ( i = 0; i < ArraySize( aOp ); i++ ) |
||
2720 | { |
||
2721 | if ( aOp[i].zName == zOpName ) |
||
2722 | { |
||
2723 | op = aOp[i].op; |
||
2724 | break; |
||
2725 | } |
||
2726 | } |
||
2727 | if ( i >= ArraySize( aOp ) ) |
||
2728 | { |
||
2729 | if ( TCL.Tcl_GetIntFromObj( interp, objv[2], out op ) != 0 ) |
||
2730 | return TCL.TCL_ERROR; |
||
2731 | } |
||
2732 | if ( TCL.Tcl_GetBooleanFromObj( interp, objv[3], out resetFlag ) ) |
||
2733 | return TCL.TCL_ERROR; |
||
2734 | iValue = sqlite3_stmt_status( pStmt, op, resetFlag ? 1 : 0 ); |
||
2735 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( iValue ) ); |
||
2736 | return TCL.TCL_OK; |
||
2737 | } |
||
2738 | |||
2739 | /* |
||
2740 | ** Usage: sqlite3_next_stmt DB STMT |
||
2741 | ** |
||
2742 | ** Return the next statment in sequence after STMT. |
||
2743 | */ |
||
2744 | static int test_next_stmt( |
||
2745 | object clientdata, |
||
2746 | Tcl_Interp interp, |
||
2747 | int objc, |
||
2748 | Tcl_Obj[] objv |
||
2749 | ) |
||
2750 | { |
||
2751 | sqlite3_stmt pStmt = null; |
||
2752 | sqlite3 db = null; |
||
2753 | StringBuilder zBuf = new StringBuilder( 50 ); |
||
2754 | if ( objc != 3 ) |
||
2755 | { |
||
2756 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
2757 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB STMT" ); |
||
2758 | return TCL.TCL_ERROR; |
||
2759 | } |
||
2760 | |||
2761 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
2762 | return TCL.TCL_ERROR; |
||
2763 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[2] ), out pStmt ) != 0 ) |
||
2764 | return TCL.TCL_ERROR; |
||
2765 | pStmt = sqlite3_next_stmt( db, pStmt ); |
||
2766 | if ( pStmt != null ) |
||
2767 | { |
||
2768 | if ( sqlite3TestMakePointerStr( interp, zBuf, pStmt ) != 0 ) |
||
2769 | return TCL.TCL_ERROR; |
||
2770 | TCL.Tcl_AppendResult( interp, zBuf ); |
||
2771 | } |
||
2772 | return TCL.TCL_OK; |
||
2773 | } |
||
2774 | |||
2775 | /* |
||
2776 | ** Usage: sqlite3_stmt_readonly STMT |
||
2777 | ** |
||
2778 | ** Return true if STMT is a NULL pointer or a pointer to a statement |
||
2779 | ** that is guaranteed to leave the database unmodified. |
||
2780 | */ |
||
2781 | static int test_stmt_readonly( |
||
2782 | object clientData, |
||
2783 | Tcl_Interp interp, |
||
2784 | int objc, |
||
2785 | Tcl_Obj[] objv |
||
2786 | ) |
||
2787 | { |
||
2788 | sqlite3_stmt pStmt = null; |
||
2789 | int rc; |
||
2790 | |||
2791 | if ( objc != 2 ) |
||
2792 | { |
||
2793 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
2794 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT", 0 ); |
||
2795 | return TCL.TCL_ERROR; |
||
2796 | } |
||
2797 | |||
2798 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
2799 | return TCL.TCL_ERROR; |
||
2800 | rc = sqlite3_stmt_readonly( pStmt ) ? 1 : 0; |
||
2801 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( rc ) ); |
||
2802 | return TCL.TCL_OK; |
||
2803 | } |
||
2804 | |||
2805 | /* |
||
2806 | ** Usage: uses_stmt_journal STMT |
||
2807 | ** |
||
2808 | ** Return true if STMT uses a statement journal. |
||
2809 | */ |
||
2810 | static int uses_stmt_journal( |
||
2811 | object clientdata, |
||
2812 | Tcl_Interp interp, |
||
2813 | int objc, |
||
2814 | Tcl_Obj[] objv |
||
2815 | ) |
||
2816 | { |
||
2817 | sqlite3_stmt pStmt = null; |
||
2818 | int rc; |
||
2819 | |||
2820 | if ( objc != 2 ) |
||
2821 | { |
||
2822 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
2823 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT", 0 ); |
||
2824 | return TCL.TCL_ERROR; |
||
2825 | } |
||
2826 | |||
2827 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
2828 | return TCL.TCL_ERROR; |
||
2829 | rc = sqlite3_stmt_readonly( pStmt ) ? 1 : 0; |
||
2830 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( pStmt.usesStmtJournal ? 1 : 0 ) ); |
||
2831 | return TCL.TCL_OK; |
||
2832 | } |
||
2833 | |||
2834 | /* |
||
2835 | ** Usage: sqlite3_reset STMT |
||
2836 | ** |
||
2837 | ** Reset a statement handle. |
||
2838 | */ |
||
2839 | static int test_reset( |
||
2840 | object clientdata, |
||
2841 | Tcl_Interp interp, |
||
2842 | int objc, |
||
2843 | Tcl_Obj[] objv |
||
2844 | ) |
||
2845 | { |
||
2846 | sqlite3_stmt pStmt = null; |
||
2847 | int rc; |
||
2848 | |||
2849 | if ( objc != 2 ) |
||
2850 | { |
||
2851 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
2852 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " <STMT>" ); |
||
2853 | return TCL.TCL_ERROR; |
||
2854 | } |
||
2855 | |||
2856 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
2857 | return TCL.TCL_ERROR; |
||
2858 | |||
2859 | rc = sqlite3_reset( pStmt ); |
||
2860 | if ( pStmt != null && sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
2861 | { |
||
2862 | return TCL.TCL_ERROR; |
||
2863 | } |
||
2864 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
||
2865 | /* |
||
2866 | if( rc !=0){ |
||
2867 | return TCL.TCL_ERROR; |
||
2868 | } |
||
2869 | */ |
||
2870 | return TCL.TCL_OK; |
||
2871 | } |
||
2872 | |||
2873 | /* |
||
2874 | ** Usage: sqlite3_expired STMT |
||
2875 | ** |
||
2876 | ** Return TRUE if a recompilation of the statement is recommended. |
||
2877 | */ |
||
2878 | static int test_expired( |
||
2879 | object clientdata, |
||
2880 | Tcl_Interp interp, |
||
2881 | int objc, |
||
2882 | Tcl_Obj[] objv |
||
2883 | ) |
||
2884 | { |
||
2885 | #if !SQLITE_OMIT_DEPRECATED |
||
2886 | sqlite3_stmt pStmt = null; |
||
2887 | if ( objc != 2 ) |
||
2888 | { |
||
2889 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
2890 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " <STMT>" ); |
||
2891 | return TCL.TCL_ERROR; |
||
2892 | } |
||
2893 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) return TCL.TCL_ERROR; |
||
2894 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( sqlite3_expired( pStmt ) ) ); |
||
2895 | #endif |
||
2896 | TCL.Tcl_SetResult( interp, "0", 0 ); |
||
2897 | return TCL.TCL_OK; |
||
2898 | } |
||
2899 | |||
2900 | /* |
||
2901 | ** Usage: sqlite3TransferBindings FROMSTMT TOSTMT |
||
2902 | ** |
||
2903 | ** Transfer all bindings from FROMSTMT over to TOSTMT |
||
2904 | */ |
||
2905 | static int test_transfer_bind( |
||
2906 | object clientdata, |
||
2907 | Tcl_Interp interp, |
||
2908 | int objc, |
||
2909 | Tcl_Obj[] objv |
||
2910 | ) |
||
2911 | { |
||
2912 | #if !SQLITE_OMIT_DEPRECATED |
||
2913 | sqlite3_stmt pStmt1 = null, pStmt2 = null; |
||
2914 | if ( objc != 3 ) |
||
2915 | { |
||
2916 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
2917 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " FROM-STMT TO-STMT" ); |
||
2918 | return TCL.TCL_ERROR; |
||
2919 | } |
||
2920 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt1 ) != 0 ) return TCL.TCL_ERROR; |
||
2921 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[2] ), out pStmt2 ) != 0 ) return TCL.TCL_ERROR; |
||
2922 | TCL.Tcl_SetObjResult( interp, |
||
2923 | TCL.Tcl_NewIntObj( pStmt1.nVar == pStmt2.nVar ? sqlite3TransferBindings( pStmt1, pStmt2 ) : TCL.TCL_ERROR ) ); |
||
2924 | #endif |
||
2925 | return TCL.TCL_OK; |
||
2926 | } |
||
2927 | |||
2928 | /* |
||
2929 | ** Usage: sqlite3_changes DB |
||
2930 | ** |
||
2931 | ** Return the number of changes made to the database by the last SQL |
||
2932 | ** execution. |
||
2933 | */ |
||
2934 | static int test_changes( |
||
2935 | object clientdata, |
||
2936 | Tcl_Interp interp, |
||
2937 | int objc, |
||
2938 | Tcl_Obj[] objv |
||
2939 | ) |
||
2940 | { |
||
2941 | sqlite3 db = null; |
||
2942 | if ( objc != 2 ) |
||
2943 | { |
||
2944 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
2945 | TCL.Tcl_GetString( objv[0] ), " DB" ); |
||
2946 | return TCL.TCL_ERROR; |
||
2947 | } |
||
2948 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
2949 | return TCL.TCL_ERROR; |
||
2950 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_changes( db ) ) ); |
||
2951 | return TCL.TCL_OK; |
||
2952 | } |
||
2953 | |||
2954 | /* |
||
2955 | ** This is the "static_bind_value" that variables are bound to when |
||
2956 | ** the FLAG option of sqlite3_bind is "static" |
||
2957 | */ |
||
2958 | //static string sqlite_static_bind_value = ""; |
||
2959 | //static int sqlite_static_bind_nbyte = 0; |
||
2960 | |||
2961 | /* |
||
2962 | ** Usage: sqlite3_bind VM IDX VALUE FLAGS |
||
2963 | ** |
||
2964 | ** Sets the value of the IDX-th occurance of "?" in the original SQL |
||
2965 | ** string. VALUE is the new value. If FLAGS=="null" then VALUE is |
||
2966 | ** ignored and the value is set to NULL. If FLAGS=="static" then |
||
2967 | ** the value is set to the value of a static variable named |
||
2968 | ** "sqlite_static_bind_value". If FLAGS=="normal" then a copy |
||
2969 | ** of the VALUE is made. If FLAGS=="blob10" then a VALUE is ignored |
||
2970 | ** an a 10-byte blob "abc\000xyz\000pq" is inserted. |
||
2971 | */ |
||
2972 | static int test_bind( |
||
2973 | object NotUsed, |
||
2974 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
2975 | int argc, /* Number of arguments */ |
||
2976 | Tcl_Obj[] argv /* Text of each argument */ |
||
2977 | ) |
||
2978 | { |
||
2979 | sqlite3_stmt pStmt = null; |
||
2980 | int rc; |
||
2981 | int idx = 0; |
||
2982 | if ( argc != 5 ) |
||
2983 | { |
||
2984 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
2985 | " VM IDX VALUE (null|static|normal)\"" ); |
||
2986 | return TCL.TCL_ERROR; |
||
2987 | } |
||
2988 | if ( getStmtPointer( interp, argv[1].ToString(), out pStmt ) != 0 ) |
||
2989 | return TCL.TCL_ERROR; |
||
2990 | if ( TCL.Tcl_GetInt( interp, argv[2], out idx ) ) |
||
2991 | return TCL.TCL_ERROR; |
||
2992 | if ( argv[4].ToString() == "null" ) |
||
2993 | { |
||
2994 | rc = sqlite3_bind_null( pStmt, idx ); |
||
2995 | } |
||
2996 | else if ( argv[4].ToString() == "static" ) |
||
2997 | { |
||
2998 | rc = sqlite3_bind_text( pStmt, idx, sqlite_static_bind_value.sValue, -1, null ); |
||
2999 | } |
||
3000 | else if ( argv[4].ToString() == "static-nbytes" ) |
||
3001 | { |
||
3002 | rc = sqlite3_bind_text( pStmt, idx, sqlite_static_bind_value.sValue, |
||
3003 | sqlite_static_bind_nbyte.iValue, null ); |
||
3004 | } |
||
3005 | else if ( argv[4].ToString() == "normal" ) |
||
3006 | { |
||
3007 | rc = sqlite3_bind_text( pStmt, idx, argv[3].ToString(), -1, SQLITE_TRANSIENT ); |
||
3008 | } |
||
3009 | else if ( argv[4].ToString() == "blob10" ) |
||
3010 | { |
||
3011 | rc = sqlite3_bind_text( pStmt, idx, "abc\0xyz\0pq", 10, SQLITE_STATIC ); |
||
3012 | } |
||
3013 | else |
||
3014 | { |
||
3015 | TCL.Tcl_AppendResult( interp, "4th argument should be " + |
||
3016 | "\"null\" or \"static\" or \"normal\"" ); |
||
3017 | return TCL.TCL_ERROR; |
||
3018 | } |
||
3019 | if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
3020 | return TCL.TCL_ERROR; |
||
3021 | if ( rc != 0 ) |
||
3022 | { |
||
3023 | StringBuilder zBuf = new StringBuilder( 50 ); |
||
3024 | sqlite3_snprintf( 50, zBuf, "(%d) ", rc ); |
||
3025 | TCL.Tcl_SetResult( interp, zBuf + sqlite3ErrStr( rc ), 0 ); |
||
3026 | return TCL.TCL_ERROR; |
||
3027 | } |
||
3028 | return TCL.TCL_OK; |
||
3029 | } |
||
3030 | |||
3031 | #if !SQLITE_OMIT_UTF16 |
||
3032 | /* |
||
3033 | ** Usage: add_test_collate <db ptr> <utf8> <utf16le> <utf16be> |
||
3034 | ** |
||
3035 | ** This function is used to test that SQLite selects the correct collation |
||
3036 | ** sequence callback when multiple versions (for different text encodings) |
||
3037 | ** are available. |
||
3038 | ** |
||
3039 | ** Calling this routine registers the collation sequence "test_collate" |
||
3040 | ** with database handle <db>. The second argument must be a list of three |
||
3041 | ** boolean values. If the first is true, then a version of test_collate is |
||
3042 | ** registered for UTF-8, if the second is true, a version is registered for |
||
3043 | ** UTF-16le, if the third is true, a UTF-16be version is available. |
||
3044 | ** Previous versions of test_collate are deleted. |
||
3045 | ** |
||
3046 | ** The collation sequence test_collate is implemented by calling the |
||
3047 | ** following TCL script: |
||
3048 | ** |
||
3049 | ** "test_collate <enc> <lhs> <rhs>" |
||
3050 | ** |
||
3051 | ** The <lhs> and <rhs> are the two values being compared, encoded in UTF-8. |
||
3052 | ** The <enc> parameter is the encoding of the collation function that |
||
3053 | ** SQLite selected to call. The TCL test script implements the |
||
3054 | ** "test_collate" proc. |
||
3055 | ** |
||
3056 | ** Note that this will only work with one intepreter at a time, as the |
||
3057 | ** interp pointer to use when evaluating the TCL script is stored in |
||
3058 | ** pTestCollateInterp. |
||
3059 | */ |
||
3060 | //static Tcl_Interp * pTestCollateInterp; |
||
3061 | //static int test_collate_func( |
||
3062 | // object pCtx,, |
||
3063 | // int nA, string zA, |
||
3064 | // int nB, string zB |
||
3065 | //){ |
||
3066 | // Tcl_Interp *i = pTestCollateInterp; |
||
3067 | // int encin = SQLITE_PTR_TO_INT(pCtx); |
||
3068 | // int res; |
||
3069 | // int n; |
||
3070 | |||
3071 | // sqlite3_value pVal; |
||
3072 | // Tcl_Obj pX; |
||
3073 | |||
3074 | // pX = TCL.Tcl_NewStringObj("test_collate", -1); |
||
3075 | // TCL.Tcl_IncrRefCount(pX); |
||
3076 | |||
3077 | // switch( encin ){ |
||
3078 | // case SQLITE_UTF8: |
||
3079 | // TCL.Tcl_ListObjAppendElement(i,pX,TCL.Tcl_NewStringObj("UTF-8",-1)); |
||
3080 | // break; |
||
3081 | // case SQLITE_UTF16LE: |
||
3082 | // TCL.Tcl_ListObjAppendElement(i,pX,TCL.Tcl_NewStringObj("UTF-16LE",-1)); |
||
3083 | // break; |
||
3084 | // case SQLITE_UTF16BE: |
||
3085 | // TCL.Tcl_ListObjAppendElement(i,pX,TCL.Tcl_NewStringObj("UTF-16BE",-1)); |
||
3086 | // break; |
||
3087 | // default: |
||
3088 | // Debug.Assert(false); |
||
3089 | // } |
||
3090 | |||
3091 | //sqlite3BeginBenignMalloc(); |
||
3092 | // pVal = sqlite3ValueNew(0); |
||
3093 | // if( pVal ){ |
||
3094 | // sqlite3ValueSetStr(pVal, nA, zA, encin, SQLITE_STATIC); |
||
3095 | // n = sqlite3_value_bytes(pVal); |
||
3096 | // TCL.Tcl_ListObjAppendElement(i,pX, |
||
3097 | // TCL.Tcl_NewStringObj((char)sqlite3_value_text(pVal),n)); |
||
3098 | // sqlite3ValueSetStr(pVal, nB, zB, encin, SQLITE_STATIC); |
||
3099 | // n = sqlite3_value_bytes(pVal); |
||
3100 | // TCL.Tcl_ListObjAppendElement(i,pX, |
||
3101 | // TCL.Tcl_NewStringObj((char)sqlite3_value_text(pVal),n)); |
||
3102 | // sqlite3ValueFree(pVal); |
||
3103 | //} |
||
3104 | //sqlite3EndBenignMalloc(); |
||
3105 | |||
3106 | // TCL.Tcl_EvalObjEx(i, pX, 0); |
||
3107 | // TCL.Tcl_DecrRefCount(pX); |
||
3108 | // TCL.Tcl_GetIntFromObj(i, TCL.Tcl_GetObjResult(i), res); |
||
3109 | // return res; |
||
3110 | //} |
||
3111 | //static int test_collate( |
||
3112 | // object clientdata, |
||
3113 | // Tcl_Interp interp, |
||
3114 | // int objc, |
||
3115 | // Tcl_Obj[] objv |
||
3116 | //){ |
||
3117 | // sqlite3 db=null; |
||
3118 | // int val; |
||
3119 | // sqlite3_value pVal; |
||
3120 | // int rc; |
||
3121 | |||
3122 | // if( objc!=5 ) goto bad_args; |
||
3123 | // pTestCollateInterp = interp; |
||
3124 | // if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
||
3125 | |||
3126 | // if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[2], out val) ) return TCL.TCL_ERROR; |
||
3127 | // rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, |
||
3128 | // (void )SQLITE_UTF8, val?test_collate_func:0); |
||
3129 | // if( rc==SQLITE_OK ){ |
||
3130 | // string zUtf16; |
||
3131 | // if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[3], out val) ) return TCL.TCL_ERROR; |
||
3132 | // rc = sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, |
||
3133 | // (void )SQLITE_UTF16LE, val?test_collate_func:0); |
||
3134 | // if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[4], out val) ) return TCL.TCL_ERROR; |
||
3135 | |||
3136 | //#if FALSE |
||
3137 | // if( sqlite3_iMallocFail>0 ){ |
||
3138 | // sqlite3_iMallocFail++; |
||
3139 | // } |
||
3140 | //#endif |
||
3141 | // sqlite3_mutex_enter(db.mutex); |
||
3142 | // pVal = sqlite3ValueNew(db); |
||
3143 | // sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC); |
||
3144 | // zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE); |
||
3145 | // if( db.mallocFailed !=0{ |
||
3146 | // rc = SQLITE_NOMEM; |
||
3147 | // }else{ |
||
3148 | // rc = sqlite3_create_collation16(db, zUtf16, SQLITE_UTF16BE, |
||
3149 | // (void )SQLITE_UTF16BE, val?test_collate_func:0); |
||
3150 | // } |
||
3151 | // sqlite3ValueFree(pVal); |
||
3152 | // sqlite3_mutex_leave(db.mutex); |
||
3153 | // } |
||
3154 | // if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
||
3155 | |||
3156 | // if( rc!=SQLITE_OK ){ |
||
3157 | // TCL.Tcl_AppendResult(interp, sqlite3TestErrorName(rc)); |
||
3158 | // return TCL.TCL_ERROR; |
||
3159 | // } |
||
3160 | // return TCL.TCL_OK; |
||
3161 | |||
3162 | //bad_args: |
||
3163 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
3164 | // TCL.Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); |
||
3165 | // return TCL.TCL_ERROR; |
||
3166 | //} |
||
3167 | |||
3168 | /* |
||
3169 | ** When the collation needed callback is invoked, record the name of |
||
3170 | ** the requested collating function here. The recorded name is linked |
||
3171 | ** to a TCL variable and used to make sure that the requested collation |
||
3172 | ** name is correct. |
||
3173 | */ |
||
3174 | //static char zNeededCollation[200]; |
||
3175 | //static char pzNeededCollation = zNeededCollation; |
||
3176 | |||
3177 | |||
3178 | /* |
||
3179 | ** Called when a collating sequence is needed. Registered using |
||
3180 | ** sqlite3_collation_needed16(). |
||
3181 | */ |
||
3182 | //static void test_collate_needed_cb( |
||
3183 | // object pCtx,, |
||
3184 | // sqlite3 db, |
||
3185 | // int eTextRep, |
||
3186 | // const void pName |
||
3187 | //){ |
||
3188 | // int enc = ENC(db); |
||
3189 | // int i; |
||
3190 | // string z; |
||
3191 | // for(z = (char)pName, i=0; *z || z[1]; z++){ |
||
3192 | // if( *z ) zNeededCollation[i++] = *z; |
||
3193 | // } |
||
3194 | // zNeededCollation[i] = 0; |
||
3195 | // sqlite3_create_collation( |
||
3196 | // db, "test_collate", ENC(db), SQLITE_INT_TO_PTR(enc), test_collate_func); |
||
3197 | //} |
||
3198 | |||
3199 | /* |
||
3200 | ** Usage: add_test_collate_needed DB |
||
3201 | */ |
||
3202 | //static int test_collate_needed( |
||
3203 | // object clientdata, |
||
3204 | // Tcl_Interp interp, |
||
3205 | // int objc, |
||
3206 | // Tcl_Obj[] objv |
||
3207 | //){ |
||
3208 | // sqlite3 db=null; |
||
3209 | // int rc; |
||
3210 | |||
3211 | // if( objc!=2 ) goto bad_args; |
||
3212 | // if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
||
3213 | // rc = sqlite3_collation_needed16(db, 0, test_collate_needed_cb); |
||
3214 | // zNeededCollation[0] = 0; |
||
3215 | // if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
||
3216 | // return TCL.TCL_OK; |
||
3217 | |||
3218 | //bad_args: |
||
3219 | // TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
||
3220 | // return TCL.TCL_ERROR; |
||
3221 | //} |
||
3222 | |||
3223 | /* |
||
3224 | ** tclcmd: add_alignment_test_collations DB |
||
3225 | ** |
||
3226 | ** Add two new collating sequences to the database DB |
||
3227 | ** |
||
3228 | ** utf16_aligned |
||
3229 | ** utf16_unaligned |
||
3230 | ** |
||
3231 | ** Both collating sequences use the same sort order as BINARY. |
||
3232 | ** The only difference is that the utf16_aligned collating |
||
3233 | ** sequence is declared with the SQLITE_UTF16_ALIGNED flag. |
||
3234 | ** Both collating functions increment the unaligned utf16 counter |
||
3235 | ** whenever they see a string that begins on an odd byte boundary. |
||
3236 | */ |
||
3237 | //static int unaligned_string_counter = 0; |
||
3238 | //static int alignmentCollFunc( |
||
3239 | // object NotUsed, |
||
3240 | // int nKey1, const void pKey1, |
||
3241 | // int nKey2, const void pKey2 |
||
3242 | //){ |
||
3243 | // int rc, n; |
||
3244 | // n = nKey1<nKey2 ? nKey1 : nKey2; |
||
3245 | //if( nKey1>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey1))) ) unaligned_string_counter++; |
||
3246 | //if( nKey2>0 && 1==(1&(SQLITE_PTR_TO_INT(pKey2))) ) unaligned_string_counter++; |
||
3247 | // rc = memcmp(pKey1, pKey2, n); |
||
3248 | // if( rc==0 ){ |
||
3249 | // rc = nKey1 - nKey2; |
||
3250 | // } |
||
3251 | // return rc; |
||
3252 | //} |
||
3253 | //static int add_alignment_test_collations( |
||
3254 | // object clientdata, |
||
3255 | // Tcl_Interp interp, |
||
3256 | // int objc, |
||
3257 | // Tcl_Obj[] objv |
||
3258 | //){ |
||
3259 | // sqlite3 db=null; |
||
3260 | // if( objc>=2 ){ |
||
3261 | // if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
||
3262 | // sqlite3_create_collation(db, "utf16_unaligned", SQLITE_UTF16, |
||
3263 | // 0, alignmentCollFunc); |
||
3264 | // sqlite3_create_collation(db, "utf16_aligned", SQLITE_UTF16_ALIGNED, |
||
3265 | // 0, alignmentCollFunc); |
||
3266 | // } |
||
3267 | // return SQLITE_OK; |
||
3268 | //} |
||
3269 | #endif // * !SQLITE_OMIT_UTF16) */ |
||
3270 | |||
3271 | /* |
||
3272 | ** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be> |
||
3273 | ** |
||
3274 | ** This function is used to test that SQLite selects the correct user |
||
3275 | ** function callback when multiple versions (for different text encodings) |
||
3276 | ** are available. |
||
3277 | ** |
||
3278 | ** Calling this routine registers up to three versions of the user function |
||
3279 | ** "test_function" with database handle <db>. If the second argument is |
||
3280 | ** true, then a version of test_function is registered for UTF-8, if the |
||
3281 | ** third is true, a version is registered for UTF-16le, if the fourth is |
||
3282 | ** true, a UTF-16be version is available. Previous versions of |
||
3283 | ** test_function are deleted. |
||
3284 | ** |
||
3285 | ** The user function is implemented by calling the following TCL script: |
||
3286 | ** |
||
3287 | ** "test_function <enc> <arg>" |
||
3288 | ** |
||
3289 | ** Where <enc> is one of UTF-8, UTF-16LE or UTF16BE, and <arg> is the |
||
3290 | ** single argument passed to the SQL function. The value returned by |
||
3291 | ** the TCL script is used as the return value of the SQL function. It |
||
3292 | ** is passed to SQLite using UTF-16BE for a UTF-8 test_function(), UTF-8 |
||
3293 | ** for a UTF-16LE test_function(), and UTF-16LE for an implementation that |
||
3294 | ** prefers UTF-16BE. |
||
3295 | */ |
||
3296 | #if !SQLITE_OMIT_UTF16 |
||
3297 | //static void test_function_utf8( |
||
3298 | // sqlite3_context pCtx, |
||
3299 | // int nArg, |
||
3300 | // sqlite3_value[] argv |
||
3301 | //){ |
||
3302 | // Tcl_Interp interp; |
||
3303 | // Tcl_Obj pX; |
||
3304 | // sqlite3_value pVal; |
||
3305 | // interp = (Tcl_Interp )sqlite3_context_db_handle(pCtx); |
||
3306 | // pX = TCL.Tcl_NewStringObj("test_function", -1); |
||
3307 | // TCL.Tcl_IncrRefCount(pX); |
||
3308 | // TCL.Tcl_ListObjAppendElement(interp, pX, TCL.Tcl_NewStringObj("UTF-8", -1)); |
||
3309 | // TCL.Tcl_ListObjAppendElement(interp, pX, |
||
3310 | // TCL.Tcl_NewStringObj((char)sqlite3_value_text(argv[0]), -1)); |
||
3311 | // TCL.Tcl_EvalObjEx(interp, pX, 0); |
||
3312 | // TCL.Tcl_DecrRefCount(pX); |
||
3313 | // sqlite3_result_text(pCtx, TCL.Tcl_GetStringResult(interp), -1, SQLITE_TRANSIENT); |
||
3314 | // pVal = sqlite3ValueNew(0); |
||
3315 | // sqlite3ValueSetStr(pVal, -1, TCL.Tcl_GetStringResult(interp), |
||
3316 | // SQLITE_UTF8, SQLITE_STATIC); |
||
3317 | // sqlite3_result_text16be(pCtx, sqlite3_value_text16be(pVal), |
||
3318 | // -1, SQLITE_TRANSIENT); |
||
3319 | // sqlite3ValueFree(pVal); |
||
3320 | //} |
||
3321 | //static void test_function_utf16le( |
||
3322 | // sqlite3_context pCtx, |
||
3323 | // int nArg, |
||
3324 | // sqlite3_value[] argv |
||
3325 | //){ |
||
3326 | // Tcl_Interp interp; |
||
3327 | // Tcl_Obj pX; |
||
3328 | // sqlite3_value pVal; |
||
3329 | // interp = (Tcl_Interp )sqlite3_context_db_handle(pCtx); |
||
3330 | // pX = TCL.Tcl_NewStringObj("test_function", -1); |
||
3331 | // TCL.Tcl_IncrRefCount(pX); |
||
3332 | // TCL.Tcl_ListObjAppendElement(interp, pX, TCL.Tcl_NewStringObj("UTF-16LE", -1)); |
||
3333 | // TCL.Tcl_ListObjAppendElement(interp, pX, |
||
3334 | // TCL.Tcl_NewStringObj((char)sqlite3_value_text(argv[0]), -1)); |
||
3335 | // TCL.Tcl_EvalObjEx(interp, pX, 0); |
||
3336 | // TCL.Tcl_DecrRefCount(pX); |
||
3337 | // pVal = sqlite3ValueNew(0); |
||
3338 | // sqlite3ValueSetStr(pVal, -1, TCL.Tcl_GetStringResult(interp), |
||
3339 | // SQLITE_UTF8, SQLITE_STATIC); |
||
3340 | // sqlite3_result_text(pCtx,(char)sqlite3_value_text(pVal),-1,SQLITE_TRANSIENT); |
||
3341 | // sqlite3ValueFree(pVal); |
||
3342 | //} |
||
3343 | //static void test_function_utf16be( |
||
3344 | // sqlite3_context pCtx, |
||
3345 | // int nArg, |
||
3346 | // sqlite3_value[] argv |
||
3347 | //){ |
||
3348 | // Tcl_Interp interp; |
||
3349 | // Tcl_Obj pX; |
||
3350 | // sqlite3_value pVal; |
||
3351 | // interp = (Tcl_Interp )sqlite3_context_db_handle(pCtx); |
||
3352 | // pX = TCL.Tcl_NewStringObj("test_function", -1); |
||
3353 | // TCL.Tcl_IncrRefCount(pX); |
||
3354 | // TCL.Tcl_ListObjAppendElement(interp, pX, TCL.Tcl_NewStringObj("UTF-16BE", -1)); |
||
3355 | // TCL.Tcl_ListObjAppendElement(interp, pX, |
||
3356 | // TCL.Tcl_NewStringObj((char)sqlite3_value_text(argv[0]), -1)); |
||
3357 | // TCL.Tcl_EvalObjEx(interp, pX, 0); |
||
3358 | // TCL.Tcl_DecrRefCount(pX); |
||
3359 | // pVal = sqlite3ValueNew(0); |
||
3360 | // sqlite3ValueSetStr(pVal, -1, TCL.Tcl_GetStringResult(interp), |
||
3361 | // SQLITE_UTF8, SQLITE_STATIC); |
||
3362 | // sqlite3_result_text16(pCtx, sqlite3_value_text16le(pVal), |
||
3363 | // -1, SQLITE_TRANSIENT); |
||
3364 | // sqlite3_result_text16be(pCtx, sqlite3_value_text16le(pVal), |
||
3365 | // -1, SQLITE_TRANSIENT); |
||
3366 | // sqlite3_result_text16le(pCtx, sqlite3_value_text16le(pVal), |
||
3367 | // -1, SQLITE_TRANSIENT); |
||
3368 | // sqlite3ValueFree(pVal); |
||
3369 | //} |
||
3370 | #endif // * SQLITE_OMIT_UTF16 */ |
||
3371 | //static int test_function( |
||
3372 | // object clientdata, |
||
3373 | // Tcl_Interp interp, |
||
3374 | // int objc, |
||
3375 | // Tcl_Obj[] objv |
||
3376 | //){ |
||
3377 | #if !SQLITE_OMIT_UTF16 |
||
3378 | // sqlite3 db=null; |
||
3379 | // int val; |
||
3380 | |||
3381 | // if( objc!=5 ) goto bad_args; |
||
3382 | // if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
||
3383 | |||
3384 | // if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[2], out val) ) return TCL.TCL_ERROR; |
||
3385 | // if( val ){ |
||
3386 | // sqlite3_create_function(db, "test_function", 1, SQLITE_UTF8, |
||
3387 | // interp, test_function_utf8, 0, 0); |
||
3388 | // } |
||
3389 | // if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[3], out val) ) return TCL.TCL_ERROR; |
||
3390 | // if( val ){ |
||
3391 | // sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16LE, |
||
3392 | // interp, test_function_utf16le, 0, 0); |
||
3393 | // } |
||
3394 | // if( TCL.TCL_OK!=TCL.Tcl_GetBooleanFromObj(interp, objv[4], out val) ) return TCL.TCL_ERROR; |
||
3395 | // if( val ){ |
||
3396 | // sqlite3_create_function(db, "test_function", 1, SQLITE_UTF16BE, |
||
3397 | // interp, test_function_utf16be, 0, 0); |
||
3398 | // } |
||
3399 | |||
3400 | // return TCL.TCL_OK; |
||
3401 | //bad_args: |
||
3402 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
3403 | // TCL.Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0); |
||
3404 | #endif // * SQLITE_OMIT_UTF16 */ |
||
3405 | // return TCL.TCL_ERROR; |
||
3406 | //} |
||
3407 | |||
3408 | /* |
||
3409 | ** Usage: test_errstr <err code> |
||
3410 | ** |
||
3411 | ** Test that the english language string equivalents for sqlite error codes |
||
3412 | ** are sane. The parameter is an integer representing an sqlite error code. |
||
3413 | ** The result is a list of two elements, the string representation of the |
||
3414 | ** error code and the english language explanation. |
||
3415 | */ |
||
3416 | static int test_errstr( |
||
3417 | object clientdata, |
||
3418 | Tcl_Interp interp, |
||
3419 | int objc, |
||
3420 | Tcl_Obj[] objv |
||
3421 | ) |
||
3422 | { |
||
3423 | string zCode; |
||
3424 | int i; |
||
3425 | if ( objc != 2 ) |
||
3426 | { |
||
3427 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "<error code>" ); |
||
3428 | } |
||
3429 | |||
3430 | zCode = TCL.Tcl_GetString( objv[1] ); |
||
3431 | for ( i = 0; i < 200; i++ ) |
||
3432 | { |
||
3433 | if ( t1ErrorName( i ).Equals( zCode ) ) |
||
3434 | break; |
||
3435 | } |
||
3436 | TCL.Tcl_SetResult( interp, sqlite3ErrStr( i ), 0 ); |
||
3437 | return TCL.TCL_OK; |
||
3438 | } |
||
3439 | |||
3440 | /* |
||
3441 | ** Usage: breakpoint |
||
3442 | ** |
||
3443 | ** This routine exists for one purpose - to provide a place to put a |
||
3444 | ** breakpoint with GDB that can be triggered using TCL code. The use |
||
3445 | ** for this is when a particular test fails on (say) the 1485th iteration. |
||
3446 | ** In the TCL test script, we can add code like this: |
||
3447 | ** |
||
3448 | ** if {$i==1485} breakpoint |
||
3449 | ** |
||
3450 | ** Then run testfixture in the debugger and wait for the breakpoint to |
||
3451 | ** fire. Then additional breakpoints can be set to trace down the bug. |
||
3452 | */ |
||
3453 | static int test_breakpoint( |
||
3454 | object NotUsed, |
||
3455 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
3456 | int argc, /* Number of arguments */ |
||
3457 | Tcl_Obj[] argv /* Text of each argument */ |
||
3458 | ) |
||
3459 | { |
||
3460 | return TCL.TCL_OK; /* Do nothing */ |
||
3461 | } |
||
3462 | |||
3463 | /* |
||
3464 | ** Usage: sqlite3_bind_zeroblob STMT IDX N |
||
3465 | ** |
||
3466 | ** Test the sqlite3_bind_zeroblob interface. STMT is a prepared statement. |
||
3467 | ** IDX is the index of a wildcard in the prepared statement. This command |
||
3468 | ** binds a N-byte zero-filled BLOB to the wildcard. |
||
3469 | */ |
||
3470 | static int test_bind_zeroblob( |
||
3471 | object clientdata, |
||
3472 | Tcl_Interp interp, |
||
3473 | int objc, |
||
3474 | Tcl_Obj[] objv |
||
3475 | ) |
||
3476 | { |
||
3477 | sqlite3_stmt pStmt = null; |
||
3478 | int idx = 0; |
||
3479 | int n = 0; |
||
3480 | int rc; |
||
3481 | |||
3482 | if ( objc != 4 ) |
||
3483 | { |
||
3484 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT IDX N" ); |
||
3485 | return TCL.TCL_ERROR; |
||
3486 | } |
||
3487 | |||
3488 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3489 | return TCL.TCL_ERROR; |
||
3490 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
||
3491 | return TCL.TCL_ERROR; |
||
3492 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out n ) ) |
||
3493 | return TCL.TCL_ERROR; |
||
3494 | |||
3495 | rc = sqlite3_bind_zeroblob( pStmt, idx, n ); |
||
3496 | if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
3497 | return TCL.TCL_ERROR; |
||
3498 | if ( rc != SQLITE_OK ) |
||
3499 | { |
||
3500 | return TCL.TCL_ERROR; |
||
3501 | } |
||
3502 | |||
3503 | return TCL.TCL_OK; |
||
3504 | } |
||
3505 | |||
3506 | /* |
||
3507 | ** Usage: sqlite3_bind_int STMT N VALUE |
||
3508 | ** |
||
3509 | ** Test the sqlite3_bind_int interface. STMT is a prepared statement. |
||
3510 | ** N is the index of a wildcard in the prepared statement. This command |
||
3511 | ** binds a 32-bit integer VALUE to that wildcard. |
||
3512 | */ |
||
3513 | static int test_bind_int( |
||
3514 | object clientdata, |
||
3515 | Tcl_Interp interp, |
||
3516 | int objc, |
||
3517 | Tcl_Obj[] objv |
||
3518 | ) |
||
3519 | { |
||
3520 | sqlite3_stmt pStmt = null; |
||
3521 | int idx = 0; |
||
3522 | int value = 0; |
||
3523 | int rc; |
||
3524 | |||
3525 | if ( objc != 4 ) |
||
3526 | { |
||
3527 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
3528 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N VALUE" ); |
||
3529 | return TCL.TCL_ERROR; |
||
3530 | } |
||
3531 | |||
3532 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3533 | return TCL.TCL_ERROR; |
||
3534 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
||
3535 | return TCL.TCL_ERROR; |
||
3536 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out value ) ) |
||
3537 | return TCL.TCL_ERROR; |
||
3538 | |||
3539 | rc = sqlite3_bind_int( pStmt, idx, value ); |
||
3540 | if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
3541 | return TCL.TCL_ERROR; |
||
3542 | if ( rc != SQLITE_OK ) |
||
3543 | { |
||
3544 | return TCL.TCL_ERROR; |
||
3545 | } |
||
3546 | |||
3547 | return TCL.TCL_OK; |
||
3548 | } |
||
3549 | |||
3550 | |||
3551 | /* |
||
3552 | ** Usage: sqlite3_bind_int64 STMT N VALUE |
||
3553 | ** |
||
3554 | ** Test the sqlite3_bind_int64 interface. STMT is a prepared statement. |
||
3555 | ** N is the index of a wildcard in the prepared statement. This command |
||
3556 | ** binds a 64-bit integer VALUE to that wildcard. |
||
3557 | */ |
||
3558 | static int test_bind_int64( |
||
3559 | object clientdata, |
||
3560 | Tcl_Interp interp, |
||
3561 | int objc, |
||
3562 | Tcl_Obj[] objv |
||
3563 | ) |
||
3564 | { |
||
3565 | sqlite3_stmt pStmt = null; |
||
3566 | int idx = 0; |
||
3567 | i64 value = 0; |
||
3568 | int rc; |
||
3569 | |||
3570 | if ( objc != 4 ) |
||
3571 | { |
||
3572 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
3573 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N VALUE" ); |
||
3574 | return TCL.TCL_ERROR; |
||
3575 | } |
||
3576 | |||
3577 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3578 | return TCL.TCL_ERROR; |
||
3579 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
||
3580 | return TCL.TCL_ERROR; |
||
3581 | if ( TCL.Tcl_GetWideIntFromObj( interp, objv[3], out value ) ) |
||
3582 | return TCL.TCL_ERROR; |
||
3583 | |||
3584 | rc = sqlite3_bind_int64( pStmt, idx, value ); |
||
3585 | if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
3586 | return TCL.TCL_ERROR; |
||
3587 | if ( rc != SQLITE_OK ) |
||
3588 | { |
||
3589 | return TCL.TCL_ERROR; |
||
3590 | } |
||
3591 | |||
3592 | return TCL.TCL_OK; |
||
3593 | } |
||
3594 | |||
3595 | |||
3596 | /* |
||
3597 | ** Usage: sqlite3_bind_double STMT N VALUE |
||
3598 | ** |
||
3599 | ** Test the sqlite3_bind_double interface. STMT is a prepared statement. |
||
3600 | ** N is the index of a wildcard in the prepared statement. This command |
||
3601 | ** binds a 64-bit integer VALUE to that wildcard. |
||
3602 | */ |
||
3603 | class _aSpecialFp |
||
3604 | { |
||
3605 | public string zName; /* Name of the special floating point value */ |
||
3606 | public u32 iUpper; /* Upper 32 bits */ |
||
3607 | public u32 iLower; /* Lower 32 bits */ |
||
3608 | public _aSpecialFp( string zName, u32 iUpper, u32 iLower ) |
||
3609 | { |
||
3610 | this.zName = zName; |
||
3611 | this.iUpper = iUpper; |
||
3612 | this.iLower = iLower; |
||
3613 | } |
||
3614 | } |
||
3615 | |||
3616 | static int test_bind_double( |
||
3617 | object clientdata, |
||
3618 | Tcl_Interp interp, |
||
3619 | int objc, |
||
3620 | Tcl_Obj[] objv |
||
3621 | ) |
||
3622 | { |
||
3623 | sqlite3_stmt pStmt = null; |
||
3624 | ; |
||
3625 | int idx = 0; |
||
3626 | double value = 0; |
||
3627 | int rc; |
||
3628 | string zVal; |
||
3629 | int i; |
||
3630 | _aSpecialFp[] aSpecialFp = new _aSpecialFp[] { |
||
3631 | new _aSpecialFp( "NaN", 0x7fffffff, 0xffffffff ), |
||
3632 | new _aSpecialFp( "SNaN", 0x7ff7ffff, 0xffffffff ), |
||
3633 | new _aSpecialFp( "-NaN", 0xffffffff, 0xffffffff ), |
||
3634 | new _aSpecialFp( "-SNaN", 0xfff7ffff, 0xffffffff ), |
||
3635 | new _aSpecialFp( "+Inf", 0x7ff00000, 0x00000000 ), |
||
3636 | new _aSpecialFp( "-Inf", 0xfff00000, 0x00000000 ), |
||
3637 | new _aSpecialFp( "Epsilon", 0x00000000, 0x00000001 ), |
||
3638 | new _aSpecialFp( "-Epsilon", 0x80000000, 0x00000001 ), |
||
3639 | new _aSpecialFp( "NaN0", 0x7ff80000, 0x00000000 ), |
||
3640 | new _aSpecialFp( "-NaN0", 0xfff80000, 0x00000000 ), |
||
3641 | }; |
||
3642 | |||
3643 | if ( objc != 4 ) |
||
3644 | { |
||
3645 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
3646 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N VALUE" ); |
||
3647 | return TCL.TCL_ERROR; |
||
3648 | } |
||
3649 | |||
3650 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3651 | return TCL.TCL_ERROR; |
||
3652 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
||
3653 | return TCL.TCL_ERROR; |
||
3654 | |||
3655 | /* Intercept the string "NaN" and generate a NaN value for it. |
||
3656 | ** All other strings are passed through to TCL.Tcl_GetDoubleFromObj(). |
||
3657 | ** TCL.Tcl_GetDoubleFromObj() should understand "NaN" but some versions |
||
3658 | ** contain a bug. |
||
3659 | */ |
||
3660 | zVal = TCL.Tcl_GetString( objv[3] ); |
||
3661 | for ( i = 0; i < aSpecialFp.Length; i++ ) |
||
3662 | {//sizeof(aSpecialFp)/sizeof(aSpecialFp[0]); i++){ |
||
3663 | if ( aSpecialFp[i].zName == zVal ) |
||
3664 | { |
||
3665 | i64 x; |
||
3666 | x = aSpecialFp[i].iUpper; |
||
3667 | x <<= 32; |
||
3668 | x |= aSpecialFp[i].iLower; |
||
3669 | Debug.Assert( sizeof( double ) == 8 ); |
||
3670 | Debug.Assert( sizeof( sqlite3_u3264 ) == 8 ); |
||
3671 | #if WINDOWS_PHONE |
||
3672 | value = BitConverter.ToDouble(BitConverter.GetBytes((long)x), 0); |
||
3673 | #else |
||
3674 | value = BitConverter.Int64BitsToDouble( x );//memcpy(&value, x, 8); |
||
3675 | #endif |
||
3676 | //value = Double.NaN; |
||
3677 | break; |
||
3678 | } |
||
3679 | } |
||
3680 | if ( ( i >= aSpecialFp.Length ) && //sizeof(aSpecialFp)/sizeof(aSpecialFp[0]) && |
||
3681 | TCL.Tcl_GetDoubleFromObj( interp, objv[3], out value ) ) |
||
3682 | { |
||
3683 | return TCL.TCL_ERROR; |
||
3684 | } |
||
3685 | rc = sqlite3_bind_double( pStmt, idx, value ); |
||
3686 | if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
3687 | return TCL.TCL_ERROR; |
||
3688 | if ( rc != SQLITE_OK ) |
||
3689 | { |
||
3690 | return TCL.TCL_ERROR; |
||
3691 | } |
||
3692 | |||
3693 | return TCL.TCL_OK; |
||
3694 | } |
||
3695 | |||
3696 | /* |
||
3697 | ** Usage: sqlite3_bind_null STMT N |
||
3698 | ** |
||
3699 | ** Test the sqlite3_bind_null interface. STMT is a prepared statement. |
||
3700 | ** N is the index of a wildcard in the prepared statement. This command |
||
3701 | ** binds a NULL to the wildcard. |
||
3702 | */ |
||
3703 | static int test_bind_null( |
||
3704 | object clientdata, |
||
3705 | Tcl_Interp interp, |
||
3706 | int objc, |
||
3707 | Tcl_Obj[] objv |
||
3708 | ) |
||
3709 | { |
||
3710 | sqlite3_stmt pStmt = null; |
||
3711 | ; |
||
3712 | int idx = 0; |
||
3713 | int rc; |
||
3714 | |||
3715 | if ( objc != 3 ) |
||
3716 | { |
||
3717 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
3718 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N" ); |
||
3719 | return TCL.TCL_ERROR; |
||
3720 | } |
||
3721 | |||
3722 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3723 | return TCL.TCL_ERROR; |
||
3724 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
||
3725 | return TCL.TCL_ERROR; |
||
3726 | |||
3727 | rc = sqlite3_bind_null( pStmt, idx ); |
||
3728 | if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
3729 | return TCL.TCL_ERROR; |
||
3730 | if ( rc != SQLITE_OK ) |
||
3731 | { |
||
3732 | return TCL.TCL_ERROR; |
||
3733 | } |
||
3734 | |||
3735 | return TCL.TCL_OK; |
||
3736 | } |
||
3737 | |||
3738 | /* |
||
3739 | ** Usage: sqlite3_bind_text STMT N STRING BYTES |
||
3740 | ** |
||
3741 | ** Test the sqlite3_bind_text interface. STMT is a prepared statement. |
||
3742 | ** N is the index of a wildcard in the prepared statement. This command |
||
3743 | ** binds a UTF-8 string STRING to the wildcard. The string is BYTES bytes |
||
3744 | ** long. |
||
3745 | */ |
||
3746 | static int test_bind_text( |
||
3747 | object clientdata, |
||
3748 | Tcl_Interp interp, |
||
3749 | int objc, |
||
3750 | Tcl_Obj[] objv |
||
3751 | ) |
||
3752 | { |
||
3753 | sqlite3_stmt pStmt = null; |
||
3754 | int idx = 0; |
||
3755 | int bytes = 0; |
||
3756 | byte[] value; |
||
3757 | int rc; |
||
3758 | |||
3759 | if ( objc != 5 ) |
||
3760 | { |
||
3761 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
3762 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N VALUE BYTES" ); |
||
3763 | return TCL.TCL_ERROR; |
||
3764 | } |
||
3765 | |||
3766 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3767 | return TCL.TCL_ERROR; |
||
3768 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out idx ) ) |
||
3769 | return TCL.TCL_ERROR; |
||
3770 | value = TCL.Tcl_GetByteArrayFromObj( objv[3], out bytes ); |
||
3771 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[4], out bytes ) ) |
||
3772 | return TCL.TCL_ERROR; |
||
3773 | |||
3774 | rc = sqlite3_bind_text( pStmt, idx, Encoding.UTF8.GetString( value, 0, value.Length ), bytes, SQLITE_TRANSIENT ); |
||
3775 | if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
3776 | return TCL.TCL_ERROR; |
||
3777 | if ( rc != SQLITE_OK ) |
||
3778 | { |
||
3779 | TCL.Tcl_AppendResult( interp, sqlite3TestErrorName( rc ) ); |
||
3780 | return TCL.TCL_ERROR; |
||
3781 | } |
||
3782 | |||
3783 | return TCL.TCL_OK; |
||
3784 | } |
||
3785 | |||
3786 | /* |
||
3787 | ** Usage: sqlite3_bind_text16 ?-static? STMT N STRING BYTES |
||
3788 | ** |
||
3789 | ** Test the sqlite3_bind_text16 interface. STMT is a prepared statement. |
||
3790 | ** N is the index of a wildcard in the prepared statement. This command |
||
3791 | ** binds a UTF-16 string STRING to the wildcard. The string is BYTES bytes |
||
3792 | ** long. |
||
3793 | */ |
||
3794 | static int test_bind_text16( |
||
3795 | object clientdata, |
||
3796 | Tcl_Interp interp, |
||
3797 | int objc, |
||
3798 | Tcl_Obj[] objv |
||
3799 | ) |
||
3800 | { |
||
3801 | #if !SQLITE_OMIT_UTF16 |
||
3802 | sqlite3_stmt pStmt=null; |
||
3803 | int idx=0; |
||
3804 | int bytes=0; |
||
3805 | string value; |
||
3806 | int rc; |
||
3807 | |||
3808 | dxDel xDel = (objc==6?SQLITE_STATIC:SQLITE_TRANSIENT); |
||
3809 | Tcl_Obj oStmt = objv[objc-4]; |
||
3810 | Tcl_Obj oN = objv[objc-3]; |
||
3811 | Tcl_Obj oString = objv[objc-2]; |
||
3812 | Tcl_Obj oBytes = objv[objc-1]; |
||
3813 | |||
3814 | if( objc!=5 && objc!=6){ |
||
3815 | TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
3816 | TCL.Tcl_GetStringFromObj(objv[0], 0), " STMT N VALUE BYTES", 0); |
||
3817 | return TCL.TCL_ERROR; |
||
3818 | } |
||
3819 | |||
3820 | if( getStmtPointer(interp, TCL.Tcl_GetString(oStmt), out pStmt)!=0 ) return TCL.TCL_ERROR; |
||
3821 | if( TCL.Tcl_GetIntFromObj(interp, oN, out idx) ) return TCL.TCL_ERROR; |
||
3822 | int dummy0 = 0; |
||
3823 | value = Encoding.UTF8.GetString(TCL.Tcl_GetByteArrayFromObj( oString, out dummy0 )); |
||
3824 | if( TCL.Tcl_GetIntFromObj(interp, oBytes, out bytes) ) return TCL.TCL_ERROR; |
||
3825 | |||
3826 | rc = sqlite3_bind_text16(pStmt, idx, value, bytes, xDel); |
||
3827 | if( sqlite3TestErrCode(interp, StmtToDb(pStmt), rc) !=0) return TCL.TCL_ERROR; |
||
3828 | if( rc!=SQLITE_OK ){ |
||
3829 | TCL.Tcl_AppendResult(interp, sqlite3TestErrorName(rc)); |
||
3830 | return TCL.TCL_ERROR; |
||
3831 | } |
||
3832 | |||
3833 | #endif // * SQLITE_OMIT_UTF16 */ |
||
3834 | return TCL.TCL_OK; |
||
3835 | } |
||
3836 | |||
3837 | /* |
||
3838 | ** Usage: sqlite3_bind_blob ?-static? STMT N DATA BYTES |
||
3839 | ** |
||
3840 | ** Test the sqlite3_bind_blob interface. STMT is a prepared statement. |
||
3841 | ** N is the index of a wildcard in the prepared statement. This command |
||
3842 | ** binds a BLOB to the wildcard. The BLOB is BYTES bytes in size. |
||
3843 | */ |
||
3844 | static int test_bind_blob( |
||
3845 | object clientdata, |
||
3846 | Tcl_Interp interp, |
||
3847 | int objc, |
||
3848 | Tcl_Obj[] objv |
||
3849 | ) |
||
3850 | { |
||
3851 | sqlite3_stmt pStmt = null; |
||
3852 | int idx = 0; |
||
3853 | int bytes = 0; |
||
3854 | byte[] value; |
||
3855 | int rc; |
||
3856 | dxDel xDestructor = SQLITE_TRANSIENT; |
||
3857 | |||
3858 | int iObjv = 0; |
||
3859 | if ( objc != 5 && objc != 6 ) |
||
3860 | { |
||
3861 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
3862 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " STMT N DATA BYTES" ); |
||
3863 | return TCL.TCL_ERROR; |
||
3864 | } |
||
3865 | |||
3866 | if ( objc == 6 ) |
||
3867 | { |
||
3868 | xDestructor = SQLITE_STATIC; |
||
3869 | iObjv++; |
||
3870 | } |
||
3871 | |||
3872 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[iObjv + 1] ), out pStmt ) != 0 ) |
||
3873 | return TCL.TCL_ERROR; |
||
3874 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[iObjv + 2], out idx ) ) |
||
3875 | return TCL.TCL_ERROR; |
||
3876 | value = Encoding.UTF8.GetBytes( TCL.Tcl_GetString( objv[iObjv + 3] ) ); |
||
3877 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[iObjv + 4], out bytes ) ) |
||
3878 | return TCL.TCL_ERROR; |
||
3879 | |||
3880 | rc = sqlite3_bind_blob( pStmt, idx, value, bytes, xDestructor ); |
||
3881 | if ( sqlite3TestErrCode( interp, StmtToDb( pStmt ), rc ) != 0 ) |
||
3882 | return TCL.TCL_ERROR; |
||
3883 | if ( rc != SQLITE_OK ) |
||
3884 | { |
||
3885 | return TCL.TCL_ERROR; |
||
3886 | } |
||
3887 | |||
3888 | return TCL.TCL_OK; |
||
3889 | } |
||
3890 | |||
3891 | /* |
||
3892 | ** Usage: sqlite3_bind_parameter_count STMT |
||
3893 | ** |
||
3894 | ** Return the number of wildcards in the given statement. |
||
3895 | */ |
||
3896 | static int test_bind_parameter_count( |
||
3897 | object clientdata, |
||
3898 | Tcl_Interp interp, |
||
3899 | int objc, |
||
3900 | Tcl_Obj[] objv |
||
3901 | ) |
||
3902 | { |
||
3903 | sqlite3_stmt pStmt = null; |
||
3904 | |||
3905 | if ( objc != 2 ) |
||
3906 | { |
||
3907 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT" ); |
||
3908 | return TCL.TCL_ERROR; |
||
3909 | } |
||
3910 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3911 | return TCL.TCL_ERROR; |
||
3912 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_bind_parameter_count( pStmt ) ) ); |
||
3913 | return TCL.TCL_OK; |
||
3914 | } |
||
3915 | |||
3916 | /* |
||
3917 | ** Usage: sqlite3_bind_parameter_name STMT N |
||
3918 | ** |
||
3919 | ** Return the name of the Nth wildcard. The first wildcard is 1. |
||
3920 | ** An empty string is returned if N is out of range or if the wildcard |
||
3921 | ** is nameless. |
||
3922 | */ |
||
3923 | static int test_bind_parameter_name( |
||
3924 | object clientdata, |
||
3925 | Tcl_Interp interp, |
||
3926 | int objc, |
||
3927 | Tcl_Obj[] objv |
||
3928 | ) |
||
3929 | { |
||
3930 | sqlite3_stmt pStmt = null; |
||
3931 | int i = 0; |
||
3932 | |||
3933 | if ( objc != 3 ) |
||
3934 | { |
||
3935 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT N" ); |
||
3936 | return TCL.TCL_ERROR; |
||
3937 | } |
||
3938 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3939 | return TCL.TCL_ERROR; |
||
3940 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out i ) ) |
||
3941 | return TCL.TCL_ERROR; |
||
3942 | TCL.Tcl_SetObjResult( interp, |
||
3943 | TCL.Tcl_NewStringObj( sqlite3_bind_parameter_name( pStmt, i ), -1 ) |
||
3944 | ); |
||
3945 | return TCL.TCL_OK; |
||
3946 | } |
||
3947 | |||
3948 | /* |
||
3949 | ** Usage: sqlite3_bind_parameter_index STMT NAME |
||
3950 | ** |
||
3951 | ** Return the index of the wildcard called NAME. Return 0 if there is |
||
3952 | ** no such wildcard. |
||
3953 | */ |
||
3954 | static int test_bind_parameter_index( |
||
3955 | object clientdata, |
||
3956 | Tcl_Interp interp, |
||
3957 | int objc, |
||
3958 | Tcl_Obj[] objv |
||
3959 | ) |
||
3960 | { |
||
3961 | sqlite3_stmt pStmt = null; |
||
3962 | |||
3963 | if ( objc != 3 ) |
||
3964 | { |
||
3965 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT NAME" ); |
||
3966 | return TCL.TCL_ERROR; |
||
3967 | } |
||
3968 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3969 | return TCL.TCL_ERROR; |
||
3970 | TCL.Tcl_SetObjResult( interp, |
||
3971 | TCL.Tcl_NewIntObj( |
||
3972 | sqlite3_bind_parameter_index( pStmt, TCL.Tcl_GetString( objv[2] ) ) |
||
3973 | ) |
||
3974 | ); |
||
3975 | return TCL.TCL_OK; |
||
3976 | } |
||
3977 | |||
3978 | /* |
||
3979 | ** Usage: sqlite3_clear_bindings STMT |
||
3980 | ** |
||
3981 | */ |
||
3982 | static int test_clear_bindings( |
||
3983 | object clientdata, |
||
3984 | Tcl_Interp interp, |
||
3985 | int objc, |
||
3986 | Tcl_Obj[] objv |
||
3987 | ) |
||
3988 | { |
||
3989 | sqlite3_stmt pStmt = null; |
||
3990 | |||
3991 | if ( objc != 2 ) |
||
3992 | { |
||
3993 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT" ); |
||
3994 | return TCL.TCL_ERROR; |
||
3995 | } |
||
3996 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
3997 | return TCL.TCL_ERROR; |
||
3998 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_clear_bindings( pStmt ) ) ); |
||
3999 | return TCL.TCL_OK; |
||
4000 | } |
||
4001 | |||
4002 | /* |
||
4003 | ** Usage: sqlite3_sleep MILLISECONDS |
||
4004 | */ |
||
4005 | static int test_sleep( |
||
4006 | object clientdata, |
||
4007 | Tcl_Interp interp, |
||
4008 | int objc, |
||
4009 | Tcl_Obj[] objv |
||
4010 | ) |
||
4011 | { |
||
4012 | int ms = 0; |
||
4013 | |||
4014 | if ( objc != 2 ) |
||
4015 | { |
||
4016 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "MILLISECONDS" ); |
||
4017 | return TCL.TCL_ERROR; |
||
4018 | } |
||
4019 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[1], out ms ) ) |
||
4020 | { |
||
4021 | return TCL.TCL_ERROR; |
||
4022 | } |
||
4023 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_sleep( ms ) ) ); |
||
4024 | return TCL.TCL_OK; |
||
4025 | } |
||
4026 | |||
4027 | /* |
||
4028 | ** Usage: sqlite3_extended_errcode DB |
||
4029 | ** |
||
4030 | ** Return the string representation of the most recent sqlite3_* API |
||
4031 | ** error code. e.g. "SQLITE_ERROR". |
||
4032 | */ |
||
4033 | static int test_ex_errcode( |
||
4034 | object clientdata, |
||
4035 | Tcl_Interp interp, |
||
4036 | int objc, |
||
4037 | Tcl_Obj[] objv |
||
4038 | ) |
||
4039 | { |
||
4040 | sqlite3 db = null; |
||
4041 | int rc; |
||
4042 | |||
4043 | if ( objc != 2 ) |
||
4044 | { |
||
4045 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4046 | TCL.Tcl_GetString( objv[0] ), " DB" ); |
||
4047 | return TCL.TCL_ERROR; |
||
4048 | } |
||
4049 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
4050 | return TCL.TCL_ERROR; |
||
4051 | rc = sqlite3_extended_errcode( db ); |
||
4052 | TCL.Tcl_AppendResult( interp, t1ErrorName( rc ) ); |
||
4053 | return TCL.TCL_OK; |
||
4054 | } |
||
4055 | |||
4056 | |||
4057 | /* |
||
4058 | ** Usage: sqlite3_errcode DB |
||
4059 | ** |
||
4060 | ** Return the string representation of the most recent sqlite3_* API |
||
4061 | ** error code. e.g. "SQLITE_ERROR". |
||
4062 | */ |
||
4063 | static int test_errcode( |
||
4064 | object clientdata, |
||
4065 | Tcl_Interp interp, |
||
4066 | int objc, |
||
4067 | Tcl_Obj[] objv |
||
4068 | ) |
||
4069 | { |
||
4070 | sqlite3 db = null; |
||
4071 | int rc; |
||
4072 | StringBuilder zBuf = new StringBuilder( 50 ); |
||
4073 | |||
4074 | if ( objc != 2 ) |
||
4075 | { |
||
4076 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4077 | TCL.Tcl_GetString( objv[0] ), " DB" ); |
||
4078 | return TCL.TCL_ERROR; |
||
4079 | } |
||
4080 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
4081 | return TCL.TCL_ERROR; |
||
4082 | rc = sqlite3_errcode( db ); |
||
4083 | if ( ( rc & 0xff ) == rc ) |
||
4084 | { |
||
4085 | zBuf.Length = 0; |
||
4086 | } |
||
4087 | else |
||
4088 | { |
||
4089 | sqlite3_snprintf( 30, zBuf, "+%d", rc >> 8 ); |
||
4090 | } |
||
4091 | TCL.Tcl_AppendResult( interp, t1ErrorName( rc ), zBuf ); |
||
4092 | return TCL.TCL_OK; |
||
4093 | } |
||
4094 | |||
4095 | /* |
||
4096 | ** Usage: sqlite3_errmsg DB |
||
4097 | ** |
||
4098 | ** Returns the UTF-8 representation of the error message string for the |
||
4099 | ** most recent sqlite3_* API call. |
||
4100 | */ |
||
4101 | static int test_errmsg( |
||
4102 | object clientdata, |
||
4103 | Tcl_Interp interp, |
||
4104 | int objc, |
||
4105 | Tcl_Obj[] objv |
||
4106 | ) |
||
4107 | { |
||
4108 | sqlite3 db = null; |
||
4109 | string zErr; |
||
4110 | |||
4111 | if ( objc != 2 ) |
||
4112 | { |
||
4113 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4114 | TCL.Tcl_GetString( objv[0] ), " DB" ); |
||
4115 | return TCL.TCL_ERROR; |
||
4116 | } |
||
4117 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
4118 | return TCL.TCL_ERROR; |
||
4119 | |||
4120 | zErr = sqlite3_errmsg( db ); |
||
4121 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewStringObj( zErr, -1 ) ); |
||
4122 | return TCL.TCL_OK; |
||
4123 | } |
||
4124 | |||
4125 | /* |
||
4126 | ** Usage: test_errmsg16 DB |
||
4127 | ** |
||
4128 | ** Returns the UTF-16 representation of the error message string for the |
||
4129 | ** most recent sqlite3_* API call. This is a byte array object at the TCL |
||
4130 | ** level, and it includes the 0x00 0x00 terminator bytes at the end of the |
||
4131 | ** UTF-16 string. |
||
4132 | */ |
||
4133 | //static int test_errmsg16( |
||
4134 | // object clientdata, |
||
4135 | // Tcl_Interp interp, |
||
4136 | // int objc, |
||
4137 | // Tcl_Obj[] objv |
||
4138 | //){ |
||
4139 | #if !SQLITE_OMIT_UTF16 |
||
4140 | sqlite3 db; |
||
4141 | string zErr; |
||
4142 | string z; |
||
4143 | int bytes = 0; |
||
4144 | |||
4145 | if( objc!=2 ){ |
||
4146 | TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
4147 | TCL.Tcl_GetString(objv[0]), " DB", 0); |
||
4148 | return TCL.TCL_ERROR; |
||
4149 | } |
||
4150 | if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), &db) ) return TCL.TCL_ERROR; |
||
4151 | |||
4152 | zErr = sqlite3_errmsg16(db); |
||
4153 | if( zErr ){ |
||
4154 | z = zErr; |
||
4155 | for(bytes=0; z[bytes] || z[bytes+1]; bytes+=2){} |
||
4156 | } |
||
4157 | TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewByteArrayObj(zErr, bytes)); |
||
4158 | #endif // * SQLITE_OMIT_UTF16 */ |
||
4159 | // return TCL.TCL_OK; |
||
4160 | //} |
||
4161 | |||
4162 | /* |
||
4163 | ** Usage: sqlite3_prepare DB sql bytes ?tailvar? |
||
4164 | ** |
||
4165 | ** Compile up to <bytes> bytes of the supplied SQL string <sql> using |
||
4166 | ** database handle <DB>. The parameter <tailval> is the name of a global |
||
4167 | ** variable that is set to the unused portion of <sql> (if any). A |
||
4168 | ** STMT handle is returned. |
||
4169 | */ |
||
4170 | static int test_prepare( |
||
4171 | object clientdata, |
||
4172 | Tcl_Interp interp, |
||
4173 | int objc, |
||
4174 | Tcl_Obj[] objv |
||
4175 | ) |
||
4176 | { |
||
4177 | sqlite3 db = null; |
||
4178 | string zSql; |
||
4179 | int bytes = 0; |
||
4180 | string zTail = ""; |
||
4181 | sqlite3_stmt pStmt = null; |
||
4182 | StringBuilder zBuf = new StringBuilder( 50 ); |
||
4183 | int rc; |
||
4184 | |||
4185 | if ( objc != 5 && objc != 4 ) |
||
4186 | { |
||
4187 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4188 | TCL.Tcl_GetString( objv[0] ), " DB sql bytes ?tailvar?" ); |
||
4189 | return TCL.TCL_ERROR; |
||
4190 | } |
||
4191 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
4192 | return TCL.TCL_ERROR; |
||
4193 | zSql = TCL.Tcl_GetString( objv[2] ); |
||
4194 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out bytes ) ) |
||
4195 | return TCL.TCL_ERROR; |
||
4196 | |||
4197 | if ( bytes > zSql.Length ) |
||
4198 | bytes = zSql.Length; |
||
4199 | rc = sqlite3_prepare( db, zSql, bytes, ref pStmt, ref zTail ); |
||
4200 | TCL.Tcl_ResetResult( interp ); |
||
4201 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
4202 | return TCL.TCL_ERROR; |
||
4203 | if ( zTail != null && objc >= 5 ) |
||
4204 | { |
||
4205 | if ( bytes >= 0 ) |
||
4206 | { |
||
4207 | bytes = bytes - zSql.Length - zTail.Length;// ( zTail - zSql ); |
||
4208 | } |
||
4209 | if ( zTail.Length < bytes ) |
||
4210 | { |
||
4211 | bytes = zTail.Length; |
||
4212 | } |
||
4213 | TCL.Tcl_ObjSetVar2( interp, objv[4], null, TCL.Tcl_NewStringObj( zTail, bytes ), 0 ); |
||
4214 | } |
||
4215 | if ( rc != SQLITE_OK ) |
||
4216 | { |
||
4217 | Debug.Assert( pStmt == null ); |
||
4218 | sqlite3_snprintf( 200, zBuf, "(%d) ", rc ); |
||
4219 | TCL.Tcl_SetResult( interp, zBuf + sqlite3_errmsg( db ), 0 ); |
||
4220 | return TCL.TCL_ERROR; |
||
4221 | } |
||
4222 | |||
4223 | if ( pStmt != null ) |
||
4224 | { |
||
4225 | if ( sqlite3TestMakePointerStr( interp, zBuf, pStmt ) != 0 ) |
||
4226 | return TCL.TCL_ERROR; |
||
4227 | TCL.Tcl_AppendResult( interp, zBuf, null ); |
||
4228 | } |
||
4229 | return TCL.TCL_OK; |
||
4230 | } |
||
4231 | |||
4232 | /* |
||
4233 | ** Usage: sqlite3_prepare_v2 DB sql bytes ?tailvar? |
||
4234 | ** |
||
4235 | ** Compile up to <bytes> bytes of the supplied SQL string <sql> using |
||
4236 | ** database handle <DB>. The parameter <tailval> is the name of a global |
||
4237 | ** variable that is set to the unused portion of <sql> (if any). A |
||
4238 | ** STMT handle is returned. |
||
4239 | */ |
||
4240 | static int test_prepare_v2( |
||
4241 | object clientdata, |
||
4242 | Tcl_Interp interp, |
||
4243 | int objc, |
||
4244 | Tcl_Obj[] objv |
||
4245 | ) |
||
4246 | { |
||
4247 | sqlite3 db = null; |
||
4248 | string zSql; |
||
4249 | int bytes = 0; |
||
4250 | string zTail = ""; |
||
4251 | sqlite3_stmt pStmt = null; |
||
4252 | StringBuilder zBuf = new StringBuilder( 50 ); |
||
4253 | int rc; |
||
4254 | |||
4255 | if ( objc != 5 && objc != 4 ) |
||
4256 | { |
||
4257 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4258 | TCL.Tcl_GetString( objv[0] ), " DB sql bytes ?tailvar?", null ); |
||
4259 | return TCL.TCL_ERROR; |
||
4260 | } |
||
4261 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
4262 | return TCL.TCL_ERROR; |
||
4263 | zSql = TCL.Tcl_GetString( objv[2] ); |
||
4264 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out bytes ) ) |
||
4265 | return TCL.TCL_ERROR; |
||
4266 | |||
4267 | rc = sqlite3_prepare_v2( db, zSql, bytes, ref pStmt, ref zTail ); |
||
4268 | Debug.Assert( rc == SQLITE_OK || pStmt == null ); |
||
4269 | TCL.Tcl_ResetResult( interp ); |
||
4270 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
4271 | return TCL.TCL_ERROR; |
||
4272 | if ( zTail != null && objc >= 5 ) |
||
4273 | { |
||
4274 | if ( bytes >= 0 ) |
||
4275 | { |
||
4276 | bytes = bytes - zSql.Length - zTail.Length;// ( zTail - zSql ); |
||
4277 | } |
||
4278 | TCL.Tcl_ObjSetVar2( interp, objv[4], null, TCL.Tcl_NewStringObj( zTail, bytes ), 0 ); |
||
4279 | } |
||
4280 | if ( rc != SQLITE_OK ) |
||
4281 | { |
||
4282 | Debug.Assert( pStmt == null ); |
||
4283 | sqlite3_snprintf( 50, zBuf, "(%d) ", rc ); |
||
4284 | TCL.Tcl_AppendResult( interp, zBuf, sqlite3_errmsg( db ) ); |
||
4285 | return TCL.TCL_ERROR; |
||
4286 | } |
||
4287 | |||
4288 | if ( pStmt != null ) |
||
4289 | { |
||
4290 | if ( sqlite3TestMakePointerStr( interp, zBuf, pStmt ) != 0 ) |
||
4291 | return TCL.TCL_ERROR; |
||
4292 | TCL.Tcl_AppendResult( interp, zBuf ); |
||
4293 | } |
||
4294 | return TCL.TCL_OK; |
||
4295 | } |
||
4296 | |||
4297 | /* |
||
4298 | ** Usage: sqlite3_prepare_tkt3134 DB |
||
4299 | ** |
||
4300 | ** Generate a prepared statement for a zero-byte string as a test |
||
4301 | ** for ticket #3134. The string should be preceeded by a zero byte. |
||
4302 | */ |
||
4303 | static int test_prepare_tkt3134( |
||
4304 | object clientdata, |
||
4305 | Tcl_Interp interp, |
||
4306 | int objc, |
||
4307 | Tcl_Obj[] objv |
||
4308 | ) |
||
4309 | { |
||
4310 | sqlite3 db = null; |
||
4311 | string zSql = "\000SELECT 1"; |
||
4312 | sqlite3_stmt pStmt = null; |
||
4313 | StringBuilder zBuf = new StringBuilder( 50 ); |
||
4314 | int rc; |
||
4315 | |||
4316 | if ( objc != 2 ) |
||
4317 | { |
||
4318 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4319 | TCL.Tcl_GetString( objv[0] ), " DB sql bytes tailvar" ); |
||
4320 | return TCL.TCL_ERROR; |
||
4321 | } |
||
4322 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
4323 | return TCL.TCL_ERROR; |
||
4324 | rc = sqlite3_prepare_v2( db, zSql.Substring( 1 ), 0, ref pStmt, 0 ); |
||
4325 | Debug.Assert( rc == SQLITE_OK || pStmt == null ); |
||
4326 | if ( sqlite3TestErrCode( interp, db, rc ) != 0 ) |
||
4327 | return TCL.TCL_ERROR; |
||
4328 | if ( rc != SQLITE_OK ) |
||
4329 | { |
||
4330 | Debug.Assert( pStmt == null ); |
||
4331 | zBuf.Length = 0; |
||
4332 | zBuf.Append( rc.ToString() ); //sprintf( zBuf, "(%d) ", rc ); |
||
4333 | TCL.Tcl_AppendResult( interp, zBuf, sqlite3_errmsg( db ) ); |
||
4334 | return TCL.TCL_ERROR; |
||
4335 | } |
||
4336 | |||
4337 | if ( pStmt != null ) |
||
4338 | { |
||
4339 | if ( sqlite3TestMakePointerStr( interp, zBuf, pStmt ) != 0 ) |
||
4340 | return TCL.TCL_ERROR; |
||
4341 | TCL.Tcl_AppendResult( interp, zBuf ); |
||
4342 | } |
||
4343 | return TCL.TCL_OK; |
||
4344 | } |
||
4345 | |||
4346 | /* |
||
4347 | ** Usage: sqlite3_prepare16 DB sql bytes tailvar |
||
4348 | ** |
||
4349 | ** Compile up to <bytes> bytes of the supplied SQL string <sql> using |
||
4350 | ** database handle <DB>. The parameter <tailval> is the name of a global |
||
4351 | ** variable that is set to the unused portion of <sql> (if any). A |
||
4352 | ** STMT handle is returned. |
||
4353 | */ |
||
4354 | static int test_prepare16( |
||
4355 | object clientdata, |
||
4356 | Tcl_Interp interp, |
||
4357 | int objc, |
||
4358 | Tcl_Obj[] objv |
||
4359 | ) |
||
4360 | { |
||
4361 | #if !SQLITE_OMIT_UTF16 |
||
4362 | sqlite3 db=null; |
||
4363 | string zSql; |
||
4364 | string zTail = 0; |
||
4365 | Tcl_Obj pTail = 0; |
||
4366 | sqlite3_stmt pStmt = null; |
||
4367 | char zBuf[50]; |
||
4368 | int rc; |
||
4369 | int bytes; /* The integer specified as arg 3 */ |
||
4370 | int objlen; /* The byte-array length of arg 2 */ |
||
4371 | |||
4372 | if( objc!=5 && objc!=4 ){ |
||
4373 | TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
4374 | TCL.Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0); |
||
4375 | return TCL.TCL_ERROR; |
||
4376 | } |
||
4377 | if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
||
4378 | zSql = TCL.Tcl_GetByteArrayFromObj(objv[2], out objlen); |
||
4379 | if( TCL.Tcl_GetIntFromObj(interp, objv[3], out bytes) ) return TCL.TCL_ERROR; |
||
4380 | |||
4381 | rc = sqlite3_prepare16(db, zSql, bytes, pStmt, objc>=5 ? &zTail : 0); |
||
4382 | if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
||
4383 | if( rc !=0){ |
||
4384 | return TCL.TCL_ERROR; |
||
4385 | } |
||
4386 | |||
4387 | if( objc>=5 ){ |
||
4388 | if( zTail ){ |
||
4389 | objlen = objlen - ((u8 )zTail-(u8 )zSql); |
||
4390 | }else{ |
||
4391 | objlen = 0; |
||
4392 | } |
||
4393 | pTail = TCL.Tcl_NewByteArrayObj((u8 )zTail, objlen); |
||
4394 | TCL.Tcl_IncrRefCount(pTail); |
||
4395 | Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); |
||
4396 | TCL.Tcl_DecrRefCount(pTail); |
||
4397 | } |
||
4398 | |||
4399 | if( pStmt ){ |
||
4400 | if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL.TCL_ERROR; |
||
4401 | } |
||
4402 | TCL.Tcl_AppendResult(interp, zBuf); |
||
4403 | #endif // * SQLITE_OMIT_UTF16 */ |
||
4404 | return TCL.TCL_OK; |
||
4405 | } |
||
4406 | |||
4407 | /* |
||
4408 | ** Usage: sqlite3_prepare16_v2 DB sql bytes tailvar |
||
4409 | ** |
||
4410 | ** Compile up to <bytes> bytes of the supplied SQL string <sql> using |
||
4411 | ** database handle <DB>. The parameter <tailval> is the name of a global |
||
4412 | ** variable that is set to the unused portion of <sql> (if any). A |
||
4413 | ** STMT handle is returned. |
||
4414 | */ |
||
4415 | //static int test_prepare16_v2( |
||
4416 | // object clientdata, |
||
4417 | // Tcl_Interp interp, |
||
4418 | // int objc, |
||
4419 | // Tcl_Obj[] objv |
||
4420 | //){ |
||
4421 | #if !SQLITE_OMIT_UTF16 |
||
4422 | // sqlite3 db=null; |
||
4423 | // string zSql; |
||
4424 | // string zTail = 0; |
||
4425 | // Tcl_Obj pTail = 0; |
||
4426 | // sqlite3_stmt pStmt = null; |
||
4427 | // char zBuf[50]; |
||
4428 | // int rc; |
||
4429 | // int bytes; /* The integer specified as arg 3 */ |
||
4430 | // int objlen; /* The byte-array length of arg 2 */ |
||
4431 | |||
4432 | // if( objc!=5 && objc!=4 ){ |
||
4433 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
4434 | // TCL.Tcl_GetString(objv[0]), " DB sql bytes ?tailvar?", 0); |
||
4435 | // return TCL.TCL_ERROR; |
||
4436 | // } |
||
4437 | // if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
||
4438 | // zSql = TCL.Tcl_GetByteArrayFromObj(objv[2], out objlen); |
||
4439 | // if( TCL.Tcl_GetIntFromObj(interp, objv[3], out bytes) ) return TCL.TCL_ERROR; |
||
4440 | |||
4441 | // rc = sqlite3_prepare16_v2(db, zSql, bytes, pStmt,objc>=5 ? &zTail : 0); |
||
4442 | // if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR; |
||
4443 | // if( rc !=0){ |
||
4444 | // return TCL.TCL_ERROR; |
||
4445 | // } |
||
4446 | |||
4447 | if( objc>=5 ){ |
||
4448 | if( zTail ){ |
||
4449 | objlen = objlen - ((u8 )zTail-(u8 )zSql); |
||
4450 | }else{ |
||
4451 | objlen = 0; |
||
4452 | } |
||
4453 | pTail = TCL.Tcl_NewByteArrayObj((u8 )zTail, objlen); |
||
4454 | TCL.Tcl_IncrRefCount(pTail); |
||
4455 | Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0); |
||
4456 | TCL.Tcl_DecrRefCount(pTail); |
||
4457 | // } |
||
4458 | |||
4459 | // if( pStmt ){ |
||
4460 | // if( sqlite3TestMakePointerStr(interp, zBuf, pStmt) ) return TCL.TCL_ERROR; |
||
4461 | // } |
||
4462 | // TCL.Tcl_AppendResult(interp, zBuf); |
||
4463 | #endif // * SQLITE_OMIT_UTF16 */ |
||
4464 | // return TCL.TCL_OK; |
||
4465 | //} |
||
4466 | |||
4467 | /* |
||
4468 | ** Usage: sqlite3_open filename ?options-list? |
||
4469 | */ |
||
4470 | static int test_open( |
||
4471 | object clientdata, |
||
4472 | Tcl_Interp interp, |
||
4473 | int objc, |
||
4474 | Tcl_Obj[] objv |
||
4475 | ) |
||
4476 | { |
||
4477 | string zFilename; |
||
4478 | SqliteDb db = new SqliteDb(); |
||
4479 | int rc; |
||
4480 | StringBuilder zBuf = new StringBuilder( 100 ); |
||
4481 | if ( objc != 3 && objc != 2 && objc != 1 ) |
||
4482 | { |
||
4483 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4484 | TCL.Tcl_GetString( objv[0] ), " filename options-list" ); |
||
4485 | return TCL.TCL_ERROR; |
||
4486 | } |
||
4487 | |||
4488 | zFilename = objc > 1 ? TCL.Tcl_GetString( objv[1] ) : null; |
||
4489 | rc = sqlite3_open( zFilename, out db.db ); |
||
4490 | |||
4491 | if ( sqlite3TestMakePointerStr( interp, zBuf, db ) != TCL.TCL_OK ) |
||
4492 | return TCL.TCL_ERROR; |
||
4493 | TCL.Tcl_AppendResult( interp, zBuf ); |
||
4494 | return TCL.TCL_OK; |
||
4495 | } |
||
4496 | |||
4497 | class OpenFlag |
||
4498 | { |
||
4499 | public string zFlag; |
||
4500 | public int flag; |
||
4501 | |||
4502 | public OpenFlag( string zFlag, int flag ) |
||
4503 | { |
||
4504 | this.zFlag = zFlag; |
||
4505 | this.flag = flag; |
||
4506 | } |
||
4507 | } |
||
4508 | /* |
||
4509 | ** Usage: sqlite3_open_v2 FILENAME FLAGS VFS |
||
4510 | */ |
||
4511 | static int test_open_v2( |
||
4512 | object clientdata, |
||
4513 | Tcl_Interp interp, |
||
4514 | int objc, |
||
4515 | Tcl_Obj[] objv |
||
4516 | ) |
||
4517 | { |
||
4518 | string zFilename; |
||
4519 | string zVfs; |
||
4520 | int flags = 0; |
||
4521 | sqlite3 db = null; |
||
4522 | int rc; |
||
4523 | StringBuilder zBuf = new StringBuilder( 100 ); |
||
4524 | |||
4525 | int nFlag = 0; |
||
4526 | Tcl_Obj[] apFlag = null; |
||
4527 | int i; |
||
4528 | |||
4529 | if ( objc != 4 ) |
||
4530 | { |
||
4531 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "FILENAME FLAGS VFS" ); |
||
4532 | return TCL.TCL_ERROR; |
||
4533 | } |
||
4534 | zFilename = TCL.Tcl_GetString( objv[1] ); |
||
4535 | zVfs = TCL.Tcl_GetString( objv[3] ); |
||
4536 | if ( zVfs[0] == 0x00 ) |
||
4537 | zVfs = null; |
||
4538 | |||
4539 | rc = TCL.Tcl_ListObjGetElements( interp, objv[2], out nFlag, out apFlag ) ? TCL.TCL_OK : 1; |
||
4540 | if ( rc != TCL.TCL_OK ) |
||
4541 | return rc; |
||
4542 | for ( i = 0; i < nFlag; i++ ) |
||
4543 | { |
||
4544 | int iFlag; |
||
4545 | OpenFlag[] aFlag = new OpenFlag[] { |
||
4546 | new OpenFlag( "SQLITE_OPEN_READONLY", SQLITE_OPEN_READONLY ), |
||
4547 | new OpenFlag( "SQLITE_OPEN_READWRITE", SQLITE_OPEN_READWRITE ), |
||
4548 | new OpenFlag( "SQLITE_OPEN_CREATE", SQLITE_OPEN_CREATE ), |
||
4549 | new OpenFlag( "SQLITE_OPEN_DELETEONCLOSE", SQLITE_OPEN_DELETEONCLOSE ), |
||
4550 | new OpenFlag( "SQLITE_OPEN_EXCLUSIVE", SQLITE_OPEN_EXCLUSIVE ), |
||
4551 | new OpenFlag( "SQLITE_OPEN_AUTOPROXY", SQLITE_OPEN_AUTOPROXY ), |
||
4552 | new OpenFlag( "SQLITE_OPEN_MAIN_DB", SQLITE_OPEN_MAIN_DB ), |
||
4553 | new OpenFlag( "SQLITE_OPEN_TEMP_DB", SQLITE_OPEN_TEMP_DB ), |
||
4554 | new OpenFlag( "SQLITE_OPEN_TRANSIENT_DB", SQLITE_OPEN_TRANSIENT_DB ), |
||
4555 | new OpenFlag( "SQLITE_OPEN_MAIN_JOURNAL", SQLITE_OPEN_MAIN_JOURNAL ), |
||
4556 | new OpenFlag( "SQLITE_OPEN_TEMP_JOURNAL", SQLITE_OPEN_TEMP_JOURNAL ), |
||
4557 | new OpenFlag( "SQLITE_OPEN_SUBJOURNAL", SQLITE_OPEN_SUBJOURNAL ), |
||
4558 | new OpenFlag( "SQLITE_OPEN_MASTER_JOURNAL", SQLITE_OPEN_MASTER_JOURNAL ), |
||
4559 | new OpenFlag( "SQLITE_OPEN_NOMUTEX", SQLITE_OPEN_NOMUTEX ), |
||
4560 | new OpenFlag( "SQLITE_OPEN_FULLMUTEX", SQLITE_OPEN_FULLMUTEX ), |
||
4561 | new OpenFlag( "SQLITE_OPEN_SHAREDCACHE", SQLITE_OPEN_SHAREDCACHE ), |
||
4562 | new OpenFlag( "SQLITE_OPEN_PRIVATECACHE", SQLITE_OPEN_PRIVATECACHE ), |
||
4563 | new OpenFlag( "SQLITE_OPEN_WAL", SQLITE_OPEN_WAL ), |
||
4564 | new OpenFlag( "SQLITE_OPEN_URI", SQLITE_OPEN_URI ), |
||
4565 | new OpenFlag( null, 0 ) |
||
4566 | }; |
||
4567 | //rc = TCL.Tcl_GetIndexFromObjStruct( interp, apFlag[i], aFlag, sizeof( aFlag[0] ), |
||
4568 | // "flag", 0, ref iFlag ); |
||
4569 | |||
4570 | for ( iFlag = 0; iFlag < aFlag.Length && ( aFlag[iFlag].zFlag != objv[4].ToString() ); iFlag++ ) |
||
4571 | { |
||
4572 | } |
||
4573 | if ( iFlag >= aFlag.Length ) |
||
4574 | return TCL.TCL_ERROR; |
||
4575 | flags |= aFlag[iFlag].flag; |
||
4576 | } |
||
4577 | |||
4578 | rc = sqlite3_open_v2( zFilename, out db, flags, zVfs ); |
||
4579 | if ( sqlite3TestMakePointerStr( interp, zBuf, db ) != 0 ) |
||
4580 | return TCL.TCL_ERROR; |
||
4581 | TCL.Tcl_AppendResult( interp, zBuf, 0 ); |
||
4582 | return TCL.TCL_OK; |
||
4583 | } |
||
4584 | /* |
||
4585 | ** Usage: sqlite3_open16 filename options |
||
4586 | */ |
||
4587 | //static int test_open16( |
||
4588 | // object clientdata, |
||
4589 | // Tcl_Interp interp, |
||
4590 | // int objc, |
||
4591 | // Tcl_Obj[] objv |
||
4592 | //){ |
||
4593 | #if !SQLITE_OMIT_UTF16 |
||
4594 | // string zFilename; |
||
4595 | // sqlite3 db=null; |
||
4596 | // int rc; |
||
4597 | // char zBuf[100]; |
||
4598 | |||
4599 | // if( objc!=3 ){ |
||
4600 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
4601 | // TCL.Tcl_GetString(objv[0]), " filename options-list", 0); |
||
4602 | // return TCL.TCL_ERROR; |
||
4603 | // } |
||
4604 | |||
4605 | // zFilename = TCL.Tcl_GetByteArrayFromObj(objv[1], 0); |
||
4606 | // rc = sqlite3_open16(zFilename, ref db); |
||
4607 | |||
4608 | // if ( sqlite3TestMakePointerStr( interp, zBuf, db ) != TCL.TCL_OK ) return TCL.TCL_ERROR; |
||
4609 | // TCL.Tcl_AppendResult(interp, zBuf); |
||
4610 | #endif // * SQLITE_OMIT_UTF16 */ |
||
4611 | // return TCL.TCL_OK; |
||
4612 | //} |
||
4613 | |||
4614 | /* |
||
4615 | ** Usage: sqlite3_complete16 <UTF-16 string> |
||
4616 | ** |
||
4617 | ** Return 1 if the supplied argument is a complete SQL statement, or zero |
||
4618 | ** otherwise. |
||
4619 | */ |
||
4620 | //static int test_complete16( |
||
4621 | // object clientdata, |
||
4622 | // Tcl_Interp interp, |
||
4623 | // int objc, |
||
4624 | // Tcl_Obj[] objv |
||
4625 | //){ |
||
4626 | #if !SQLITE_OMIT_COMPLETE && !SQLITE_OMIT_UTF16 |
||
4627 | // string zBuf; |
||
4628 | |||
4629 | // if( objc!=2 ){ |
||
4630 | // TCL.Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>"); |
||
4631 | // return TCL.TCL_ERROR; |
||
4632 | // } |
||
4633 | |||
4634 | // zBuf = (char)TCL.Tcl_GetByteArrayFromObj(objv[1], 0); |
||
4635 | // TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(sqlite3_complete16(zBuf))); |
||
4636 | #endif // * SQLITE_OMIT_COMPLETE && SQLITE_OMIT_UTF16 */ |
||
4637 | // return TCL.TCL_OK; |
||
4638 | //} |
||
4639 | |||
4640 | /* |
||
4641 | ** Usage: sqlite3_step STMT |
||
4642 | ** |
||
4643 | ** Advance the statement to the next row. |
||
4644 | */ |
||
4645 | static int test_step( |
||
4646 | object clientdata, |
||
4647 | Tcl_Interp interp, |
||
4648 | int objc, |
||
4649 | Tcl_Obj[] objv |
||
4650 | ) |
||
4651 | { |
||
4652 | sqlite3_stmt pStmt = null; |
||
4653 | int rc; |
||
4654 | |||
4655 | if ( objc != 2 ) |
||
4656 | { |
||
4657 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4658 | TCL.Tcl_GetString( objv[0] ), " STMT" ); |
||
4659 | return TCL.TCL_ERROR; |
||
4660 | } |
||
4661 | |||
4662 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
4663 | return TCL.TCL_ERROR; |
||
4664 | rc = sqlite3_step( pStmt ); |
||
4665 | |||
4666 | /* if( rc!=SQLITE_DONE && rc!=SQLITE_ROW ) return TCL.TCL_ERROR; */ |
||
4667 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), 0 ); |
||
4668 | return TCL.TCL_OK; |
||
4669 | } |
||
4670 | |||
4671 | static int test_sql( |
||
4672 | object clientdata, |
||
4673 | Tcl_Interp interp, |
||
4674 | int objc, |
||
4675 | Tcl_Obj[] objv |
||
4676 | ) |
||
4677 | { |
||
4678 | sqlite3_stmt pStmt = null; |
||
4679 | |||
4680 | if ( objc != 2 ) |
||
4681 | { |
||
4682 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT" ); |
||
4683 | return TCL.TCL_ERROR; |
||
4684 | } |
||
4685 | |||
4686 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
4687 | return TCL.TCL_ERROR; |
||
4688 | TCL.Tcl_SetResult( interp, sqlite3_sql( pStmt ), TCL.TCL_VOLATILE ); |
||
4689 | return TCL.TCL_OK; |
||
4690 | } |
||
4691 | |||
4692 | |||
4693 | /* |
||
4694 | ** Usage: sqlite3_column_count STMT |
||
4695 | ** |
||
4696 | ** Return the number of columns returned by the sql statement STMT. |
||
4697 | */ |
||
4698 | static int test_column_count( |
||
4699 | object clientdata, |
||
4700 | Tcl_Interp interp, |
||
4701 | int objc, |
||
4702 | Tcl_Obj[] objv |
||
4703 | ) |
||
4704 | { |
||
4705 | sqlite3_stmt pStmt = null; |
||
4706 | |||
4707 | if ( objc != 2 ) |
||
4708 | { |
||
4709 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4710 | TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
||
4711 | return TCL.TCL_ERROR; |
||
4712 | } |
||
4713 | |||
4714 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
4715 | return TCL.TCL_ERROR; |
||
4716 | |||
4717 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_column_count( pStmt ) ) ); |
||
4718 | return TCL.TCL_OK; |
||
4719 | } |
||
4720 | |||
4721 | /* |
||
4722 | ** Usage: sqlite3_column_type STMT column |
||
4723 | ** |
||
4724 | ** Return the type of the data in column 'column' of the current row. |
||
4725 | */ |
||
4726 | static int test_column_type( |
||
4727 | object clientdata, |
||
4728 | Tcl_Interp interp, |
||
4729 | int objc, |
||
4730 | Tcl_Obj[] objv |
||
4731 | ) |
||
4732 | { |
||
4733 | sqlite3_stmt pStmt = null; |
||
4734 | int col = 0; |
||
4735 | int tp; |
||
4736 | |||
4737 | if ( objc != 3 ) |
||
4738 | { |
||
4739 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4740 | TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
||
4741 | return TCL.TCL_ERROR; |
||
4742 | } |
||
4743 | |||
4744 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
4745 | return TCL.TCL_ERROR; |
||
4746 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
||
4747 | return TCL.TCL_ERROR; |
||
4748 | |||
4749 | tp = sqlite3_column_type( pStmt, col ); |
||
4750 | switch ( tp ) |
||
4751 | { |
||
4752 | case SQLITE_INTEGER: |
||
4753 | TCL.Tcl_SetResult( interp, "INTEGER", TCL.TCL_STATIC ); |
||
4754 | break; |
||
4755 | case SQLITE_NULL: |
||
4756 | TCL.Tcl_SetResult( interp, "NULL", TCL.TCL_STATIC ); |
||
4757 | break; |
||
4758 | case SQLITE_FLOAT: |
||
4759 | TCL.Tcl_SetResult( interp, "FLOAT", TCL.TCL_STATIC ); |
||
4760 | break; |
||
4761 | case SQLITE_TEXT: |
||
4762 | TCL.Tcl_SetResult( interp, "TEXT", TCL.TCL_STATIC ); |
||
4763 | break; |
||
4764 | case SQLITE_BLOB: |
||
4765 | TCL.Tcl_SetResult( interp, "BLOB", TCL.TCL_STATIC ); |
||
4766 | break; |
||
4767 | default: |
||
4768 | Debugger.Break(); |
||
4769 | break; |
||
4770 | } |
||
4771 | |||
4772 | return TCL.TCL_OK; |
||
4773 | } |
||
4774 | |||
4775 | /* |
||
4776 | ** Usage: sqlite3_column_int64 STMT column |
||
4777 | ** |
||
4778 | ** Return the data in column 'column' of the current row cast as an |
||
4779 | ** wide (64-bit) integer. |
||
4780 | */ |
||
4781 | static int test_column_int64( |
||
4782 | object clientdata, |
||
4783 | Tcl_Interp interp, |
||
4784 | int objc, |
||
4785 | Tcl_Obj[] objv |
||
4786 | ) |
||
4787 | { |
||
4788 | sqlite3_stmt pStmt = new sqlite3_stmt(); |
||
4789 | int col = 0; |
||
4790 | i64 iVal; |
||
4791 | |||
4792 | if ( objc != 3 ) |
||
4793 | { |
||
4794 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4795 | TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
||
4796 | return TCL.TCL_ERROR; |
||
4797 | } |
||
4798 | |||
4799 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != TCL.TCL_OK ) |
||
4800 | return TCL.TCL_ERROR; |
||
4801 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
||
4802 | return TCL.TCL_ERROR; |
||
4803 | |||
4804 | iVal = sqlite3_column_int64( pStmt, col ); |
||
4805 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewWideIntObj( iVal ) ); |
||
4806 | return TCL.TCL_OK; |
||
4807 | } |
||
4808 | |||
4809 | /* |
||
4810 | ** Usage: sqlite3_column_blob STMT column |
||
4811 | */ |
||
4812 | static int test_column_blob( |
||
4813 | object clientdata, |
||
4814 | Tcl_Interp interp, |
||
4815 | int objc, |
||
4816 | Tcl_Obj[] objv |
||
4817 | ) |
||
4818 | { |
||
4819 | sqlite3_stmt pStmt = new sqlite3_stmt(); |
||
4820 | int col = 0; |
||
4821 | |||
4822 | int len; |
||
4823 | byte[] pBlob; |
||
4824 | |||
4825 | if ( objc != 3 ) |
||
4826 | { |
||
4827 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4828 | TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
||
4829 | return TCL.TCL_ERROR; |
||
4830 | } |
||
4831 | |||
4832 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != TCL.TCL_OK ) |
||
4833 | return TCL.TCL_ERROR; |
||
4834 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
||
4835 | return TCL.TCL_ERROR; |
||
4836 | |||
4837 | len = sqlite3_column_bytes( pStmt, col ); |
||
4838 | pBlob = sqlite3_column_blob( pStmt, col ); |
||
4839 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewByteArrayObj( pBlob, len ) ); |
||
4840 | return TCL.TCL_OK; |
||
4841 | } |
||
4842 | |||
4843 | /* |
||
4844 | ** Usage: sqlite3_column_double STMT column |
||
4845 | ** |
||
4846 | ** Return the data in column 'column' of the current row cast as a double. |
||
4847 | */ |
||
4848 | static int test_column_double( |
||
4849 | object clientdata, |
||
4850 | Tcl_Interp interp, |
||
4851 | int objc, |
||
4852 | Tcl_Obj[] objv |
||
4853 | ) |
||
4854 | { |
||
4855 | sqlite3_stmt pStmt = new sqlite3_stmt(); |
||
4856 | int col = 0; |
||
4857 | double rVal; |
||
4858 | |||
4859 | if ( objc != 3 ) |
||
4860 | { |
||
4861 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4862 | TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
||
4863 | return TCL.TCL_ERROR; |
||
4864 | } |
||
4865 | |||
4866 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != TCL.TCL_OK ) |
||
4867 | return TCL.TCL_ERROR; |
||
4868 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
||
4869 | return TCL.TCL_ERROR; |
||
4870 | |||
4871 | rVal = sqlite3_column_double( pStmt, col ); |
||
4872 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewDoubleObj( rVal ) ); |
||
4873 | return TCL.TCL_OK; |
||
4874 | } |
||
4875 | |||
4876 | /* |
||
4877 | ** Usage: sqlite3_data_count STMT |
||
4878 | ** |
||
4879 | ** Return the number of columns returned by the sql statement STMT. |
||
4880 | */ |
||
4881 | static int test_data_count( |
||
4882 | object clientdata, |
||
4883 | Tcl_Interp interp, |
||
4884 | int objc, |
||
4885 | Tcl_Obj[] objv |
||
4886 | ) |
||
4887 | { |
||
4888 | sqlite3_stmt pStmt = null; |
||
4889 | |||
4890 | if ( objc != 2 ) |
||
4891 | { |
||
4892 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4893 | TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
||
4894 | return TCL.TCL_ERROR; |
||
4895 | } |
||
4896 | |||
4897 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != TCL.TCL_OK ) |
||
4898 | return TCL.TCL_ERROR; |
||
4899 | |||
4900 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( sqlite3_data_count( pStmt ) ) ); |
||
4901 | return TCL.TCL_OK; |
||
4902 | } |
||
4903 | |||
4904 | /* |
||
4905 | ** Usage: sqlite3_column_text STMT column |
||
4906 | ** |
||
4907 | ** Usage: sqlite3_column_decltype STMT column |
||
4908 | ** |
||
4909 | ** Usage: sqlite3_column_name STMT column |
||
4910 | */ |
||
4911 | static int test_stmt_utf8( |
||
4912 | object clientdata, /* Pointer to SQLite API function to be invoke */ |
||
4913 | Tcl_Interp interp, |
||
4914 | int objc, |
||
4915 | Tcl_Obj[] objv |
||
4916 | ) |
||
4917 | { |
||
4918 | sqlite3_stmt pStmt = null; |
||
4919 | int col = 0; |
||
4920 | dxColumn xFunc;//string (*xFunc)(sqlite3_stmt*, int); |
||
4921 | string zRet; |
||
4922 | |||
4923 | xFunc = (dxColumn)clientdata; //(string ()(sqlite3_stmt*, int))clientData; |
||
4924 | if ( objc != 3 ) |
||
4925 | { |
||
4926 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
4927 | TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
||
4928 | return TCL.TCL_ERROR; |
||
4929 | } |
||
4930 | |||
4931 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
4932 | return TCL.TCL_ERROR; |
||
4933 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
||
4934 | return TCL.TCL_ERROR; |
||
4935 | zRet = (string)xFunc( pStmt, col ); |
||
4936 | if ( zRet != null ) |
||
4937 | { |
||
4938 | TCL.Tcl_SetResult( interp, zRet, 0 ); |
||
4939 | } |
||
4940 | return TCL.TCL_OK; |
||
4941 | } |
||
4942 | |||
4943 | static int test_global_recover( |
||
4944 | object clientdata, |
||
4945 | Tcl_Interp interp, |
||
4946 | int objc, |
||
4947 | Tcl_Obj[] objv |
||
4948 | ) |
||
4949 | { |
||
4950 | #if !SQLITE_OMIT_DEPRECATED |
||
4951 | int rc; |
||
4952 | if ( objc != 1 ) |
||
4953 | { |
||
4954 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "" ); |
||
4955 | return TCL.TCL_ERROR; |
||
4956 | } |
||
4957 | rc = sqlite3_global_recover(); |
||
4958 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
||
4959 | #else |
||
4960 | TCL.Tcl_SetResult( interp, t1ErrorName( SQLITE_OK ), TCL.TCL_STATIC ); |
||
4961 | #endif |
||
4962 | return TCL.TCL_OK; |
||
4963 | } |
||
4964 | |||
4965 | /* |
||
4966 | ** Usage: sqlite3_column_text STMT column |
||
4967 | ** |
||
4968 | ** Usage: sqlite3_column_decltype STMT column |
||
4969 | ** |
||
4970 | ** Usage: sqlite3_column_name STMT column |
||
4971 | */ |
||
4972 | //static int test_stmt_utf16( |
||
4973 | // object clientdata, /* Pointer to SQLite API function to be invoked */ |
||
4974 | // Tcl_Interp interp, |
||
4975 | // int objc, |
||
4976 | // Tcl_Obj[] objv |
||
4977 | //){ |
||
4978 | #if !SQLITE_OMIT_UTF16 |
||
4979 | // sqlite3_stmt pStmt; |
||
4980 | // int col; |
||
4981 | // Tcl_Obj pRet; |
||
4982 | // string zName16; |
||
4983 | // const void *(*xFunc)(sqlite3_stmt*, int); |
||
4984 | |||
4985 | xFunc = (dxColumn)clientdata; //(string ()(sqlite3_stmt*, int))clientData; |
||
4986 | // if( objc!=3 ){ |
||
4987 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
4988 | // TCL.Tcl_GetString(objv[0]), " STMT column", 0); |
||
4989 | // return TCL.TCL_ERROR; |
||
4990 | // } |
||
4991 | |||
4992 | // if( getStmtPointer(interp, TCL.Tcl_GetString(objv[1]), pStmt) ) return TCL.TCL_ERROR; |
||
4993 | // if( TCL.Tcl_GetIntFromObj(interp, objv[2], out col) ) return TCL.TCL_ERROR; |
||
4994 | |||
4995 | // zName16 = xFunc(pStmt, col); |
||
4996 | // if( zName16 ){ |
||
4997 | int n; |
||
4998 | string z = zName16; |
||
4999 | for(n=0; z[n] || z[n+1]; n+=2){} |
||
5000 | pRet = TCL.Tcl_NewByteArrayObj(zName16, n+2); |
||
5001 | // TCL.Tcl_SetObjResult(interp, pRet); |
||
5002 | // } |
||
5003 | #endif // * SQLITE_OMIT_UTF16 */ |
||
5004 | |||
5005 | // return TCL.TCL_OK; |
||
5006 | //} |
||
5007 | |||
5008 | /* |
||
5009 | ** Usage: sqlite3_column_int STMT column |
||
5010 | ** |
||
5011 | ** Usage: sqlite3_column_bytes STMT column |
||
5012 | ** |
||
5013 | ** Usage: sqlite3_column_bytes16 STMT column |
||
5014 | ** |
||
5015 | */ |
||
5016 | static int test_stmt_int( |
||
5017 | object clientdata, /* Pointer to SQLite API function to be invoked */ |
||
5018 | Tcl_Interp interp, |
||
5019 | int objc, |
||
5020 | Tcl_Obj[] objv |
||
5021 | ) |
||
5022 | { |
||
5023 | sqlite3_stmt pStmt = null; |
||
5024 | int col = 0; |
||
5025 | dxColumn_I xFunc;//(sqlite3_stmt*, int) ; |
||
5026 | |||
5027 | xFunc = (dxColumn_I)clientdata; //(int ()(sqlite3_stmt*, int))clientData; |
||
5028 | if ( objc != 3 ) |
||
5029 | { |
||
5030 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
5031 | TCL.Tcl_GetString( objv[0] ), " STMT column" ); |
||
5032 | return TCL.TCL_ERROR; |
||
5033 | } |
||
5034 | |||
5035 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
5036 | return TCL.TCL_ERROR; |
||
5037 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[2], out col ) ) |
||
5038 | return TCL.TCL_ERROR; |
||
5039 | |||
5040 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( xFunc( pStmt, col ) ) ); |
||
5041 | return TCL.TCL_OK; |
||
5042 | } |
||
5043 | |||
5044 | |||
5045 | /* |
||
5046 | ** Usage: sqlite_set_magic DB MAGIC-NUMBER |
||
5047 | ** |
||
5048 | ** Set the db.magic value. This is used to test error recovery logic. |
||
5049 | */ |
||
5050 | static int sqlite_set_magic( |
||
5051 | object clientdata, /* Pointer to SQLite API function to be invoked */ |
||
5052 | Tcl_Interp interp, |
||
5053 | int argc, |
||
5054 | Tcl_Obj[] argv |
||
5055 | ) |
||
5056 | { |
||
5057 | sqlite3 db = null; |
||
5058 | if ( argc != 3 ) |
||
5059 | { |
||
5060 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
5061 | " DB MAGIC" ); |
||
5062 | return TCL.TCL_ERROR; |
||
5063 | } |
||
5064 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
5065 | return TCL.TCL_ERROR; |
||
5066 | if ( argv[2].ToString() == "SQLITE_MAGIC_OPEN" ) |
||
5067 | { |
||
5068 | db.magic = SQLITE_MAGIC_OPEN; |
||
5069 | } |
||
5070 | else if ( argv[2].ToString() == "SQLITE_MAGIC_CLOSED" ) |
||
5071 | { |
||
5072 | db.magic = SQLITE_MAGIC_CLOSED; |
||
5073 | } |
||
5074 | else if ( argv[2].ToString() == "SQLITE_MAGIC_BUSY" ) |
||
5075 | { |
||
5076 | db.magic = SQLITE_MAGIC_BUSY; |
||
5077 | } |
||
5078 | else if ( argv[2].ToString() == "SQLITE_MAGIC_ERROR" ) |
||
5079 | { |
||
5080 | db.magic = SQLITE_MAGIC_ERROR; |
||
5081 | } |
||
5082 | else if ( TCL.Tcl_GetInt( interp, argv[2], out db.magic ) ) |
||
5083 | { |
||
5084 | return TCL.TCL_ERROR; |
||
5085 | } |
||
5086 | return TCL.TCL_OK; |
||
5087 | } |
||
5088 | |||
5089 | /* |
||
5090 | ** Usage: sqlite3_interrupt DB |
||
5091 | ** |
||
5092 | ** Trigger an interrupt on DB |
||
5093 | */ |
||
5094 | static int test_interrupt( |
||
5095 | object clientdata, |
||
5096 | Tcl_Interp interp, |
||
5097 | int argc, |
||
5098 | Tcl_Obj[] argv ) |
||
5099 | { |
||
5100 | sqlite3 db = null; |
||
5101 | if ( argc != 2 ) |
||
5102 | { |
||
5103 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], " DB" ); |
||
5104 | return TCL.TCL_ERROR; |
||
5105 | } |
||
5106 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
5107 | return TCL.TCL_ERROR; |
||
5108 | sqlite3_interrupt( db ); |
||
5109 | return TCL.TCL_OK; |
||
5110 | } |
||
5111 | |||
5112 | //static u8 *sqlite3_stack_baseline = 0; |
||
5113 | |||
5114 | /* |
||
5115 | ** Fill the stack with a known bitpattern. |
||
5116 | */ |
||
5117 | //static void prepStack(void){ |
||
5118 | // int i; |
||
5119 | // u32 bigBuf[65536]; |
||
5120 | // for(i=0; i<sizeof(bigBuf); i++) bigBuf[i] = 0xdeadbeef; |
||
5121 | // sqlite3_stack_baseline = (u8)&bigBuf[65536]; |
||
5122 | //} |
||
5123 | |||
5124 | /* |
||
5125 | ** Get the current stack depth. Used for debugging only. |
||
5126 | */ |
||
5127 | //u64 sqlite3StackDepth(void){ |
||
5128 | // u8 x; |
||
5129 | // return (u64)(sqlite3_stack_baseline - &x); |
||
5130 | //} |
||
5131 | |||
5132 | /* |
||
5133 | ** Usage: sqlite3_stack_used DB SQL |
||
5134 | ** |
||
5135 | ** Try to measure the amount of stack space used by a call to sqlite3_exec |
||
5136 | */ |
||
5137 | //static int test_stack_used( |
||
5138 | // object clientdata, |
||
5139 | // Tcl_Interp interp, |
||
5140 | // int argc, |
||
5141 | // char **argv |
||
5142 | //){ |
||
5143 | // sqlite3 db=null; |
||
5144 | // int i; |
||
5145 | // if( argc!=3 ){ |
||
5146 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], |
||
5147 | // " DB SQL", 0); |
||
5148 | // return TCL.TCL_ERROR; |
||
5149 | // } |
||
5150 | // if( getDbPointer(interp, argv[1].ToString(), out db) !=0) return TCL.TCL_ERROR; |
||
5151 | // prepStack(); |
||
5152 | // (void)sqlite3_exec(db, argv[2], 0, 0, 0); |
||
5153 | // for(i=65535; i>=0 && ((u32)sqlite3_stack_baseline)[-i]==0xdeadbeef; i--){} |
||
5154 | // TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(i*4)); |
||
5155 | // return TCL.TCL_OK; |
||
5156 | //} |
||
5157 | |||
5158 | /* |
||
5159 | ** Usage: sqlite_delete_function DB function-name |
||
5160 | ** |
||
5161 | ** Delete the user function 'function-name' from database handle DB. It |
||
5162 | ** is assumed that the user function was created as UTF8, any number of |
||
5163 | ** arguments (the way the TCL interface does it). |
||
5164 | */ |
||
5165 | static int delete_function( |
||
5166 | object clientdata, |
||
5167 | Tcl_Interp interp, |
||
5168 | int argc, |
||
5169 | Tcl_Obj[] argv |
||
5170 | ) |
||
5171 | { |
||
5172 | int rc; |
||
5173 | sqlite3 db = null; |
||
5174 | if ( argc != 3 ) |
||
5175 | { |
||
5176 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
5177 | " DB function-name", null ); |
||
5178 | return TCL.TCL_ERROR; |
||
5179 | } |
||
5180 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
5181 | return TCL.TCL_ERROR; |
||
5182 | rc = sqlite3_create_function( db, argv[2].ToString(), -1, SQLITE_UTF8, null, null, null, null ); |
||
5183 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
||
5184 | return TCL.TCL_OK; |
||
5185 | } |
||
5186 | |||
5187 | /* |
||
5188 | ** Usage: sqlite_delete_collation DB collation-name |
||
5189 | ** |
||
5190 | ** Delete the collation sequence 'collation-name' from database handle |
||
5191 | ** DB. It is assumed that the collation sequence was created as UTF8 (the |
||
5192 | ** way the TCL interface does it). |
||
5193 | */ |
||
5194 | static int delete_collation( |
||
5195 | object clientdata, |
||
5196 | Tcl_Interp interp, |
||
5197 | int argc, |
||
5198 | Tcl_Obj[] argv |
||
5199 | ) |
||
5200 | { |
||
5201 | int rc; |
||
5202 | sqlite3 db = null; |
||
5203 | if ( argc != 3 ) |
||
5204 | { |
||
5205 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
5206 | " DB function-name", null ); |
||
5207 | return TCL.TCL_ERROR; |
||
5208 | } |
||
5209 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
5210 | return TCL.TCL_ERROR; |
||
5211 | rc = sqlite3_create_collation( db, argv[2].ToString(), SQLITE_UTF8, null, null ); |
||
5212 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
||
5213 | return TCL.TCL_OK; |
||
5214 | } |
||
5215 | |||
5216 | /* |
||
5217 | ** Usage: sqlite3_get_autocommit DB |
||
5218 | ** |
||
5219 | ** Return true if the database DB is currently in auto-commit mode. |
||
5220 | ** Return false if not. |
||
5221 | */ |
||
5222 | static int get_autocommit( |
||
5223 | object clientdata, |
||
5224 | Tcl_Interp interp, |
||
5225 | int argc, |
||
5226 | Tcl_Obj[] argv |
||
5227 | ) |
||
5228 | { |
||
5229 | StringBuilder zBuf = new StringBuilder( 30 ); |
||
5230 | sqlite3 db = null; |
||
5231 | if ( argc != 2 ) |
||
5232 | { |
||
5233 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
5234 | " DB" ); |
||
5235 | return TCL.TCL_ERROR; |
||
5236 | } |
||
5237 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
5238 | return TCL.TCL_ERROR; |
||
5239 | sqlite3_snprintf( 30, zBuf, "%d", sqlite3_get_autocommit( db ) ); |
||
5240 | TCL.Tcl_AppendResult( interp, zBuf ); |
||
5241 | return TCL.TCL_OK; |
||
5242 | } |
||
5243 | |||
5244 | /* |
||
5245 | ** Usage: sqlite3_busy_timeout DB MS |
||
5246 | ** |
||
5247 | ** Set the busy timeout. This is more easily done using the timeout |
||
5248 | ** method of the TCL interface. But we need a way to test the case |
||
5249 | ** where it returns SQLITE_MISUSE. |
||
5250 | */ |
||
5251 | static int test_busy_timeout( |
||
5252 | object clientdata, |
||
5253 | Tcl_Interp interp, |
||
5254 | int argc, |
||
5255 | Tcl_Obj[] argv |
||
5256 | ) |
||
5257 | { |
||
5258 | int rc, ms = 0; |
||
5259 | sqlite3 db = null; |
||
5260 | if ( argc != 3 ) |
||
5261 | { |
||
5262 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0], |
||
5263 | " DB" ); |
||
5264 | return TCL.TCL_ERROR; |
||
5265 | } |
||
5266 | if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 ) |
||
5267 | return TCL.TCL_ERROR; |
||
5268 | if ( TCL.Tcl_GetInt( interp, argv[2], out ms ) ) |
||
5269 | return TCL.TCL_ERROR; |
||
5270 | rc = sqlite3_busy_timeout( db, ms ); |
||
5271 | TCL.Tcl_AppendResult( interp, sqlite3TestErrorName( rc ) ); |
||
5272 | return TCL.TCL_OK; |
||
5273 | } |
||
5274 | |||
5275 | /* |
||
5276 | ** Usage: tcl_variable_type VARIABLENAME |
||
5277 | ** |
||
5278 | ** Return the name of the internal representation for the |
||
5279 | ** value of the given variable. |
||
5280 | */ |
||
5281 | static int tcl_variable_type( |
||
5282 | object clientdata, |
||
5283 | Tcl_Interp interp, |
||
5284 | int objc, |
||
5285 | Tcl_Obj[] objv |
||
5286 | ) |
||
5287 | { |
||
5288 | Tcl_Obj pVar; |
||
5289 | if ( objc != 2 ) |
||
5290 | { |
||
5291 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "VARIABLE" ); |
||
5292 | return TCL.TCL_ERROR; |
||
5293 | } |
||
5294 | pVar = TCL.Tcl_GetVar2Ex( interp, TCL.Tcl_GetString( objv[1] ), null, (TCL.VarFlag)TCL.TCL_LEAVE_ERR_MSG ); |
||
5295 | if ( pVar == null ) |
||
5296 | return TCL.TCL_ERROR; |
||
5297 | if ( pVar.typePtr != "" ) |
||
5298 | { |
||
5299 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewStringObj( pVar.typePtr, -1 ) ); |
||
5300 | } |
||
5301 | return TCL.TCL_OK; |
||
5302 | } |
||
5303 | |||
5304 | /* |
||
5305 | ** Usage: sqlite3_release_memory ?N? |
||
5306 | ** |
||
5307 | ** Attempt to release memory currently held but not actually required. |
||
5308 | ** The integer N is the number of bytes we are trying to release. The |
||
5309 | ** return value is the amount of memory actually released. |
||
5310 | */ |
||
5311 | static int test_release_memory( |
||
5312 | object clientdata, |
||
5313 | Tcl_Interp interp, |
||
5314 | int objc, |
||
5315 | Tcl_Obj[] objv |
||
5316 | ) |
||
5317 | { |
||
5318 | #if SQLITE_ENABLE_MEMORY_MANAGEMENT && !SQLITE_OMIT_DISKIO |
||
5319 | int N; |
||
5320 | int amt; |
||
5321 | if( objc!=1 && objc!=2 ){ |
||
5322 | TCL.Tcl_WrongNumArgs(interp, 1, objv, "?N?"); |
||
5323 | return TCL.TCL_ERROR; |
||
5324 | } |
||
5325 | if( objc==2 ){ |
||
5326 | if( TCL.Tcl_GetIntFromObj(interp, objv[1], out N) ) return TCL.TCL_ERROR; |
||
5327 | }else{ |
||
5328 | N = -1; |
||
5329 | } |
||
5330 | amt = sqlite3_release_memory(N); |
||
5331 | TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(amt)); |
||
5332 | #endif |
||
5333 | return TCL.TCL_OK; |
||
5334 | } |
||
5335 | |||
5336 | /* |
||
5337 | ** Usage: sqlite3_soft_heap_limit ?N? |
||
5338 | ** |
||
5339 | ** Query or set the soft heap limit for the current thread. The |
||
5340 | ** limit is only changed if the N is present. The previous limit |
||
5341 | ** is returned. |
||
5342 | */ |
||
5343 | static int test_soft_heap_limit( |
||
5344 | object clientdata, |
||
5345 | Tcl_Interp interp, |
||
5346 | int objc, |
||
5347 | Tcl_Obj[] objv |
||
5348 | ) |
||
5349 | { |
||
5350 | sqlite3_int64 amt; |
||
5351 | sqlite3_int64 N = -1; |
||
5352 | if ( objc != 1 && objc != 2 ) |
||
5353 | { |
||
5354 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "?N?" ); |
||
5355 | return TCL.TCL_ERROR; |
||
5356 | } |
||
5357 | if ( objc == 2 ) |
||
5358 | { |
||
5359 | if ( TCL.Tcl_GetWideIntFromObj( interp, objv[1], out N ) ) |
||
5360 | return TCL.TCL_ERROR; |
||
5361 | } |
||
5362 | amt = sqlite3_soft_heap_limit64( N ); |
||
5363 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewWideIntObj( amt ) ); |
||
5364 | return TCL.TCL_OK; |
||
5365 | } |
||
5366 | |||
5367 | /* |
||
5368 | ** Usage: sqlite3_thread_cleanup |
||
5369 | ** |
||
5370 | ** Call the sqlite3_thread_cleanup API. |
||
5371 | */ |
||
5372 | //static int test_thread_cleanup( |
||
5373 | // object clientdata, |
||
5374 | // Tcl_Interp interp, |
||
5375 | // int objc, |
||
5376 | // Tcl_Obj[] objv |
||
5377 | //){ |
||
5378 | // sqlite3_thread_cleanup(); |
||
5379 | // return TCL.TCL_OK; |
||
5380 | //} |
||
5381 | |||
5382 | |||
5383 | /* |
||
5384 | ** Usage: sqlite3_pager_refcounts DB |
||
5385 | ** |
||
5386 | ** Return a list of numbers which are the PagerRefcount for all |
||
5387 | ** pagers on each database connection. |
||
5388 | */ |
||
5389 | //static int test_pager_refcounts( |
||
5390 | // object clientdata, |
||
5391 | // Tcl_Interp interp, |
||
5392 | // int objc, |
||
5393 | // Tcl_Obj[] objv |
||
5394 | //){ |
||
5395 | // sqlite3 db=null; |
||
5396 | // int i; |
||
5397 | // int v, *a; |
||
5398 | // Tcl_Obj pResult; |
||
5399 | |||
5400 | // if( objc!=2 ){ |
||
5401 | // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", |
||
5402 | // TCL.Tcl_GetStringFromObj(objv[0], 0), " DB", 0); |
||
5403 | // return TCL.TCL_ERROR; |
||
5404 | // } |
||
5405 | // if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), out db) !=0) return TCL.TCL_ERROR; |
||
5406 | // pResult = TCL.Tcl_NewObj(); |
||
5407 | // for(i=0; i<db.nDb; i++){ |
||
5408 | // if( db.aDb[i].pBt==null ){ |
||
5409 | // v = -1; |
||
5410 | // }else{ |
||
5411 | // sqlite3_mutex_enter(db.mutex); |
||
5412 | // a = sqlite3PagerStats(sqlite3BtreePager(db.aDb[i].pBt)); |
||
5413 | // v = a[0]; |
||
5414 | // sqlite3_mutex_leave(db.mutex); |
||
5415 | // } |
||
5416 | // TCL.Tcl_ListObjAppendElement(0, pResult, TCL.Tcl_NewIntObj(v)); |
||
5417 | // } |
||
5418 | // TCL.Tcl_SetObjResult(interp, pResult); |
||
5419 | // return TCL.TCL_OK; |
||
5420 | //} |
||
5421 | |||
5422 | |||
5423 | /* |
||
5424 | ** tclcmd: working_64bit_int |
||
5425 | ** |
||
5426 | ** Some TCL builds (ex: cygwin) do not support 64-bit integers. This |
||
5427 | ** leads to a number of test failures. The present command checks the |
||
5428 | ** TCL build to see whether or not it supports 64-bit integers. It |
||
5429 | ** returns TRUE if it does and FALSE if not. |
||
5430 | ** |
||
5431 | ** This command is used to warn users that their TCL build is defective |
||
5432 | ** and that the errors they are seeing in the test scripts might be |
||
5433 | ** a result of their defective TCL rather than problems in SQLite. |
||
5434 | */ |
||
5435 | static int working_64bit_int( |
||
5436 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
5437 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5438 | int objc, /* Number of arguments */ |
||
5439 | Tcl_Obj[] objv /* Command arguments */ |
||
5440 | ) |
||
5441 | { |
||
5442 | Tcl_Obj pTestObj; |
||
5443 | int working = 0; |
||
5444 | |||
5445 | pTestObj = TCL.Tcl_NewWideIntObj( 1000000 * (i64)1234567890 ); |
||
5446 | working = ( TCL.Tcl_GetString( pTestObj ) == "1234567890000000" ) ? 1 : 0; |
||
5447 | TCL.Tcl_DecrRefCount( ref pTestObj ); |
||
5448 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewBooleanObj( working ) ); |
||
5449 | return TCL.TCL_OK; |
||
5450 | } |
||
5451 | |||
5452 | |||
5453 | /* |
||
5454 | ** tclcmd: vfs_unlink_test |
||
5455 | ** |
||
5456 | ** This TCL command unregisters the primary VFS and then registers |
||
5457 | ** it back again. This is used to test the ability to register a |
||
5458 | ** VFS when none are previously registered, and the ability to |
||
5459 | ** unregister the only available VFS. Ticket #2738 |
||
5460 | */ |
||
5461 | static int vfs_unlink_test( |
||
5462 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
5463 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5464 | int objc, /* Number of arguments */ |
||
5465 | Tcl_Obj[] objv /* Command arguments */ |
||
5466 | ) |
||
5467 | { |
||
5468 | int i; |
||
5469 | sqlite3_vfs pMain; |
||
5470 | sqlite3_vfs one = new sqlite3_vfs(); |
||
5471 | sqlite3_vfs two = new sqlite3_vfs(); |
||
5472 | |||
5473 | sqlite3_vfs_unregister( null ); /* Unregister of NULL is harmless */ |
||
5474 | one.zName = "__one"; |
||
5475 | two.zName = "__two"; |
||
5476 | |||
5477 | /* Calling sqlite3_vfs_register with 2nd argument of 0 does not |
||
5478 | ** change the default VFS |
||
5479 | */ |
||
5480 | pMain = sqlite3_vfs_find( null ); |
||
5481 | sqlite3_vfs_register( one, 0 ); |
||
5482 | Debug.Assert( pMain == null || pMain == sqlite3_vfs_find( null ) ); |
||
5483 | sqlite3_vfs_register( two, 0 ); |
||
5484 | Debug.Assert( pMain == null || pMain == sqlite3_vfs_find( null ) ); |
||
5485 | |||
5486 | /* We can find a VFS by its name */ |
||
5487 | Debug.Assert( sqlite3_vfs_find( "__one" ) == one ); |
||
5488 | Debug.Assert( sqlite3_vfs_find( "__two" ) == two ); |
||
5489 | |||
5490 | /* Calling sqlite_vfs_register with non-zero second parameter changes the |
||
5491 | ** default VFS, even if the 1st parameter is an existig VFS that is |
||
5492 | ** previously registered as the non-default. |
||
5493 | */ |
||
5494 | sqlite3_vfs_register( one, 1 ); |
||
5495 | Debug.Assert( sqlite3_vfs_find( "__one" ) == one ); |
||
5496 | Debug.Assert( sqlite3_vfs_find( "__two" ) == two ); |
||
5497 | Debug.Assert( sqlite3_vfs_find( null ) == one ); |
||
5498 | sqlite3_vfs_register( two, 1 ); |
||
5499 | Debug.Assert( sqlite3_vfs_find( "__one" ) == one ); |
||
5500 | Debug.Assert( sqlite3_vfs_find( "__two" ) == two ); |
||
5501 | Debug.Assert( sqlite3_vfs_find( null ) == two ); |
||
5502 | if ( pMain != null ) |
||
5503 | { |
||
5504 | sqlite3_vfs_register( pMain, 1 ); |
||
5505 | Debug.Assert( sqlite3_vfs_find( "__one" ) == one ); |
||
5506 | Debug.Assert( sqlite3_vfs_find( "__two" ) == two ); |
||
5507 | Debug.Assert( sqlite3_vfs_find( null ) == pMain ); |
||
5508 | } |
||
5509 | |||
5510 | /* Unlink the default VFS. Repeat until there are no more VFSes |
||
5511 | ** registered. |
||
5512 | */ |
||
5513 | for ( i = 0; i < apVfs.Length; i++ ) |
||
5514 | {//sizeof(apVfs)/sizeof(apVfs[0]); i++){ |
||
5515 | apVfs[i] = sqlite3_vfs_find( null ); |
||
5516 | if ( apVfs[i] != null ) |
||
5517 | { |
||
5518 | Debug.Assert( apVfs[i] == sqlite3_vfs_find( apVfs[i].zName ) ); |
||
5519 | sqlite3_vfs_unregister( apVfs[i] ); |
||
5520 | Debug.Assert( null == sqlite3_vfs_find( apVfs[i].zName ) ); |
||
5521 | } |
||
5522 | } |
||
5523 | Debug.Assert( null == sqlite3_vfs_find( null ) ); |
||
5524 | |||
5525 | |||
5526 | /* Register the main VFS as non-default (will be made default, since |
||
5527 | ** it'll be the only one in existence). |
||
5528 | */ |
||
5529 | sqlite3_vfs_register( pMain, 0 ); |
||
5530 | Debug.Assert( sqlite3_vfs_find( null ) == pMain ); |
||
5531 | |||
5532 | /* Un-register the main VFS again to restore an empty VFS list */ |
||
5533 | sqlite3_vfs_unregister( pMain ); |
||
5534 | Debug.Assert( null == sqlite3_vfs_find( null ) ); |
||
5535 | |||
5536 | /* Relink all VFSes in reverse order. */ |
||
5537 | for ( i = apVfs.Length - 1; i >= 0; i-- ) |
||
5538 | {//sizeof(apVfs)/sizeof(apVfs[0])-1; i>=0; i--){ |
||
5539 | if ( apVfs[i] != null ) |
||
5540 | { |
||
5541 | sqlite3_vfs_register( apVfs[i], 1 ); |
||
5542 | Debug.Assert( apVfs[i] == sqlite3_vfs_find( null ) ); |
||
5543 | Debug.Assert( apVfs[i] == sqlite3_vfs_find( apVfs[i].zName ) ); |
||
5544 | } |
||
5545 | } |
||
5546 | |||
5547 | /* Unregister out sample VFSes. */ |
||
5548 | sqlite3_vfs_unregister( one ); |
||
5549 | sqlite3_vfs_unregister( two ); |
||
5550 | |||
5551 | /* Unregistering a VFS that is not currently registered is harmless */ |
||
5552 | sqlite3_vfs_unregister( one ); |
||
5553 | sqlite3_vfs_unregister( two ); |
||
5554 | Debug.Assert( sqlite3_vfs_find( "__one" ) == null ); |
||
5555 | Debug.Assert( sqlite3_vfs_find( "__two" ) == null ); |
||
5556 | |||
5557 | /* We should be left with the original default VFS back as the |
||
5558 | ** original */ |
||
5559 | Debug.Assert( sqlite3_vfs_find( null ) == pMain ); |
||
5560 | |||
5561 | return TCL.TCL_OK; |
||
5562 | } |
||
5563 | |||
5564 | /* |
||
5565 | ** tclcmd: vfs_initfail_test |
||
5566 | ** |
||
5567 | ** This TCL command attempts to vfs_find and vfs_register when the |
||
5568 | ** sqlite3_initialize() interface is failing. All calls should fail. |
||
5569 | */ |
||
5570 | //static int vfs_initfail_test( |
||
5571 | // ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
||
5572 | // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5573 | // int objc, /* Number of arguments */ |
||
5574 | // Tcl_Obj[] objv /* Command arguments */ |
||
5575 | //){ |
||
5576 | // sqlite3_vfs one; |
||
5577 | // one.zName = "__one"; |
||
5578 | |||
5579 | // if( sqlite3_vfs_find(0) ) return TCL.TCL_ERROR; |
||
5580 | // sqlite3_vfs_register(&one, 0); |
||
5581 | // if( sqlite3_vfs_find(0) ) return TCL.TCL_ERROR; |
||
5582 | // sqlite3_vfs_register(&one, 1); |
||
5583 | // if( sqlite3_vfs_find(0) ) return TCL.TCL_ERROR; |
||
5584 | // return TCL.TCL_OK; |
||
5585 | //} |
||
5586 | |||
5587 | |||
5588 | /* |
||
5589 | ** Saved VFSes |
||
5590 | */ |
||
5591 | static sqlite3_vfs[] apVfs = new sqlite3_vfs[20]; |
||
5592 | static int nVfs = 0; |
||
5593 | |||
5594 | /* |
||
5595 | ** tclcmd: vfs_unregister_all |
||
5596 | ** |
||
5597 | ** Unregister all VFSes. |
||
5598 | */ |
||
5599 | static int vfs_unregister_all( |
||
5600 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
5601 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5602 | int objc, /* Number of arguments */ |
||
5603 | Tcl_Obj[] objv /* Command arguments */ |
||
5604 | ) |
||
5605 | { |
||
5606 | int i; |
||
5607 | for ( i = 0; i < apVfs.Length; i++ ) |
||
5608 | { |
||
5609 | apVfs[i] = sqlite3_vfs_find( null ); |
||
5610 | if ( apVfs[i] == null ) |
||
5611 | break; |
||
5612 | sqlite3_vfs_unregister( apVfs[i] ); |
||
5613 | } |
||
5614 | nVfs = i; |
||
5615 | return TCL.TCL_OK; |
||
5616 | } |
||
5617 | |||
5618 | /* |
||
5619 | ** tclcmd: vfs_reregister_all |
||
5620 | ** |
||
5621 | ** Restore all VFSes that were removed using vfs_unregister_all |
||
5622 | */ |
||
5623 | static int vfs_reregister_all( |
||
5624 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
5625 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5626 | int objc, /* Number of arguments */ |
||
5627 | Tcl_Obj[] objv /* Command arguments */ |
||
5628 | ) |
||
5629 | { |
||
5630 | int i; |
||
5631 | for ( i = 0; i < nVfs; i++ ) |
||
5632 | { |
||
5633 | sqlite3_vfs_register( apVfs[i], i == 0 ? 1 : 0 ); |
||
5634 | } |
||
5635 | return TCL.TCL_OK; |
||
5636 | } |
||
5637 | |||
5638 | |||
5639 | /* |
||
5640 | ** tclcmd: file_control_test DB |
||
5641 | ** |
||
5642 | ** This TCL command runs the sqlite3_file_control interface and |
||
5643 | ** verifies correct operation of the same. |
||
5644 | */ |
||
5645 | static int file_control_test( |
||
5646 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
5647 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5648 | int objc, /* Number of arguments */ |
||
5649 | Tcl_Obj[] objv /* Command arguments */ |
||
5650 | ) |
||
5651 | { |
||
5652 | sqlite3_int64 iArg = 0; |
||
5653 | sqlite3 db = null; |
||
5654 | int rc; |
||
5655 | |||
5656 | if ( objc != 2 ) |
||
5657 | { |
||
5658 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
5659 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB" ); |
||
5660 | return TCL.TCL_ERROR; |
||
5661 | } |
||
5662 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
5663 | return TCL.TCL_ERROR; |
||
5664 | rc = sqlite3_file_control( db, null, 0, ref iArg ); |
||
5665 | Debug.Assert( rc == SQLITE_NOTFOUND ); |
||
5666 | rc = sqlite3_file_control( db, "notadatabase", SQLITE_FCNTL_LOCKSTATE, ref iArg ); |
||
5667 | Debug.Assert( rc == SQLITE_ERROR ); |
||
5668 | rc = sqlite3_file_control( db, "main", -1, ref iArg ); |
||
5669 | Debug.Assert( rc == SQLITE_NOTFOUND ); |
||
5670 | rc = sqlite3_file_control( db, "temp", -1, ref iArg ); |
||
5671 | Debug.Assert( rc == SQLITE_NOTFOUND || rc == SQLITE_ERROR ); |
||
5672 | return TCL.TCL_OK; |
||
5673 | } |
||
5674 | |||
5675 | |||
5676 | /* |
||
5677 | ** tclcmd: file_control_lasterrno_test DB |
||
5678 | ** |
||
5679 | ** This TCL command runs the sqlite3_file_control interface and |
||
5680 | ** verifies correct operation of the SQLITE_LAST_ERRNO verb. |
||
5681 | */ |
||
5682 | static int file_control_lasterrno_test( |
||
5683 | ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
||
5684 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5685 | int objc, /* Number of arguments */ |
||
5686 | Tcl_Obj[] objv /* Command arguments */ |
||
5687 | ) |
||
5688 | { |
||
5689 | sqlite3_int64 iArg = 0; |
||
5690 | sqlite3 db = null; |
||
5691 | int rc; |
||
5692 | |||
5693 | if ( objc != 2 ) |
||
5694 | { |
||
5695 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
5696 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB" ); |
||
5697 | return TCL.TCL_ERROR; |
||
5698 | } |
||
5699 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
5700 | { |
||
5701 | return TCL.TCL_ERROR; |
||
5702 | } |
||
5703 | rc = sqlite3_file_control( db, null, SQLITE_LAST_ERRNO, ref iArg ); |
||
5704 | if ( rc != 0 ) |
||
5705 | { |
||
5706 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( rc ) ); |
||
5707 | return TCL.TCL_ERROR; |
||
5708 | } |
||
5709 | if ( iArg != 0 ) |
||
5710 | { |
||
5711 | TCL.Tcl_AppendResult( interp, "Unexpected non-zero errno: ", iArg.ToString(), "" ); |
||
5712 | //TCL.Tcl_GetStringFromObj(TCL.Tcl_NewIntObj(iArg), 0), " ", 0); |
||
5713 | return TCL.TCL_ERROR; |
||
5714 | } |
||
5715 | return TCL.TCL_OK; |
||
5716 | } |
||
5717 | |||
5718 | |||
5719 | /* |
||
5720 | ** tclcmd: file_control_chunksize_test DB DBNAME SIZE |
||
5721 | ** |
||
5722 | ** This TCL command runs the sqlite3_file_control interface and |
||
5723 | ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and |
||
5724 | ** SQLITE_SET_LOCKPROXYFILE verbs. |
||
5725 | */ |
||
5726 | static int file_control_chunksize_test( |
||
5727 | ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
||
5728 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5729 | int objc, /* Number of arguments */ |
||
5730 | Tcl_Obj[] objv /* Command arguments */ |
||
5731 | ) |
||
5732 | { |
||
5733 | int nSize = 0; /* New chunk size */ |
||
5734 | string zDb; /* Db name ("main", "temp" etc.) */ |
||
5735 | sqlite3 db = null; /* Database handle */ |
||
5736 | int rc; /* file_control() return code */ |
||
5737 | |||
5738 | if ( objc != 4 ) |
||
5739 | { |
||
5740 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB DBNAME SIZE" ); |
||
5741 | return TCL.TCL_ERROR; |
||
5742 | } |
||
5743 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 |
||
5744 | || TCL.Tcl_GetIntFromObj( interp, objv[3], out nSize ) != 0 |
||
5745 | ) |
||
5746 | { |
||
5747 | return TCL.TCL_ERROR; |
||
5748 | } |
||
5749 | zDb = TCL.Tcl_GetString( objv[2] ); |
||
5750 | if ( zDb == "" ) |
||
5751 | zDb = null; |
||
5752 | |||
5753 | i64 iSize = 0; |
||
5754 | rc = sqlite3_file_control( db, zDb, SQLITE_FCNTL_CHUNK_SIZE, ref iSize ); |
||
5755 | nSize = (int)iSize; |
||
5756 | |||
5757 | if ( rc != 0 ) |
||
5758 | { |
||
5759 | TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), TCL.TCL_STATIC ); |
||
5760 | return TCL.TCL_ERROR; |
||
5761 | } |
||
5762 | return TCL.TCL_OK; |
||
5763 | } |
||
5764 | |||
5765 | |||
5766 | |||
5767 | /* |
||
5768 | ** tclcmd: file_control_sizehint_test DB DBNAME SIZE |
||
5769 | ** |
||
5770 | ** This TCL command runs the sqlite3_file_control interface and |
||
5771 | ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and |
||
5772 | ** SQLITE_SET_LOCKPROXYFILE verbs. |
||
5773 | */ |
||
5774 | static int file_control_sizehint_test( |
||
5775 | ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
||
5776 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5777 | int objc, /* Number of arguments */ |
||
5778 | Tcl_Obj[] objv /* Command arguments */ |
||
5779 | ) |
||
5780 | { |
||
5781 | sqlite3_int64 nSize = 0; /* Hinted size */ |
||
5782 | string zDb; /* Db name ("main", "temp" etc.) */ |
||
5783 | sqlite3 db = null; /* Database handle */ |
||
5784 | int rc; /* file_control() return code */ |
||
5785 | |||
5786 | if ( objc != 4 ) |
||
5787 | { |
||
5788 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB DBNAME SIZE" ); |
||
5789 | return TCL.TCL_ERROR; |
||
5790 | } |
||
5791 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 |
||
5792 | || TCL.Tcl_GetWideIntFromObj( interp, objv[3], out nSize ) |
||
5793 | ) |
||
5794 | { |
||
5795 | return TCL.TCL_ERROR; |
||
5796 | } |
||
5797 | zDb = TCL.Tcl_GetString( objv[2] ); |
||
5798 | if ( zDb[0] == '\0' ) |
||
5799 | zDb = null; |
||
5800 | |||
5801 | rc = sqlite3_file_control( db, zDb, SQLITE_FCNTL_SIZE_HINT, ref nSize ); |
||
5802 | if ( rc != 0 ) |
||
5803 | { |
||
5804 | TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), TCL.TCL_STATIC ); |
||
5805 | return TCL.TCL_ERROR; |
||
5806 | } |
||
5807 | return TCL.TCL_OK; |
||
5808 | } |
||
5809 | |||
5810 | /* |
||
5811 | ** tclcmd: file_control_lockproxy_test DB PWD |
||
5812 | ** |
||
5813 | ** This TCL command runs the sqlite3_file_control interface and |
||
5814 | ** verifies correct operation of the SQLITE_GET_LOCKPROXYFILE and |
||
5815 | ** SQLITE_SET_LOCKPROXYFILE verbs. |
||
5816 | */ |
||
5817 | static int file_control_lockproxy_test( |
||
5818 | ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
||
5819 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5820 | int objc, /* Number of arguments */ |
||
5821 | Tcl_Obj[] objv /* Command arguments */ |
||
5822 | ) |
||
5823 | { |
||
5824 | sqlite3 db = null; |
||
5825 | string zPwd; |
||
5826 | int nPwd = 0; |
||
5827 | |||
5828 | if ( objc != 3 ) |
||
5829 | { |
||
5830 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
5831 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB PWD" ); |
||
5832 | return TCL.TCL_ERROR; |
||
5833 | } |
||
5834 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
5835 | { |
||
5836 | return TCL.TCL_ERROR; |
||
5837 | } |
||
5838 | zPwd = TCL.Tcl_GetStringFromObj( objv[2], out nPwd ); |
||
5839 | |||
5840 | //#if !(SQLITE_ENABLE_LOCKING_STYLE) && (__APPLE__) |
||
5841 | //{ |
||
5842 | // char *testPath; |
||
5843 | // int rc; |
||
5844 | // char proxyPath[400]; |
||
5845 | |||
5846 | // if( sizeof(proxyPath)<nPwd+20 ){ |
||
5847 | // TCL.Tcl_AppendResult(interp, "PWD too big", (void)0); |
||
5848 | // return TCL.TCL_ERROR; |
||
5849 | // } |
||
5850 | // sprintf(proxyPath, "%s/test.proxy", zPwd); |
||
5851 | // rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath); |
||
5852 | // if( rc ){ |
||
5853 | // TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(rc)); |
||
5854 | // return TCL.TCL_ERROR; |
||
5855 | // } |
||
5856 | // rc = sqlite3_file_control(db, NULL, SQLITE_GET_LOCKPROXYFILE, &testPath); |
||
5857 | // if( strncmp(proxyPath,testPath,11) ){ |
||
5858 | // TCL.Tcl_AppendResult(interp, "Lock proxy file did not match the " |
||
5859 | // "previously assigned value", 0); |
||
5860 | // return TCL.TCL_ERROR; |
||
5861 | // } |
||
5862 | // if( rc ){ |
||
5863 | // TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(rc)); |
||
5864 | // return TCL.TCL_ERROR; |
||
5865 | // } |
||
5866 | // rc = sqlite3_file_control(db, NULL, SQLITE_SET_LOCKPROXYFILE, proxyPath); |
||
5867 | // if( rc ){ |
||
5868 | // TCL.Tcl_SetObjResult(interp, TCL.Tcl_NewIntObj(rc)); |
||
5869 | // return TCL.TCL_ERROR; |
||
5870 | // } |
||
5871 | //} |
||
5872 | //#endif |
||
5873 | return TCL.TCL_OK; |
||
5874 | } |
||
5875 | |||
5876 | /* |
||
5877 | ** tclcmd: sqlite3_vfs_list |
||
5878 | ** |
||
5879 | ** Return a tcl list containing the names of all registered vfs's. |
||
5880 | */ |
||
5881 | //static int vfs_list( |
||
5882 | // ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
||
5883 | // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5884 | // int objc, /* Number of arguments */ |
||
5885 | // Tcl_Obj[] objv /* Command arguments */ |
||
5886 | //){ |
||
5887 | // sqlite3_vfs pVfs; |
||
5888 | // Tcl_Obj pRet = TCL.Tcl_NewObj(); |
||
5889 | // if( objc!=1 ){ |
||
5890 | // TCL.Tcl_WrongNumArgs(interp, 1, objv, ""); |
||
5891 | // return TCL.TCL_ERROR; |
||
5892 | // } |
||
5893 | // for(pVfs=sqlite3_vfs_find(0); pVfs!=null; pVfs=pVfs.pNext){ |
||
5894 | // TCL.Tcl_ListObjAppendElement(interp, pRet, TCL.Tcl_NewStringObj(pVfs.zName, -1)); |
||
5895 | // } |
||
5896 | // TCL.Tcl_SetObjResult(interp, pRet); |
||
5897 | // return TCL.TCL_OK; |
||
5898 | //} |
||
5899 | |||
5900 | /* |
||
5901 | ** tclcmd: sqlite3_limit DB ID VALUE |
||
5902 | ** |
||
5903 | ** This TCL command runs the sqlite3_limit interface and |
||
5904 | ** verifies correct operation of the same. |
||
5905 | */ |
||
5906 | struct _aID |
||
5907 | { |
||
5908 | public string zName; |
||
5909 | public int id; |
||
5910 | public _aID( string zName, int id ) |
||
5911 | { |
||
5912 | this.zName = zName; |
||
5913 | this.id = id; |
||
5914 | } |
||
5915 | } |
||
5916 | |||
5917 | static int test_limit( |
||
5918 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
5919 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5920 | int objc, /* Number of arguments */ |
||
5921 | Tcl_Obj[] objv /* Command arguments */ |
||
5922 | ) |
||
5923 | { |
||
5924 | sqlite3 db = null; |
||
5925 | int rc = 0; |
||
5926 | _aID[] aId = new _aID[] { |
||
5927 | new _aID( "SQLITE_LIMIT_LENGTH", SQLITE_LIMIT_LENGTH ), |
||
5928 | new _aID( "SQLITE_LIMIT_SQL_LENGTH", SQLITE_LIMIT_SQL_LENGTH ), |
||
5929 | new _aID( "SQLITE_LIMIT_COLUMN", SQLITE_LIMIT_COLUMN ), |
||
5930 | new _aID( "SQLITE_LIMIT_EXPR_DEPTH", SQLITE_LIMIT_EXPR_DEPTH ), |
||
5931 | new _aID( "SQLITE_LIMIT_COMPOUND_SELECT", SQLITE_LIMIT_COMPOUND_SELECT ), |
||
5932 | new _aID( "SQLITE_LIMIT_VDBE_OP", SQLITE_LIMIT_VDBE_OP ), |
||
5933 | new _aID( "SQLITE_LIMIT_FUNCTION_ARG", SQLITE_LIMIT_FUNCTION_ARG ), |
||
5934 | new _aID( "SQLITE_LIMIT_ATTACHED", SQLITE_LIMIT_ATTACHED ), |
||
5935 | new _aID( "SQLITE_LIMIT_LIKE_PATTERN_LENGTH", SQLITE_LIMIT_LIKE_PATTERN_LENGTH ), |
||
5936 | new _aID( "SQLITE_LIMIT_VARIABLE_NUMBER", SQLITE_LIMIT_VARIABLE_NUMBER ), |
||
5937 | new _aID( "SQLITE_LIMIT_TRIGGER_DEPTH", SQLITE_LIMIT_TRIGGER_DEPTH ), |
||
5938 | |||
5939 | /* Out of range test cases */ |
||
5940 | new _aID( "SQLITE_LIMIT_TOOSMALL", -1 ), |
||
5941 | new _aID( "SQLITE_LIMIT_TOOBIG", SQLITE_LIMIT_TRIGGER_DEPTH+1 ), |
||
5942 | }; |
||
5943 | int i, id = 0; |
||
5944 | int val = 0; |
||
5945 | string zId; |
||
5946 | |||
5947 | if ( objc != 4 ) |
||
5948 | { |
||
5949 | TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", |
||
5950 | TCL.Tcl_GetStringFromObj( objv[0], 0 ), " DB ID VALUE" ); |
||
5951 | return TCL.TCL_ERROR; |
||
5952 | } |
||
5953 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
5954 | return TCL.TCL_ERROR; |
||
5955 | zId = TCL.Tcl_GetString( objv[2] ); |
||
5956 | for ( i = 0; i < aId.Length; i++ ) |
||
5957 | { |
||
5958 | if ( zId == aId[i].zName ) |
||
5959 | { |
||
5960 | id = aId[i].id; |
||
5961 | break; |
||
5962 | } |
||
5963 | } |
||
5964 | if ( i >= aId.Length ) |
||
5965 | { |
||
5966 | TCL.Tcl_AppendResult( interp, "unknown limit type: ", zId, '\0' ); |
||
5967 | return TCL.TCL_ERROR; |
||
5968 | } |
||
5969 | if ( TCL.TCL_OK != TCL.Tcl_GetIntFromObj( interp, objv[3], out val ) ) |
||
5970 | return TCL.TCL_ERROR; |
||
5971 | rc = sqlite3_limit( db, id, val ); |
||
5972 | TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( rc ) ); |
||
5973 | return TCL.TCL_OK; |
||
5974 | } |
||
5975 | |||
5976 | /* |
||
5977 | ** tclcmd: save_prng_state |
||
5978 | ** |
||
5979 | ** Save the state of the pseudo-random number generator. |
||
5980 | ** At the same time, verify that sqlite3_test_control works even when |
||
5981 | ** called with an out-of-range opcode. |
||
5982 | */ |
||
5983 | static int save_prng_state( |
||
5984 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
5985 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
5986 | int objc, /* Number of arguments */ |
||
5987 | Tcl_Obj[] objv /* Command arguments */ |
||
5988 | ) |
||
5989 | { |
||
5990 | int rc = sqlite3_test_control( 9999 ); |
||
5991 | Debug.Assert( rc == 0 ); |
||
5992 | rc = sqlite3_test_control( -1 ); |
||
5993 | Debug.Assert( rc == 0 ); |
||
5994 | sqlite3_test_control( SQLITE_TESTCTRL_PRNG_SAVE ); |
||
5995 | return TCL.TCL_OK; |
||
5996 | } |
||
5997 | /* |
||
5998 | ** tclcmd: restore_prng_state |
||
5999 | */ |
||
6000 | static int restore_prng_state( |
||
6001 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
6002 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
6003 | int objc, /* Number of arguments */ |
||
6004 | Tcl_Obj[] objv /* Command arguments */ |
||
6005 | ) |
||
6006 | { |
||
6007 | sqlite3_test_control( SQLITE_TESTCTRL_PRNG_RESTORE ); |
||
6008 | return TCL.TCL_OK; |
||
6009 | } |
||
6010 | /* |
||
6011 | ** tclcmd: reset_prng_state |
||
6012 | */ |
||
6013 | static int reset_prng_state( |
||
6014 | object clientdata, /* Pointer to sqlite3_enable_XXX function */ |
||
6015 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
6016 | int objc, /* Number of arguments */ |
||
6017 | Tcl_Obj[] objv /* Command arguments */ |
||
6018 | ) |
||
6019 | { |
||
6020 | sqlite3_test_control( SQLITE_TESTCTRL_PRNG_RESET ); |
||
6021 | return TCL.TCL_OK; |
||
6022 | } |
||
6023 | |||
6024 | |||
6025 | /* |
||
6026 | ** tclcmd: pcache_stats |
||
6027 | */ |
||
6028 | static int test_pcache_stats( |
||
6029 | ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
||
6030 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
6031 | int objc, /* Number of arguments */ |
||
6032 | Tcl_Obj[] objv /* Command arguments */ |
||
6033 | ) |
||
6034 | { |
||
6035 | int nMin; |
||
6036 | int nMax; |
||
6037 | int nCurrent; |
||
6038 | int nRecyclable; |
||
6039 | Tcl_Obj pRet; |
||
6040 | |||
6041 | sqlite3PcacheStats( out nCurrent, out nMax, out nMin, out nRecyclable ); |
||
6042 | |||
6043 | pRet = TCL.Tcl_NewObj(); |
||
6044 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewStringObj( "current", -1 ) ); |
||
6045 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nCurrent ) ); |
||
6046 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewStringObj( "max", -1 ) ); |
||
6047 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nMax ) ); |
||
6048 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewStringObj( "min", -1 ) ); |
||
6049 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nMin ) ); |
||
6050 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewStringObj( "recyclable", -1 ) ); |
||
6051 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nRecyclable ) ); |
||
6052 | |||
6053 | TCL.Tcl_SetObjResult( interp, pRet ); |
||
6054 | |||
6055 | return TCL.TCL_OK; |
||
6056 | } |
||
6057 | |||
6058 | |||
6059 | |||
6060 | public class _aObjCmd |
||
6061 | { |
||
6062 | public string zName; |
||
6063 | public Interp.dxObjCmdProc xProc; |
||
6064 | public object clientData; |
||
6065 | public _aObjCmd( string zName, Interp.dxObjCmdProc xProc ) |
||
6066 | { |
||
6067 | this.zName = zName; |
||
6068 | this.xProc = xProc; |
||
6069 | this.clientData = null; |
||
6070 | } |
||
6071 | public _aObjCmd( string zName, Interp.dxObjCmdProc xProc, object clientdata ) |
||
6072 | { |
||
6073 | this.zName = zName; |
||
6074 | this.xProc = xProc; |
||
6075 | this.clientData = clientdata.GetType().Name == "Int32" && (int)clientdata == 0 ? null : clientdata; |
||
6076 | } |
||
6077 | } |
||
6078 | |||
6079 | #if SQLITE_ENABLE_UNLOCK_NOTIFY |
||
6080 | static void test_unlock_notify_cb(void **aArg, int nArg){ |
||
6081 | int ii; |
||
6082 | for(ii=0; ii<nArg; ii++){ |
||
6083 | TCL.Tcl_EvalEx((Tcl_Interp )aArg[ii], "unlock_notify", -1, TCL.TCL_EVAL_GLOBAL); |
||
6084 | } |
||
6085 | } |
||
6086 | #endif //* SQLITE_ENABLE_UNLOCK_NOTIFY */ |
||
6087 | |||
6088 | /* |
||
6089 | ** tclcmd: sqlite3_unlock_notify db |
||
6090 | */ |
||
6091 | #if SQLITE_ENABLE_UNLOCK_NOTIFY |
||
6092 | static int test_unlock_notify( |
||
6093 | ClientData clientData, /* Unused */ |
||
6094 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
6095 | int objc, /* Number of arguments */ |
||
6096 | Tcl_Obj[] objv /* Command arguments */ |
||
6097 | ){ |
||
6098 | sqlite3 db; |
||
6099 | int rc; |
||
6100 | |||
6101 | if( objc!=2 ){ |
||
6102 | TCL.Tcl_WrongNumArgs(interp, 1, objv, "DB"); |
||
6103 | return TCL.TCL_ERROR; |
||
6104 | } |
||
6105 | |||
6106 | if( getDbPointer(interp, TCL.Tcl_GetString(objv[1]), &db) ){ |
||
6107 | return TCL.TCL_ERROR; |
||
6108 | } |
||
6109 | rc = sqlite3_unlock_notify(db, test_unlock_notify_cb, (void )interp); |
||
6110 | TCL.Tcl_SetResult(interp, (char )t1ErrorName(rc), TCL.TCL_STATIC); |
||
6111 | return TCL.TCL_OK; |
||
6112 | } |
||
6113 | #endif |
||
6114 | |||
6115 | /* |
||
6116 | ** tclcmd: sqlite3_wal_checkpoint db ?NAME? |
||
6117 | */ |
||
6118 | static int test_wal_checkpoint( |
||
6119 | ClientData clientData, /* Unused */ |
||
6120 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
6121 | int objc, /* Number of arguments */ |
||
6122 | Tcl_Obj[] objv /* Command arguments */ |
||
6123 | ) |
||
6124 | { |
||
6125 | string zDb = ""; |
||
6126 | sqlite3 db = null; |
||
6127 | int rc; |
||
6128 | |||
6129 | if ( objc != 3 && objc != 2 ) |
||
6130 | { |
||
6131 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB ?NAME?" ); |
||
6132 | return TCL.TCL_ERROR; |
||
6133 | } |
||
6134 | |||
6135 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
6136 | { |
||
6137 | return TCL.TCL_ERROR; |
||
6138 | } |
||
6139 | if ( objc == 3 ) |
||
6140 | { |
||
6141 | zDb = TCL.Tcl_GetString( objv[2] ); |
||
6142 | } |
||
6143 | rc = sqlite3_wal_checkpoint( db, zDb ); |
||
6144 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC ); |
||
6145 | return TCL.TCL_OK; |
||
6146 | } |
||
6147 | |||
6148 | /* |
||
6149 | ** tclcmd: sqlite3_wal_checkpoint_v2 db MODE ?NAME? |
||
6150 | ** |
||
6151 | ** This command calls the wal_checkpoint_v2() function with the specified |
||
6152 | ** mode argument (passive, full or restart). If present, the database name |
||
6153 | ** NAME is passed as the second argument to wal_checkpoint_v2(). If it the |
||
6154 | ** NAME argument is not present, a NULL pointer is passed instead. |
||
6155 | ** |
||
6156 | ** If wal_checkpoint_v2() returns any value other than SQLITE_BUSY or |
||
6157 | ** SQLITE_OK, then this command returns TCL_ERROR. The Tcl result is set |
||
6158 | ** to the error message obtained from sqlite3_errmsg(). |
||
6159 | ** |
||
6160 | ** Otherwise, this command returns a list of three integers. The first integer |
||
6161 | ** is 1 if SQLITE_BUSY was returned, or 0 otherwise. The following two integers |
||
6162 | ** are the values returned via the output paramaters by wal_checkpoint_v2() - |
||
6163 | ** the number of frames in the log and the number of frames in the log |
||
6164 | ** that have been checkpointed. |
||
6165 | */ |
||
6166 | static int test_wal_checkpoint_v2( |
||
6167 | ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ |
||
6168 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
6169 | int objc, /* Number of arguments */ |
||
6170 | Tcl_Obj[] objv /* Command arguments */ |
||
6171 | ) |
||
6172 | { |
||
6173 | string zDb = ""; |
||
6174 | sqlite3 db = null; |
||
6175 | int rc; |
||
6176 | |||
6177 | int eMode = 0; |
||
6178 | int nLog = -555; |
||
6179 | int nCkpt = -555; |
||
6180 | Tcl_Obj pRet; |
||
6181 | |||
6182 | string[] aMode = new string[] { "passive", "full", "restart" }; |
||
6183 | Debug.Assert( SQLITE_CHECKPOINT_PASSIVE == 0 ); |
||
6184 | Debug.Assert( SQLITE_CHECKPOINT_FULL == 1 ); |
||
6185 | Debug.Assert( SQLITE_CHECKPOINT_RESTART == 2 ); |
||
6186 | |||
6187 | if ( objc != 3 && objc != 4 ) |
||
6188 | { |
||
6189 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB MODE ?NAME?" ); |
||
6190 | return TCL.TCL_ERROR; |
||
6191 | } |
||
6192 | |||
6193 | if ( objc == 4 ) |
||
6194 | { |
||
6195 | zDb = TCL.Tcl_GetString( objv[3] ); |
||
6196 | } |
||
6197 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 |
||
6198 | || TCL.Tcl_GetIndexFromObj( interp, objv[2], aMode, "mode", 0, out eMode ) |
||
6199 | ) |
||
6200 | { |
||
6201 | return TCL.TCL_ERROR; |
||
6202 | } |
||
6203 | |||
6204 | rc = sqlite3_wal_checkpoint_v2( db, zDb, eMode, out nLog, out nCkpt ); |
||
6205 | if ( rc != SQLITE_OK && rc != SQLITE_BUSY ) |
||
6206 | { |
||
6207 | TCL.Tcl_SetResult( interp, sqlite3_errmsg( db ), TCL.TCL_VOLATILE ); |
||
6208 | return TCL.TCL_ERROR; |
||
6209 | } |
||
6210 | |||
6211 | pRet = TCL.Tcl_NewObj(); |
||
6212 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( rc == SQLITE_BUSY ? 1 : 0 ) ); |
||
6213 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nLog ) ); |
||
6214 | TCL.Tcl_ListObjAppendElement( interp, pRet, TCL.Tcl_NewIntObj( nCkpt ) ); |
||
6215 | TCL.Tcl_SetObjResult( interp, pRet ); |
||
6216 | |||
6217 | return TCL.TCL_OK; |
||
6218 | } |
||
6219 | |||
6220 | /* |
||
6221 | ** tclcmd: test_sqlite3_log ?SCRIPT? |
||
6222 | */ |
||
6223 | struct LogCallback |
||
6224 | { |
||
6225 | public Tcl_Interp pInterp; |
||
6226 | public Tcl_Obj pObj; |
||
6227 | } |
||
6228 | static LogCallback logcallback = new LogCallback(); |
||
6229 | |||
6230 | static void xLogcallback( object unused, int err, string zMsg ) |
||
6231 | { |
||
6232 | Tcl_Obj pNew = TCL.Tcl_DuplicateObj( logcallback.pObj ); |
||
6233 | TCL.Tcl_IncrRefCount( pNew ); |
||
6234 | TCL.Tcl_ListObjAppendElement( |
||
6235 | null, pNew, TCL.Tcl_NewStringObj( sqlite3TestErrorName( err ), -1 ) |
||
6236 | ); |
||
6237 | TCL.Tcl_ListObjAppendElement( null, pNew, TCL.Tcl_NewStringObj( zMsg, -1 ) ); |
||
6238 | TCL.Tcl_EvalObjEx( logcallback.pInterp, pNew, TCL.TCL_EVAL_GLOBAL | TCL.TCL_EVAL_DIRECT ); |
||
6239 | TCL.Tcl_DecrRefCount( ref pNew ); |
||
6240 | } |
||
6241 | |||
6242 | static int test_sqlite3_log( |
||
6243 | ClientData clientData, |
||
6244 | Tcl_Interp interp, /* The TCL interpreter that invoked this command */ |
||
6245 | int objc, /* Number of arguments */ |
||
6246 | Tcl_Obj[] objv /* Command arguments */ |
||
6247 | ) |
||
6248 | { |
||
6249 | if ( objc > 2 ) |
||
6250 | { |
||
6251 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "SCRIPT" ); |
||
6252 | return TCL.TCL_ERROR; |
||
6253 | } |
||
6254 | if ( logcallback.pObj != null ) |
||
6255 | { |
||
6256 | TCL.Tcl_DecrRefCount( ref logcallback.pObj ); |
||
6257 | logcallback.pObj = null; |
||
6258 | logcallback.pInterp = null; |
||
6259 | sqlite3_config( SQLITE_CONFIG_LOG, 0, 0 ); |
||
6260 | } |
||
6261 | if ( objc > 1 ) |
||
6262 | { |
||
6263 | logcallback.pObj = objv[1]; |
||
6264 | TCL.Tcl_IncrRefCount( logcallback.pObj ); |
||
6265 | logcallback.pInterp = interp; |
||
6266 | sqlite3_config( SQLITE_CONFIG_LOG, (dxLogcallback)xLogcallback, 0 ); |
||
6267 | } |
||
6268 | return TCL.TCL_OK; |
||
6269 | } |
||
6270 | |||
6271 | |||
6272 | /* |
||
6273 | ** tcl_objproc COMMANDNAME ARGS... |
||
6274 | ** |
||
6275 | ** Run a TCL command using its objProc interface. Throw an error if |
||
6276 | ** the command has no objProc interface. |
||
6277 | */ |
||
6278 | //static int runAsObjProc( |
||
6279 | // void * clientData, |
||
6280 | // Tcl_Interp interp, |
||
6281 | // int objc, |
||
6282 | // Tcl_Obj[] objv |
||
6283 | //){ |
||
6284 | // TCL.Tcl_CmdInfo cmdInfo; |
||
6285 | // if( objc<2 ){ |
||
6286 | // TCL.Tcl_WrongNumArgs(interp, 1, objv, "COMMAND ..."); |
||
6287 | // return TCL.TCL_ERROR; |
||
6288 | // } |
||
6289 | // if( null==TCL.Tcl_GetCommandInfo(interp, TCL.Tcl_GetString(objv[1]), &cmdInfo) ){ |
||
6290 | // TCL.Tcl_AppendResult(interp, "command not found: ", |
||
6291 | // TCL.Tcl_GetString(objv[1]), (char)0); |
||
6292 | // return TCL.TCL_ERROR; |
||
6293 | // } |
||
6294 | // if( cmdInfo.objProc==0 ){ |
||
6295 | // TCL.Tcl_AppendResult(interp, "command has no objProc: ", |
||
6296 | // TCL.Tcl_GetString(objv[1]), (char)0); |
||
6297 | // return TCL.TCL_ERROR; |
||
6298 | // } |
||
6299 | // return cmdInfo.objProc(cmdInfo.objClientData, interp, objc-1, objv+1); |
||
6300 | //} |
||
6301 | |||
6302 | /* |
||
6303 | ** Register commands with the TCL interpreter. |
||
6304 | */ |
||
6305 | |||
6306 | #if !SQLITE_OMIT_EXPLAIN |
||
6307 | /* |
||
6308 | ** WARNING: The following function, printExplainQueryPlan() is an exact |
||
6309 | ** copy of example code from eqp.in (eqp.html). If this code is modified, |
||
6310 | ** then the documentation copy needs to be modified as well. |
||
6311 | */ |
||
6312 | /* |
||
6313 | ** Argument pStmt is a prepared SQL statement. This function compiles |
||
6314 | ** an EXPLAIN QUERY PLAN command to report on the prepared statement, |
||
6315 | ** and prints the report to stdout using printf(). |
||
6316 | */ |
||
6317 | static int printExplainQueryPlan( sqlite3_stmt pStmt ) |
||
6318 | { |
||
6319 | string zSql; /* Input SQL */ |
||
6320 | string zExplain; /* SQL with EXPLAIN QUERY PLAN prepended */ |
||
6321 | sqlite3_stmt pExplain = null; /* Compiled EXPLAIN QUERY PLAN command */ |
||
6322 | int rc; /* Return code from sqlite3_prepare_v2() */ |
||
6323 | |||
6324 | zSql = sqlite3_sql( pStmt ); |
||
6325 | if ( zSql == null ) |
||
6326 | return SQLITE_ERROR; |
||
6327 | |||
6328 | zExplain = sqlite3_mprintf( "EXPLAIN QUERY PLAN %s", zSql ); |
||
6329 | //if ( zExplain == null ) |
||
6330 | // return SQLITE_NOMEM; |
||
6331 | |||
6332 | rc = sqlite3_prepare_v2( sqlite3_db_handle( pStmt ), zExplain, -1, ref pExplain, 0 ); |
||
6333 | //sqlite3_free(zExplain); |
||
6334 | if ( rc != SQLITE_OK ) |
||
6335 | return rc; |
||
6336 | |||
6337 | while ( SQLITE_ROW == sqlite3_step( pExplain ) ) |
||
6338 | { |
||
6339 | int iSelectid = sqlite3_column_int( pExplain, 0 ); |
||
6340 | int iOrder = sqlite3_column_int( pExplain, 1 ); |
||
6341 | int iFrom = sqlite3_column_int( pExplain, 2 ); |
||
6342 | string zDetail = sqlite3_column_text( pExplain, 3 ); |
||
6343 | |||
6344 | printf( "%d %d %d %s\n", iSelectid, iOrder, iFrom, zDetail ); |
||
6345 | } |
||
6346 | |||
6347 | return sqlite3_finalize( pExplain ); |
||
6348 | } |
||
6349 | |||
6350 | static int test_print_eqp( |
||
6351 | object clientData, |
||
6352 | Tcl_Interp interp, |
||
6353 | int objc, |
||
6354 | Tcl_Obj[] objv |
||
6355 | ) |
||
6356 | { |
||
6357 | int rc; |
||
6358 | sqlite3_stmt pStmt = null; |
||
6359 | |||
6360 | if ( objc != 2 ) |
||
6361 | { |
||
6362 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "STMT" ); |
||
6363 | return TCL.TCL_ERROR; |
||
6364 | } |
||
6365 | if ( getStmtPointer( interp, TCL.Tcl_GetString( objv[1] ), out pStmt ) != 0 ) |
||
6366 | return TCL.TCL_ERROR; |
||
6367 | rc = printExplainQueryPlan( pStmt ); |
||
6368 | /* This is needed on Windows so that a test case using this |
||
6369 | ** function can open a read pipe and get the output of |
||
6370 | ** printExplainQueryPlan() immediately. |
||
6371 | */ |
||
6372 | //fflush( stdout ); |
||
6373 | TCL.Tcl_SetResult( interp, t1ErrorName( rc ), 0 ); |
||
6374 | return TCL.TCL_OK; |
||
6375 | } |
||
6376 | #endif //* SQLITE_OMIT_EXPLAIN */ |
||
6377 | |||
6378 | class Verb |
||
6379 | { |
||
6380 | public string zName; |
||
6381 | public int i; |
||
6382 | |||
6383 | public Verb( string zName, int i ) |
||
6384 | { |
||
6385 | this.zName = zName; |
||
6386 | this.i = i; |
||
6387 | } |
||
6388 | } |
||
6389 | |||
6390 | /* |
||
6391 | ** sqlite3_test_control VERB ARGS... |
||
6392 | */ |
||
6393 | static int test_test_control( |
||
6394 | object clientData, |
||
6395 | Tcl_Interp interp, |
||
6396 | int objc, |
||
6397 | Tcl_Obj[] objv |
||
6398 | ) |
||
6399 | { |
||
6400 | Verb[] aVerb = new Verb[] { |
||
6401 | new Verb( "SQLITE_TESTCTRL_LOCALTIME_FAULT", SQLITE_TESTCTRL_LOCALTIME_FAULT ), |
||
6402 | }; |
||
6403 | int iVerb; |
||
6404 | int iFlag; |
||
6405 | int rc; |
||
6406 | |||
6407 | if ( objc < 2 ) |
||
6408 | { |
||
6409 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "VERB ARGS..." ); |
||
6410 | return TCL.TCL_ERROR; |
||
6411 | } |
||
6412 | |||
6413 | //rc = TCL.Tcl_GetIndexFromObjStruct( |
||
6414 | // interp, objv[1], aVerb, sizeof(aVerb[0]), "VERB", 0, &iVerb |
||
6415 | //); |
||
6416 | for ( iVerb = 0; iVerb < aVerb.Length && ( aVerb[iVerb].zName != objv[1].ToString() ); iVerb++ ) |
||
6417 | { |
||
6418 | } |
||
6419 | if ( iVerb >= aVerb.Length ) |
||
6420 | return TCL.TCL_ERROR; |
||
6421 | |||
6422 | iFlag = aVerb[iVerb].i; |
||
6423 | switch ( iFlag ) |
||
6424 | { |
||
6425 | case SQLITE_TESTCTRL_LOCALTIME_FAULT: |
||
6426 | { |
||
6427 | bool val = false; |
||
6428 | if ( objc != 3 ) |
||
6429 | { |
||
6430 | TCL.Tcl_WrongNumArgs( interp, 2, objv, "ONOFF" ); |
||
6431 | return TCL.TCL_ERROR; |
||
6432 | } |
||
6433 | if ( TCL.Tcl_GetBooleanFromObj( interp, objv[2], out val ) ) |
||
6434 | return TCL.TCL_ERROR; |
||
6435 | sqlite3_test_control( SQLITE_TESTCTRL_LOCALTIME_FAULT, val ); |
||
6436 | break; |
||
6437 | } |
||
6438 | } |
||
6439 | |||
6440 | TCL.Tcl_ResetResult( interp ); |
||
6441 | return TCL.TCL_OK; |
||
6442 | } |
||
6443 | |||
6444 | /* |
||
6445 | ** optimization_control DB OPT BOOLEAN |
||
6446 | ** |
||
6447 | ** Enable or disable query optimizations using the sqlite3_test_control() |
||
6448 | ** interface. Disable if BOOLEAN is false and enable if BOOLEAN is true. |
||
6449 | ** OPT is the name of the optimization to be disabled. |
||
6450 | */ |
||
6451 | public class _aOpt |
||
6452 | { |
||
6453 | public string zOptName; |
||
6454 | public int mask; |
||
6455 | |||
6456 | public _aOpt( string zOptName, int mask ) |
||
6457 | { |
||
6458 | this.zOptName = zOptName; |
||
6459 | this.mask = mask; |
||
6460 | } |
||
6461 | } |
||
6462 | |||
6463 | static int optimization_control( |
||
6464 | object clientData, |
||
6465 | Tcl_Interp interp, |
||
6466 | int objc, |
||
6467 | Tcl_Obj[] objv |
||
6468 | ) |
||
6469 | { |
||
6470 | int i; |
||
6471 | sqlite3 db = null; |
||
6472 | string zOpt; |
||
6473 | bool onoff = false; |
||
6474 | int mask = 0; |
||
6475 | _aOpt[] aOpt = { |
||
6476 | new _aOpt( "all", SQLITE_OptMask ), |
||
6477 | new _aOpt( "query-flattener", SQLITE_QueryFlattener ), |
||
6478 | new _aOpt( "column-cache", SQLITE_ColumnCache ), |
||
6479 | new _aOpt( "index-sort", SQLITE_IndexSort ), |
||
6480 | new _aOpt( "index-search", SQLITE_IndexSearch ), |
||
6481 | new _aOpt( "index-cover", SQLITE_IndexCover ), |
||
6482 | new _aOpt( "groupby-order", SQLITE_GroupByOrder ), |
||
6483 | new _aOpt( "factor-constants", SQLITE_FactorOutConst ), |
||
6484 | new _aOpt( "real-as-int", SQLITE_IdxRealAsInt ), |
||
6485 | }; |
||
6486 | |||
6487 | if ( objc != 4 ) |
||
6488 | { |
||
6489 | TCL.Tcl_WrongNumArgs( interp, 1, objv, "DB OPT BOOLEAN" ); |
||
6490 | return TCL.TCL_ERROR; |
||
6491 | } |
||
6492 | if ( getDbPointer( interp, TCL.Tcl_GetString( objv[1] ), out db ) != 0 ) |
||
6493 | return TCL.TCL_ERROR; |
||
6494 | if ( TCL.Tcl_GetBooleanFromObj( interp, objv[3], out onoff ) ) |
||
6495 | return TCL.TCL_ERROR; |
||
6496 | zOpt = TCL.Tcl_GetString( objv[2] ); |
||
6497 | for ( i = 0; i < aOpt.Length; i++ )//sizeof(aOpt)/sizeof(aOpt[0]); i++) |
||
6498 | { |
||
6499 | if ( zOpt == aOpt[i].zOptName ) |
||
6500 | { |
||
6501 | mask = aOpt[i].mask; |
||
6502 | break; |
||
6503 | } |
||
6504 | } |
||
6505 | if ( onoff ) |
||
6506 | mask = ~mask; |
||
6507 | if ( i >= aOpt.Length )//sizeof(aOpt)/sizeof(aOpt[0]) ) |
||
6508 | { |
||
6509 | TCL.Tcl_AppendResult( interp, "unknown optimization - should be one of:", |
||
6510 | null ); |
||
6511 | for ( i = 0; i < aOpt.Length; i++ )//sizeof(aOpt)/sizeof(aOpt[0]); i++) |
||
6512 | { |
||
6513 | TCL.Tcl_AppendResult( interp, " ", aOpt[i].zOptName ); |
||
6514 | } |
||
6515 | return TCL.TCL_ERROR; |
||
6516 | } |
||
6517 | sqlite3_test_control( SQLITE_TESTCTRL_OPTIMIZATIONS, db, mask ); |
||
6518 | return TCL.TCL_OK; |
||
6519 | } |
||
6520 | |||
6521 | |||
6522 | static Var.SQLITE3_GETSET bitmask_size = new Var.SQLITE3_GETSET( "bitmask_size" ); |
||
6523 | |||
6524 | #if SQLITE_OS_UNIX && (__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE |
||
6525 | extern int sqlite3_hostid_num; |
||
6526 | #endif |
||
6527 | static Var.SQLITE3_GETSET sqlite_static_bind_nbyte = new Var.SQLITE3_GETSET( "static_bind_nbyte" ); |
||
6528 | static Var.SQLITE3_GETSET sqlite_static_bind_value = new Var.SQLITE3_GETSET( "static_bind_value" ); |
||
6529 | |||
6530 | public static int Sqlitetest1_Init( Tcl_Interp interp ) |
||
6531 | { |
||
6532 | // extern int sqlite3_search_count; |
||
6533 | // extern int sqlite3_found_count; |
||
6534 | // extern int sqlite3_interrupt_count; |
||
6535 | // extern int sqlite3_sort_count; |
||
6536 | // extern int sqlite3_current_time; |
||
6537 | // extern int sqlite3_max_blobsize; |
||
6538 | // extern int sqlite3BtreeSharedCacheReport(void*, |
||
6539 | // Tcl_Interp *,int,Tcl_Obj*CONST); |
||
6540 | // static struct { |
||
6541 | // string zName; |
||
6542 | // TCL.Tcl_CmdProc *xProc; |
||
6543 | _aCmd[] aCmd = new _aCmd[] { |
||
6544 | new _aCmd( "db_enter", db_enter ), |
||
6545 | new _aCmd( "db_leave", db_leave ), |
||
6546 | new _aCmd( "sqlite3_mprintf_int", sqlite3_mprintf_int ), |
||
6547 | new _aCmd( "sqlite3_mprintf_int64", sqlite3_mprintf_int64 ), |
||
6548 | new _aCmd( "sqlite3_mprintf_long", sqlite3_mprintf_long ), |
||
6549 | new _aCmd( "sqlite3_mprintf_str", sqlite3_mprintf_str ), |
||
6550 | new _aCmd( "sqlite3_snprintf_str", sqlite3_snprintf_str ), |
||
6551 | new _aCmd( "sqlite3_mprintf_stronly", sqlite3_mprintf_stronly), |
||
6552 | new _aCmd( "sqlite3_mprintf_double", sqlite3_mprintf_double ), |
||
6553 | new _aCmd( "sqlite3_mprintf_scaled", sqlite3_mprintf_scaled ), |
||
6554 | new _aCmd( "sqlite3_mprintf_hexdouble", sqlite3_mprintf_hexdouble), |
||
6555 | new _aCmd( "sqlite3_mprintf_z_test", test_mprintf_z ), |
||
6556 | new _aCmd( "sqlite3_mprintf_n_test", test_mprintf_n ), |
||
6557 | new _aCmd( "sqlite3_snprintf_int", test_snprintf_int ), |
||
6558 | // new _aCmd( "sqlite3_last_insert_rowid", test_last_rowid ), |
||
6559 | new _aCmd( "sqlite3_exec_printf", test_exec_printf ), |
||
6560 | new _aCmd( "sqlite3_exec_hex", test_exec_hex ), |
||
6561 | new _aCmd( "sqlite3_exec", test_exec ), |
||
6562 | new _aCmd( "sqlite3_exec_nr", test_exec_nr ), |
||
6563 | #if !SQLITE_OMIT_GET_TABLE |
||
6564 | new _aCmd( "sqlite3_get_table_printf", test_get_table_printf ), |
||
6565 | #endif |
||
6566 | new _aCmd( "sqlite3_close", sqlite_test_close ), |
||
6567 | new _aCmd( "sqlite3_create_function", test_create_function ), |
||
6568 | new _aCmd( "sqlite3_create_aggregate", test_create_aggregate ), |
||
6569 | new _aCmd( "sqlite_register_test_function", test_register_func ), |
||
6570 | // new _aCmd( "sqlite_abort", sqlite_abort ), |
||
6571 | new _aCmd( "sqlite_bind", test_bind ), |
||
6572 | new _aCmd( "breakpoint", test_breakpoint ), |
||
6573 | new _aCmd( "sqlite3_key", test_key ), |
||
6574 | new _aCmd( "sqlite3_rekey", test_rekey ), |
||
6575 | new _aCmd( "sqlite_set_magic", sqlite_set_magic ), |
||
6576 | new _aCmd( "sqlite3_interrupt", test_interrupt ), |
||
6577 | new _aCmd( "sqlite_delete_function", delete_function ), |
||
6578 | new _aCmd( "sqlite_delete_collation", delete_collation ), |
||
6579 | new _aCmd( "sqlite3_get_autocommit", get_autocommit ), |
||
6580 | // new _aCmd( "sqlite3_stack_used", test_stack_used ), |
||
6581 | new _aCmd( "sqlite3_busy_timeout", test_busy_timeout ), |
||
6582 | // new _aCmd( "printf", test_printf ), |
||
6583 | // new _aCmd( "sqlite3IoTrace", test_io_trace ), |
||
6584 | }; |
||
6585 | // static struct { |
||
6586 | // string zName; |
||
6587 | // Tcl_ObjCmdProc *xProc; |
||
6588 | // void *object; |
||
6589 | _aObjCmd[] aObjCmd = new _aObjCmd[]{ |
||
6590 | new _aObjCmd( "sqlite3_connection_pointer", get_sqlite_pointer, 0 ), |
||
6591 | new _aObjCmd( "sqlite3_bind_int", test_bind_int, 0 ), |
||
6592 | new _aObjCmd( "sqlite3_bind_zeroblob", test_bind_zeroblob, 0 ), |
||
6593 | new _aObjCmd( "sqlite3_bind_int64", test_bind_int64, 0 ), |
||
6594 | new _aObjCmd( "sqlite3_bind_double", test_bind_double, 0 ), |
||
6595 | new _aObjCmd( "sqlite3_bind_null", test_bind_null ,0 ), |
||
6596 | new _aObjCmd( "sqlite3_bind_text", test_bind_text ,0 ), |
||
6597 | new _aObjCmd( "sqlite3_bind_text16", test_bind_text16 ,0 ), |
||
6598 | new _aObjCmd( "sqlite3_bind_blob", test_bind_blob ,0 ), |
||
6599 | new _aObjCmd( "sqlite3_bind_parameter_count", test_bind_parameter_count, 0), |
||
6600 | new _aObjCmd( "sqlite3_bind_parameter_name", test_bind_parameter_name, 0), |
||
6601 | new _aObjCmd( "sqlite3_bind_parameter_index", test_bind_parameter_index, 0), |
||
6602 | new _aObjCmd( "sqlite3_clear_bindings", test_clear_bindings, 0), |
||
6603 | new _aObjCmd( "sqlite3_sleep", test_sleep, 0), |
||
6604 | new _aObjCmd( "sqlite3_errcode", test_errcode ,0 ), |
||
6605 | new _aObjCmd( "sqlite3_extended_errcode", test_ex_errcode ,0 ), |
||
6606 | new _aObjCmd( "sqlite3_errmsg", test_errmsg ,0 ), |
||
6607 | // new _aObjCmd( "sqlite3_errmsg16", test_errmsg16 ,0 ), |
||
6608 | new _aObjCmd( "sqlite3_open", test_open ,0 ), |
||
6609 | // new _aObjCmd( "sqlite3_open16", test_open16 ,0 ), |
||
6610 | new _aObjCmd( "sqlite3_open_v2", test_open_v2 ,0 ), |
||
6611 | // new _aObjCmd( "sqlite3_complete16", test_complete16 ,0 ), |
||
6612 | |||
6613 | new _aObjCmd( "sqlite3_prepare", test_prepare ,0 ), |
||
6614 | new _aObjCmd( "sqlite3_prepare16", test_prepare16 ,0 ), |
||
6615 | new _aObjCmd( "sqlite3_prepare_v2", test_prepare_v2 ,0 ), |
||
6616 | new _aObjCmd( "sqlite3_prepare_tkt3134", test_prepare_tkt3134, 0), |
||
6617 | // new _aObjCmd( "sqlite3_prepare16_v2", test_prepare16_v2 ,0 ), |
||
6618 | new _aObjCmd( "sqlite3_finalize", test_finalize ,0 ), |
||
6619 | new _aObjCmd( "sqlite3_reset", test_reset ,0 ), |
||
6620 | new _aObjCmd( "sqlite3_expired", test_expired ,0 ), |
||
6621 | new _aObjCmd( "sqlite3_transfer_bindings", test_transfer_bind ,0 ), |
||
6622 | new _aObjCmd( "sqlite3_changes", test_changes ,0 ), |
||
6623 | new _aObjCmd( "sqlite3_step", test_step ,0 ), |
||
6624 | // { "sqlite3_sql", test_sql ,0 }, |
||
6625 | new _aObjCmd( "sqlite3_next_stmt", test_next_stmt ,0 ), |
||
6626 | new _aObjCmd( "sqlite3_stmt_readonly", test_stmt_readonly ,0 ), |
||
6627 | new _aObjCmd( "uses_stmt_journal", uses_stmt_journal ,0 ), |
||
6628 | |||
6629 | new _aObjCmd( "sqlite3_release_memory", test_release_memory, 0), |
||
6630 | new _aObjCmd( "sqlite3_soft_heap_limit", test_soft_heap_limit, 0), |
||
6631 | // new _aObjCmd( "sqlite3_thread_cleanup", test_thread_cleanup, 0), |
||
6632 | // new _aObjCmd( "sqlite3_pager_refcounts", test_pager_refcounts, 0), |
||
6633 | |||
6634 | // new _aObjCmd( "sqlite3_load_extension", test_load_extension, 0), |
||
6635 | // new _aObjCmd( "sqlite3_enable_load_extension", test_enable_load, 0), |
||
6636 | new _aObjCmd( "sqlite3_extended_result_codes", test_extended_result_codes, 0), |
||
6637 | new _aObjCmd( "sqlite3_limit", test_limit, 0), |
||
6638 | |||
6639 | new _aObjCmd( "save_prng_state", save_prng_state, 0 ), |
||
6640 | new _aObjCmd( "restore_prng_state", restore_prng_state, 0 ), |
||
6641 | new _aObjCmd( "reset_prng_state", reset_prng_state, 0 ), |
||
6642 | new _aObjCmd( "optimization_control", optimization_control,0), |
||
6643 | // { "tcl_objproc", runAsObjProc, 0 }, |
||
6644 | |||
6645 | // /* sqlite3_column_*() API */ |
||
6646 | new _aObjCmd( "sqlite3_column_count", test_column_count ,0 ), |
||
6647 | new _aObjCmd( "sqlite3_data_count", test_data_count ,0 ), |
||
6648 | new _aObjCmd( "sqlite3_column_type", test_column_type ,0 ), |
||
6649 | new _aObjCmd( "sqlite3_column_blob", test_column_blob ,0 ), |
||
6650 | new _aObjCmd( "sqlite3_column_double", test_column_double ,0 ), |
||
6651 | new _aObjCmd( "sqlite3_column_int64", test_column_int64 ,0 ), |
||
6652 | new _aObjCmd( "sqlite3_column_text", test_stmt_utf8, (dxColumn)sqlite3_column_text ), |
||
6653 | new _aObjCmd( "sqlite3_column_name", test_stmt_utf8, (dxColumn)sqlite3_column_name ), |
||
6654 | new _aObjCmd( "sqlite3_column_int", test_stmt_int, (dxColumn_I)sqlite3_column_int ), |
||
6655 | new _aObjCmd( "sqlite3_column_bytes", test_stmt_int, (dxColumn_I)sqlite3_column_bytes ), |
||
6656 | #if !SQLITE_OMIT_DECLTYPE |
||
6657 | new _aObjCmd( "sqlite3_column_decltype", test_stmt_utf8, (dxColumn) sqlite3_column_decltype ), |
||
6658 | #endif |
||
6659 | #if SQLITE_ENABLE_COLUMN_METADATA |
||
6660 | new _aObjCmd( "sqlite3_column_database_name", test_stmt_utf8, (dxColumn)sqlite3_column_database_name), |
||
6661 | new _aObjCmd( "sqlite3_column_table_name", test_stmt_utf8, (dxColumn)sqlite3_column_table_name), |
||
6662 | new _aObjCmd( "sqlite3_column_origin_name", test_stmt_utf8, (dxColumn)sqlite3_column_origin_name), |
||
6663 | #endif |
||
6664 | |||
6665 | #if !SQLITE_OMIT_UTF16 |
||
6666 | // { "sqlite3_column_bytes16", test_stmt_int, sqlite3_column_bytes16 ), |
||
6667 | // { "sqlite3_column_text16", test_stmt_utf16, sqlite3_column_text16 ), |
||
6668 | // { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16), |
||
6669 | // { "sqlite3_column_name16", test_stmt_utf16, sqlite3_column_name16 ), |
||
6670 | // { "add_alignment_test_collations", add_alignment_test_collations, 0 ), |
||
6671 | #if SQLITE_ENABLE_COLUMN_METADATA |
||
6672 | //{"sqlite3_column_database_name16", |
||
6673 | // test_stmt_utf16, sqlite3_column_database_name16), |
||
6674 | //{"sqlite3_column_table_name16", test_stmt_utf16, sqlite3_column_table_name16), |
||
6675 | //{"sqlite3_column_origin_name16", test_stmt_utf16, sqlite3_column_origin_name16), |
||
6676 | #endif |
||
6677 | #endif |
||
6678 | new _aObjCmd( "sqlite3_create_collation_v2", test_create_collation_v2, 0 ), |
||
6679 | new _aObjCmd( "sqlite3_global_recover", test_global_recover, 0 ), |
||
6680 | new _aObjCmd( "working_64bit_int", working_64bit_int, 0 ), |
||
6681 | new _aObjCmd( "vfs_unlink_test", vfs_unlink_test, 0 ), |
||
6682 | //{ "vfs_initfail_test", vfs_initfail_test, 0 }, |
||
6683 | new _aObjCmd( "vfs_unregister_all", vfs_unregister_all, 0 ), |
||
6684 | new _aObjCmd("vfs_reregister_all", vfs_reregister_all, 0 ), |
||
6685 | new _aObjCmd( "file_control_test", file_control_test, 0 ), |
||
6686 | new _aObjCmd("file_control_lasterrno_test", file_control_lasterrno_test, 0 ), |
||
6687 | new _aObjCmd("file_control_lockproxy_test", file_control_lockproxy_test, 0 ), |
||
6688 | new _aObjCmd("file_control_chunksize_test", file_control_chunksize_test, 0 ), |
||
6689 | new _aObjCmd("file_control_sizehint_test", file_control_sizehint_test, 0), |
||
6690 | //new _aObjCmd( "sqlite3_vfs_list", vfs_list, 0 ), |
||
6691 | new _aObjCmd( "sqlite3_create_function_v2", test_create_function_v2, 0 ), |
||
6692 | |||
6693 | // /* Functions from os.h */ |
||
6694 | #if !SQLITE_OMIT_UTF16 |
||
6695 | // { "add_test_collate", test_collate, 0 ), |
||
6696 | // { "add_test_collate_needed", test_collate_needed, 0 ), |
||
6697 | // { "add_test_function", test_function, 0 ), |
||
6698 | #endif |
||
6699 | new _aObjCmd( "sqlite3_test_errstr", test_errstr, 0 ), |
||
6700 | new _aObjCmd( "tcl_variable_type", tcl_variable_type, 0 ), |
||
6701 | #if !SQLITE_OMIT_SHARED_CACHE |
||
6702 | new _aObjCmd( "sqlite3_enable_shared_cache", test_enable_shared, 0 ), |
||
6703 | //{ "sqlite3_shared_cache_report", sqlite3BtreeSharedCacheReport, 0), |
||
6704 | #endif |
||
6705 | new _aObjCmd( "sqlite3_libversion_number", test_libversion_number, 0 ), |
||
6706 | #if SQLITE_ENABLE_COLUMN_METADATA |
||
6707 | new _aObjCmd( "sqlite3_table_column_metadata", test_table_column_metadata, 0 ), |
||
6708 | #endif |
||
6709 | #if !SQLITE_OMIT_INCRBLOB |
||
6710 | // new _aObjCmd( "sqlite3_blob_read", test_blob_read, 0 ), |
||
6711 | // new _aObjCmd( "sqlite3_blob_write", test_blob_write, 0 ), |
||
6712 | //{ "sqlite3_blob_reopen", test_blob_reopen, 0 }, |
||
6713 | //{ "sqlite3_blob_bytes", test_blob_bytes, 0 }, |
||
6714 | //{ "sqlite3_blob_close", test_blob_close, 0 }, |
||
6715 | #endif |
||
6716 | new _aObjCmd( "pcache_stats", test_pcache_stats, 0 ), |
||
6717 | #if SQLITE_ENABLE_UNLOCK_NOTIFY |
||
6718 | { "sqlite3_unlock_notify", test_unlock_notify, 0 }, |
||
6719 | #endif |
||
6720 | new _aObjCmd( "sqlite3_wal_checkpoint", test_wal_checkpoint, 0 ), |
||
6721 | new _aObjCmd( "sqlite3_wal_checkpoint_v2", test_wal_checkpoint_v2, 0 ), |
||
6722 | new _aObjCmd( "test_sqlite3_log", test_sqlite3_log, 0 ), |
||
6723 | #if !SQLITE_OMIT_EXPLAIN |
||
6724 | new _aObjCmd( "print_explain_query_plan", test_print_eqp, 0 ), |
||
6725 | #endif |
||
6726 | new _aObjCmd( "sqlite3_test_control", test_test_control ), |
||
6727 | }; |
||
6728 | bitmask_size.iValue = BMS; |
||
6729 | int i; |
||
6730 | // extern int sqlite3_sync_count, sqlite3_fullsync_count; |
||
6731 | // extern int sqlite3_opentemp_count; |
||
6732 | // extern int sqlite3_like_count; |
||
6733 | // extern int sqlite3_xferopt_count; |
||
6734 | // extern int sqlite3_pager_readdb_count; |
||
6735 | // extern int sqlite3_pager_writedb_count; |
||
6736 | // extern int sqlite3_pager_writej_count; |
||
6737 | #if SQLITE_OS_WIN |
||
6738 | // extern int sqlite3_os_type; |
||
6739 | #endif |
||
6740 | #if SQLITE_DEBUG |
||
6741 | // extern int sqlite3WhereTrace; |
||
6742 | // extern int sqlite3OSTrace; |
||
6743 | // extern int sqlite3VdbeAddopTrace; |
||
6744 | // extern int sqlite3WalTrace; |
||
6745 | #endif |
||
6746 | #if SQLITE_TEST |
||
6747 | // extern char sqlite3_query_plan[]; |
||
6748 | // static char *query_plan = sqlite3_query_plan; |
||
6749 | #if SQLITE_ENABLE_FTS3 |
||
6750 | extern int sqlite3_fts3_enable_parentheses; |
||
6751 | #endif |
||
6752 | #endif |
||
6753 | |||
6754 | for ( i = 0; i < aCmd.Length; i++ ) |
||
6755 | {//sizeof(aCmd)/sizeof(aCmd[0]); i++){ |
||
6756 | TCL.Tcl_CreateCommand( interp, aCmd[i].zName, aCmd[i].xProc, null, null ); |
||
6757 | } |
||
6758 | for ( i = 0; i < aObjCmd.Length; i++ ) |
||
6759 | {// i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ |
||
6760 | TCL.Tcl_CreateObjCommand( interp, aObjCmd[i].zName, |
||
6761 | (Interp.dxObjCmdProc)aObjCmd[i].xProc, (object)aObjCmd[i].clientData, null ); |
||
6762 | } |
||
6763 | TCL.Tcl_LinkVar( interp, "sqlite_search_count", |
||
6764 | sqlite3_search_count, VarFlags.SQLITE3_LINK_INT ); |
||
6765 | TCL.Tcl_LinkVar( interp, "sqlite_found_count", |
||
6766 | sqlite3_found_count, VarFlags.SQLITE3_LINK_INT ); |
||
6767 | TCL.Tcl_LinkVar( interp, "sqlite_sort_count", |
||
6768 | sqlite3_sort_count, VarFlags.SQLITE3_LINK_INT ); |
||
6769 | TCL.Tcl_LinkVar( interp, "sqlite3_max_blobsize", |
||
6770 | sqlite3_max_blobsize, VarFlags.SQLITE3_LINK_INT ); |
||
6771 | TCL.Tcl_LinkVar( interp, "sqlite_like_count", |
||
6772 | sqlite3_like_count, VarFlags.SQLITE3_LINK_INT ); |
||
6773 | TCL.Tcl_LinkVar( interp, "sqlite_interrupt_count", |
||
6774 | sqlite3_interrupt_count, VarFlags.SQLITE3_LINK_INT ); |
||
6775 | TCL.Tcl_LinkVar( interp, "sqlite_open_file_count", |
||
6776 | sqlite3_open_file_count, VarFlags.SQLITE3_LINK_INT ); |
||
6777 | TCL.Tcl_LinkVar( interp, "sqlite_current_time", |
||
6778 | sqlite3_current_time, VarFlags.SQLITE3_LINK_INT ); |
||
6779 | #if SQLITE_OS_UNIX && (__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE |
||
6780 | TCL.Tcl_LinkVar(interp, "sqlite_hostid_num", |
||
6781 | (char)&sqlite3_hostid_num, TCL.Tcl_LINK_INT); |
||
6782 | #endif |
||
6783 | TCL.Tcl_LinkVar( interp, "sqlite3_xferopt_count", |
||
6784 | sqlite3_xferopt_count, VarFlags.SQLITE3_LINK_INT ); |
||
6785 | TCL.Tcl_LinkVar( interp, "sqlite3_pager_readdb_count", |
||
6786 | sqlite3_pager_readdb_count, VarFlags.SQLITE3_LINK_INT ); |
||
6787 | TCL.Tcl_LinkVar( interp, "sqlite3_pager_writedb_count", |
||
6788 | sqlite3_pager_writedb_count, VarFlags.SQLITE3_LINK_INT ); |
||
6789 | TCL.Tcl_LinkVar( interp, "sqlite3_pager_writej_count", |
||
6790 | sqlite3_pager_writej_count, VarFlags.SQLITE3_LINK_INT ); |
||
6791 | #if !SQLITE_OMIT_UTF16 |
||
6792 | // TCL.Tcl_LinkVar(interp, "unaligned_string_counter", |
||
6793 | // (char)&unaligned_string_counter, VarFlag.SQLITE3_LINK_INT); |
||
6794 | #endif |
||
6795 | #if !SQLITE_OMIT_UTF16 |
||
6796 | // TCL.Tcl_LinkVar(interp, "sqlite_last_needed_collation", |
||
6797 | // (char)&pzNeededCollation, VarFlag.TCL_LINK_STRING|VarFlag.TCL_LINK_READ_ONLY); |
||
6798 | #endif |
||
6799 | #if SQLITE_OS_WIN |
||
6800 | // TCL.Tcl_LinkVar(interp, "sqlite_os_type", |
||
6801 | // (char)&sqlite3_os_type, VarFlag.SQLITE3_LINK_INT); |
||
6802 | #endif |
||
6803 | #if SQLITE_TEST |
||
6804 | TCL.Tcl_LinkVar( interp, "sqlite_query_plan", |
||
6805 | sqlite3_query_plan, VarFlags.SQLITE3_LINK_STRING | VarFlags.SQLITE3_LINK_READ_ONLY ); |
||
6806 | #endif |
||
6807 | #if SQLITE_DEBUG |
||
6808 | // TCL.Tcl_LinkVar(interp, "sqlite_addop_trace", |
||
6809 | // (char)&sqlite3VdbeAddopTrace, VarFlag.SQLITE3_LINK_INT); |
||
6810 | // TCL.Tcl_LinkVar(interp, "sqlite_where_trace", |
||
6811 | // (char)&sqlite3WhereTrace, VarFlag.SQLITE3_LINK_INT); |
||
6812 | // TCL.Tcl_LinkVar(interp, "sqlite_os_trace", |
||
6813 | // (char)&sqlite3OSTrace, VarFlag.SQLITE3_LINK_INT); |
||
6814 | #if !SQLITE_OMIT_WAL |
||
6815 | TCL.Tcl_LinkVar((interp, "sqlite_wal_trace", |
||
6816 | (char)&sqlite3WalTrace, VarFlag.SQLITE3_LINK_INT); |
||
6817 | #endif |
||
6818 | #endif |
||
6819 | #if !SQLITE_OMIT_DISKIO |
||
6820 | TCL.Tcl_LinkVar( interp, "sqlite_opentemp_count", |
||
6821 | sqlite3_opentemp_count, VarFlags.SQLITE3_LINK_INT ); |
||
6822 | #endif |
||
6823 | TCL.Tcl_LinkVar( interp, "sqlite_static_bind_value", |
||
6824 | sqlite_static_bind_value, VarFlags.SQLITE3_LINK_STRING ); |
||
6825 | TCL.Tcl_LinkVar( interp, "sqlite_static_bind_nbyte", |
||
6826 | sqlite_static_bind_nbyte, VarFlags.SQLITE3_LINK_INT ); |
||
6827 | // TCL.Tcl_LinkVar(interp, "sqlite_temp_directory", |
||
6828 | // (char)&sqlite3_temp_directory, VarFlag.TCL_LINK_STRING); |
||
6829 | TCL.Tcl_LinkVar( interp, "bitmask_size", |
||
6830 | bitmask_size, VarFlags.SQLITE3_LINK_INT | VarFlags.SQLITE3_LINK_READ_ONLY ); |
||
6831 | TCL.Tcl_LinkVar( interp, "sqlite_sync_count", |
||
6832 | sqlite3_sync_count, VarFlags.SQLITE3_LINK_INT ); |
||
6833 | TCL.Tcl_LinkVar( interp, "sqlite_fullsync_count", |
||
6834 | sqlite3_fullsync_count, VarFlags.SQLITE3_LINK_INT ); |
||
6835 | #if (SQLITE_ENABLE_FTS3) && (SQLITE_TEST) |
||
6836 | TCL.Tcl_LinkVar(interp, "sqlite_fts3_enable_parentheses", |
||
6837 | (char)&sqlite3_fts3_enable_parentheses, TCL.Tcl_LINK_INT); |
||
6838 | #endif |
||
6839 | return TCL.TCL_OK; |
||
6840 | } |
||
6841 | } |
||
6842 | #endif |
||
6843 | } |