PageRenderTime 56ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 1ms

/testfixture/src/test1_c.cs

https://bitbucket.org/eumario/csharp-sqlite
C# | 6843 lines | 4352 code | 479 blank | 2012 comment | 946 complexity | bf9b03885ff23f6ac2f249711e2306e7 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. using System;
  2. using System.Diagnostics;
  3. using System.Text;
  4. using i64 = System.Int64;
  5. using u32 = System.UInt32;
  6. namespace Community.CsharpSqlite
  7. {
  8. #if TCLSH
  9. using tcl.lang;
  10. using ClientData = System.Object;
  11. using sqlite3_int64 = System.Int64;
  12. using sqlite3_stmt = Sqlite3.Vdbe;
  13. using sqlite3_u3264 = System.UInt64;
  14. using sqlite3_value = Sqlite3.Mem;
  15. using Tcl_Interp = tcl.lang.Interp;
  16. using Tcl_Obj = tcl.lang.TclObject;
  17. public partial class Sqlite3
  18. {
  19. /*
  20. ** 2001 September 15
  21. **
  22. ** The author disclaims copyright to this source code. In place of
  23. ** a legal notice, here is a blessing:
  24. **
  25. ** May you do good and not evil.
  26. ** May you find forgiveness for yourself and forgive others.
  27. ** May you share freely, never taking more than you give.
  28. **
  29. *************************************************************************
  30. ** Code for testing all sorts of SQLite interfaces. This code
  31. ** is not included in the SQLite library. It is used for automated
  32. ** testing of the SQLite library.
  33. *************************************************************************
  34. ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
  35. ** C#-SQLite is an independent reimplementation of the SQLite software library
  36. **
  37. ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2
  38. **
  39. *************************************************************************
  40. */
  41. //#include "sqliteInt.h"
  42. //#include "tcl.h"
  43. //#include <stdlib.h>
  44. //#include <string.h>
  45. /*
  46. ** This is a copy of the first part of the SqliteDb structure in
  47. ** tclsqlite.c. We need it here so that the get_sqlite_pointer routine
  48. ** can extract the sqlite3* pointer from an existing Tcl SQLite
  49. ** connection.
  50. */
  51. //struct SqliteDb {
  52. // sqlite3 db=null;
  53. //};
  54. /*
  55. ** Convert text generated by the "%p" conversion format back into
  56. ** a pointer.
  57. */
  58. static int testHexToInt( int h )
  59. {
  60. if ( h >= '0' && h <= '9' )
  61. {
  62. return h - '0';
  63. }
  64. else if ( h >= 'a' && h <= 'f' )
  65. {
  66. return h - 'a' + 10;
  67. }
  68. else
  69. {
  70. Debug.Assert( h >= 'A' && h <= 'F' );
  71. return h - 'A' + 10;
  72. }
  73. }
  74. static object sqlite3TestTextToPtr( Tcl_Interp interp, string z )
  75. {
  76. //object p ;
  77. //var v = new u64[1];
  78. //u32 v2;
  79. //int zIndex = 0;
  80. //if ( z[0] == '0' && z[1] == 'x' )
  81. //{
  82. // zIndex += 2;
  83. //}
  84. //v[0] = 0;
  85. //while ( zIndex < z.Length )* z )
  86. //{
  87. // v[0] = ( v[0] << 4 ) + (ulong)testHexToInt( z[zIndex] );
  88. // zIndex++;
  89. //}
  90. //if ( sizeof( object ) == sizeof( u64 ) )
  91. //{
  92. // Marshal.Copy( v, 0, (IntPtr)p, 1 );// memcpy( &p, v, sizeof( p ) );
  93. //}
  94. //else
  95. //{
  96. // Debug.Assert( sizeof( p ) == sizeof( v2 ) );
  97. // v2 = (u32)v;
  98. // memcpy( &p, v2, sizeof( p ) );
  99. //}
  100. WrappedCommand cmdInfo = new WrappedCommand();
  101. if ( TCL.Tcl_GetCommandInfo( interp, z, out cmdInfo ) || cmdInfo == null )
  102. {
  103. return null;
  104. }
  105. else
  106. {
  107. return cmdInfo.objClientData;
  108. }
  109. }
  110. /*
  111. ** A TCL command that returns the address of the sqlite* pointer
  112. ** for an sqlite connection instance. Bad things happen if the
  113. ** input is not an sqlite connection.
  114. */
  115. static int get_sqlite_pointer(
  116. object clientdata,
  117. Tcl_Interp interp,
  118. int objc,
  119. Tcl_Obj[] objv
  120. )
  121. {
  122. SqliteDb p;
  123. WrappedCommand cmdInfo = null;
  124. //string zBuf ;//[100];
  125. if ( objc != 2 )
  126. {
  127. TCL.Tcl_WrongNumArgs( interp, 1, objv, "SQLITE-CONNECTION" );
  128. return TCL.TCL_ERROR;
  129. }
  130. if ( TCL.Tcl_GetCommandInfo( interp, objv[1].ToString(), out cmdInfo ) )
  131. {
  132. TCL.Tcl_AppendResult( interp, "command not found: ",
  133. TCL.Tcl_GetString( objv[1] ), null );
  134. return TCL.TCL_ERROR;
  135. }
  136. //p = (SqliteDb)cmdInfo.objclientdata;
  137. //zBuf = p.db.GetHashCode().ToString();
  138. //sqlite3_snprintf( zBuf, "%p", p.db );
  139. //if( strncmp(zBuf,"0x",2) ){
  140. // sqlite3_snprintf(zBuf, "0x%p", p.db);
  141. //}
  142. //TCL.Tcl_AppendResult(interp, zBuf,null );
  143. TCL.Tcl_AppendResult( interp, objv[1].ToString() );
  144. return TCL.TCL_OK;
  145. }
  146. /*
  147. ** Decode a pointer to an sqlite3 object.
  148. */
  149. static int getDbPointer( Tcl_Interp interp, string zA, out sqlite3 ppDb )
  150. {
  151. SqliteDb p;
  152. WrappedCommand cmdInfo = new WrappedCommand();
  153. if ( !TCL.Tcl_GetCommandInfo( interp, zA, out cmdInfo ) )
  154. {
  155. if ( cmdInfo == null )
  156. {
  157. ppDb = new sqlite3();
  158. }
  159. else
  160. {
  161. p = (SqliteDb)cmdInfo.objClientData;
  162. ppDb = p.db;
  163. }
  164. }
  165. else
  166. {
  167. ppDb = null;
  168. }
  169. return TCL.TCL_OK;
  170. }
  171. static string sqlite3TestErrorName( int rc )
  172. {
  173. string zName = "";
  174. switch ( rc )
  175. {
  176. case SQLITE_OK:
  177. zName = "SQLITE_OK";
  178. break;
  179. case SQLITE_ERROR:
  180. zName = "SQLITE_ERROR";
  181. break;
  182. case SQLITE_INTERNAL:
  183. zName = "SQLITE_INTERNAL";
  184. break;
  185. case SQLITE_PERM:
  186. zName = "SQLITE_PERM";
  187. break;
  188. case SQLITE_ABORT:
  189. zName = "SQLITE_ABORT";
  190. break;
  191. case SQLITE_BUSY:
  192. zName = "SQLITE_BUSY";
  193. break;
  194. case SQLITE_LOCKED:
  195. zName = "SQLITE_LOCKED";
  196. break;
  197. case SQLITE_LOCKED_SHAREDCACHE:
  198. zName = "SQLITE_LOCKED_SHAREDCACHE";
  199. break;
  200. case SQLITE_NOMEM:
  201. zName = "SQLITE_NOMEM";
  202. break;
  203. case SQLITE_READONLY:
  204. zName = "SQLITE_READONLY";
  205. break;
  206. case SQLITE_INTERRUPT:
  207. zName = "SQLITE_INTERRUPT";
  208. break;
  209. case SQLITE_IOERR:
  210. zName = "SQLITE_IOERR";
  211. break;
  212. case SQLITE_CORRUPT:
  213. zName = "SQLITE_CORRUPT";
  214. break;
  215. case SQLITE_NOTFOUND:
  216. zName = "SQLITE_NOTFOUND";
  217. break;
  218. case SQLITE_FULL:
  219. zName = "SQLITE_FULL";
  220. break;
  221. case SQLITE_CANTOPEN:
  222. zName = "SQLITE_CANTOPEN";
  223. break;
  224. case SQLITE_PROTOCOL:
  225. zName = "SQLITE_PROTOCOL";
  226. break;
  227. case SQLITE_EMPTY:
  228. zName = "SQLITE_EMPTY";
  229. break;
  230. case SQLITE_SCHEMA:
  231. zName = "SQLITE_SCHEMA";
  232. break;
  233. case SQLITE_TOOBIG:
  234. zName = "SQLITE_TOOBIG";
  235. break;
  236. case SQLITE_CONSTRAINT:
  237. zName = "SQLITE_CONSTRAINT";
  238. break;
  239. case SQLITE_MISMATCH:
  240. zName = "SQLITE_MISMATCH";
  241. break;
  242. case SQLITE_MISUSE:
  243. zName = "SQLITE_MISUSE";
  244. break;
  245. case SQLITE_NOLFS:
  246. zName = "SQLITE_NOLFS";
  247. break;
  248. case SQLITE_AUTH:
  249. zName = "SQLITE_AUTH";
  250. break;
  251. case SQLITE_FORMAT:
  252. zName = "SQLITE_FORMAT";
  253. break;
  254. case SQLITE_RANGE:
  255. zName = "SQLITE_RANGE";
  256. break;
  257. case SQLITE_NOTADB:
  258. zName = "SQLITE_NOTADB";
  259. break;
  260. case SQLITE_ROW:
  261. zName = "SQLITE_ROW";
  262. break;
  263. case SQLITE_DONE:
  264. zName = "SQLITE_DONE";
  265. break;
  266. case SQLITE_IOERR_READ:
  267. zName = "SQLITE_IOERR_READ";
  268. break;
  269. case SQLITE_IOERR_SHORT_READ:
  270. zName = "SQLITE_IOERR_SHORT_READ";
  271. break;
  272. case SQLITE_IOERR_WRITE:
  273. zName = "SQLITE_IOERR_WRITE";
  274. break;
  275. case SQLITE_IOERR_FSYNC:
  276. zName = "SQLITE_IOERR_FSYNC";
  277. break;
  278. case SQLITE_IOERR_DIR_FSYNC:
  279. zName = "SQLITE_IOERR_DIR_FSYNC";
  280. break;
  281. case SQLITE_IOERR_TRUNCATE:
  282. zName = "SQLITE_IOERR_TRUNCATE";
  283. break;
  284. case SQLITE_IOERR_FSTAT:
  285. zName = "SQLITE_IOERR_FSTAT";
  286. break;
  287. case SQLITE_IOERR_UNLOCK:
  288. zName = "SQLITE_IOERR_UNLOCK";
  289. break;
  290. case SQLITE_IOERR_RDLOCK:
  291. zName = "SQLITE_IOERR_RDLOCK";
  292. break;
  293. case SQLITE_IOERR_DELETE:
  294. zName = "SQLITE_IOERR_DELETE";
  295. break;
  296. case SQLITE_IOERR_BLOCKED:
  297. zName = "SQLITE_IOERR_BLOCKED";
  298. break;
  299. case SQLITE_IOERR_NOMEM:
  300. zName = "SQLITE_IOERR_NOMEM";
  301. break;
  302. case SQLITE_IOERR_ACCESS:
  303. zName = "SQLITE_IOERR_ACCESS";
  304. break;
  305. case SQLITE_IOERR_CHECKRESERVEDLOCK:
  306. zName = "SQLITE_IOERR_CHECKRESERVEDLOCK";
  307. break;
  308. case SQLITE_IOERR_LOCK:
  309. zName = "SQLITE_IOERR_LOCK";
  310. break;
  311. case SQLITE_CORRUPT_VTAB:
  312. zName = "SQLITE_CORRUPT_VTAB";
  313. break;
  314. case SQLITE_READONLY_RECOVERY:
  315. zName = "SQLITE_READONLY_RECOVERY";
  316. break;
  317. case SQLITE_READONLY_CANTLOCK:
  318. zName = "SQLITE_READONLY_CANTLOCK";
  319. break;
  320. default:
  321. zName = "SQLITE_Unknown";
  322. break;
  323. }
  324. return zName;
  325. }
  326. //#define t1ErrorName sqlite3TestErrorName
  327. static string t1ErrorName( int i )
  328. {
  329. return sqlite3TestErrorName( i );
  330. }
  331. /*
  332. ** Convert an sqlite3_stmt* into an sqlite3*. This depends on the
  333. ** fact that the sqlite3* is the first field in the Vdbe structure.
  334. */
  335. //#define StmtToDb(X) sqlite3_db_handle(X)
  336. static sqlite3 StmtToDb( Vdbe v )
  337. {
  338. return sqlite3_db_handle( v );
  339. }
  340. /*
  341. ** Check a return value to make sure it agrees with the results
  342. ** from sqlite3_errcode.
  343. */
  344. static int sqlite3TestErrCode( Tcl_Interp interp, sqlite3 db, int rc )
  345. {
  346. if ( sqlite3_threadsafe() == 0 && rc != SQLITE_MISUSE && rc != SQLITE_OK
  347. && sqlite3_errcode( db ) != rc )
  348. {
  349. StringBuilder zBuf = new StringBuilder( 200 );//char zBuf[200];
  350. int r2 = sqlite3_errcode( db );
  351. sqlite3_snprintf( 200, zBuf, "error code %s (%d) does not match sqlite3_errcode %s (%d)",
  352. sqlite3TestErrorName( rc ), rc, sqlite3TestErrorName( r2 ), r2 );//t1ErrorName( rc ), rc, t1ErrorName( r2 ), r2 );
  353. TCL.Tcl_ResetResult( interp );
  354. TCL.Tcl_AppendResult( interp, zBuf.ToString() );
  355. return 1;
  356. }
  357. return 0;
  358. }
  359. /*
  360. ** Decode a pointer to an sqlite3_stmt object.
  361. */
  362. static int getStmtPointer(
  363. Tcl_Interp interp,
  364. string zArg,
  365. out sqlite3_stmt ppStmt
  366. )
  367. {
  368. ppStmt = (sqlite3_stmt)sqlite3TestTextToPtr( interp, zArg );
  369. WrappedCommand cmdInfo = new WrappedCommand();
  370. TCL.Tcl_GetCommandInfo( interp, zArg, out cmdInfo );
  371. ppStmt = cmdInfo == null ? null : (sqlite3_stmt)cmdInfo.objClientData;
  372. return TCL.TCL_OK;
  373. }
  374. /*
  375. ** Generate a text representation of a pointer that can be understood
  376. ** by the getDbPointer and getVmPointer routines above.
  377. **
  378. ** The problem is, on some machines (Solaris) if you do a printf with
  379. ** "%p" you cannot turn around and do a scanf with the same "%p" and
  380. ** get your pointer back. You have to prepend a "0x" before it will
  381. ** work. Or at least that is what is reported to me (drh). But this
  382. ** behavior varies from machine to machine. The solution used her is
  383. ** to test the string right after it is generated to see if it can be
  384. ** understood by scanf, and if not, try prepending an "0x" to see if
  385. ** that helps. If nothing works, a fatal error is generated.
  386. */
  387. /*
  388. ** Decode a pointer to an sqlite3_stmt object.
  389. */
  390. static int sqlite3TestMakePointerStr( Tcl_Interp interp, StringBuilder zPtr, object p )
  391. {
  392. sqlite3_snprintf( 100, zPtr, "->%p", p );
  393. if ( TCL.Tcl_CreateCommandPointer( interp, zPtr, p ) )
  394. {
  395. return TCL.TCL_ERROR;
  396. }
  397. return TCL.TCL_OK;
  398. }
  399. /*
  400. ** The callback routine for sqlite3_exec_printf().
  401. */
  402. static int exec_printf_cb( object pArg, sqlite3_int64 argc, object p2, object p3 )
  403. {
  404. string[] name = (string[])p3;
  405. string[] argv = (string[])p2;
  406. TclObject str = (TclObject)pArg;
  407. int i;
  408. if ( TCL.Tcl_DStringLength( str ) == 0 )
  409. {
  410. for ( i = 0; i < argc; i++ )
  411. {
  412. TCL.Tcl_DStringAppendElement( str, name[i] != null ? name[i] + " " : "NULL " );
  413. }
  414. }
  415. string beginbrace = "", endbrace = "";
  416. for ( i = 0; i < argc; i++ )
  417. {
  418. if ( argc > 1 )
  419. {
  420. if ( Util.scanElement( null, argv[i].ToString() ) != 0 )
  421. {
  422. beginbrace = "{";
  423. endbrace = "}";
  424. }
  425. else
  426. {
  427. beginbrace = "";
  428. endbrace = "";
  429. }
  430. }
  431. TCL.Tcl_DStringAppendElement( str, argv[i] != null ? beginbrace + argv[i] + endbrace + ( i < argc - 1 ? " " : "" ) : "NULL" );
  432. }
  433. return 0;
  434. }
  435. /*
  436. ** The I/O tracing callback.
  437. */
  438. #if !(SQLITE_OMIT_TRACE) && TRACE
  439. //static FILE *iotrace_file = 0;
  440. //static void io_trace_callback(string zFormat, ...){
  441. // va_list ap;
  442. // va_start(ap, zFormat);
  443. // vfprintf(iotrace_file, zFormat, ap);
  444. // va_end(ap);
  445. // fflush(iotrace_file);
  446. //}
  447. #endif
  448. /*
  449. ** Usage: io_trace FILENAME
  450. **
  451. ** Turn I/O tracing on or off. If FILENAME is not an empty string,
  452. ** I/O tracing begins going into FILENAME. If FILENAME is an empty
  453. ** string, I/O tracing is turned off.
  454. */
  455. //static int test_io_trace(
  456. // object NotUsed,
  457. // Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  458. // int argc, /* Number of arguments */
  459. // Tcl_Obj[] argv /* Text of each argument */
  460. //){
  461. #if !(SQLITE_OMIT_TRACE) && (TRACE)
  462. // if( argc!=2 ){
  463. // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  464. // " FILENAME\"", 0);
  465. // return TCL.TCL_ERROR;
  466. // }
  467. // if( iotrace_file ){
  468. // if( iotrace_file!=stdout && iotrace_file!=stderr ){
  469. // fclose(iotrace_file);
  470. // }
  471. // iotrace_file = 0;
  472. // sqlite3IoTrace = 0;
  473. // }
  474. // if( argv[1][0] ){
  475. // if( strcmp(argv[1],"stdout")==0 ){
  476. // iotrace_file = stdout;
  477. // }else if( strcmp(argv[1],"stderr")==0 ){
  478. // iotrace_file = stderr;
  479. // }else{
  480. // iotrace_file = fopen(argv[1], "w");
  481. // }
  482. // sqlite3IoTrace = io_trace_callback;
  483. // }
  484. #endif
  485. // return TCL.TCL_OK;
  486. //}
  487. /*
  488. ** Usage: sqlite3_exec_printf DB FORMAT STRING
  489. **
  490. ** Invoke the sqlite3_exec_printf() interface using the open database
  491. ** DB. The SQL is the string FORMAT. The format string should contain
  492. ** one %s or %q. STRING is the value inserted into %s or %q.
  493. */
  494. static int test_exec_printf(
  495. object NotUsed,
  496. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  497. int argc, /* Number of arguments */
  498. Tcl_Obj[] argv /* Text of each argument */
  499. )
  500. {
  501. sqlite3 db = null;
  502. TclObject str = null;
  503. int rc;
  504. string zErr = "";
  505. string zSql = "";
  506. StringBuilder zBuf = new StringBuilder( 30 );
  507. if ( argc != 4 )
  508. {
  509. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  510. " DB FORMAT STRING" );
  511. return TCL.TCL_ERROR;
  512. }
  513. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  514. return TCL.TCL_ERROR;
  515. TCL.Tcl_DStringInit( out str );
  516. zSql = sqlite3_mprintf( argv[2].ToString(), argv[3].ToString() );
  517. rc = sqlite3_exec( db, zSql, (dxCallback)exec_printf_cb, str, ref zErr );
  518. sqlite3DbFree( db, ref zSql );
  519. sqlite3_snprintf( 30, zBuf, "%d", rc );
  520. TCL.Tcl_AppendElement( interp, zBuf );
  521. TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr ); //TCL.Tcl_DStringValue(ref str)
  522. TCL.Tcl_DStringFree( ref str );
  523. if ( zErr != null )
  524. sqlite3DbFree( db, ref zErr );
  525. if ( sqlite3TestErrCode( interp, db, rc ) != 0 )
  526. return TCL.TCL_ERROR;
  527. return TCL.TCL_OK;
  528. }
  529. /*
  530. ** Usage: sqlite3_exec_hex DB HEX
  531. **
  532. ** Invoke the sqlite3_exec() on a string that is obtained by translating
  533. ** HEX into ASCII. Most characters are translated as is. %HH becomes
  534. ** a hex character.
  535. */
  536. static int test_exec_hex(
  537. object NotUsed,
  538. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  539. int argc, /* Number of arguments */
  540. Tcl_Obj[] argv /* Text of each argument */
  541. )
  542. {
  543. sqlite3 db = null;
  544. TclObject str = null;
  545. int rc, i, j;
  546. string zErr = "";
  547. string zHex;
  548. StringBuilder zSql = new StringBuilder( 500 );
  549. string zBuf = "";
  550. if ( argc != 3 )
  551. {
  552. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  553. " DB HEX" );
  554. return TCL.TCL_ERROR;
  555. }
  556. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  557. return TCL.TCL_ERROR;
  558. zHex = argv[2].ToString();
  559. for ( i = j = 0; j < zHex.Length && zHex[j] != 0; i++, j++ )
  560. {
  561. if ( zHex[j] == '%' && zHex[j + 2] != 0 && zHex[j + 2] != 0 )
  562. {
  563. zSql.Append( (char)( ( testHexToInt( zHex[j + 1] ) << 4 ) + testHexToInt( zHex[j + 2] ) ) );
  564. j += 2;
  565. }
  566. else
  567. {
  568. zSql.Append( zHex[j] );
  569. }
  570. }
  571. //zSql[i] = '\0';
  572. TCL.Tcl_DStringInit( out str );
  573. rc = sqlite3_exec( db, zSql.ToString(), (dxCallback)exec_printf_cb, str, ref zErr );
  574. zBuf = rc.ToString();// sprintf( zBuf, "%d", rc );
  575. TCL.Tcl_AppendElement( interp, zBuf );
  576. TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr );
  577. TCL.Tcl_DStringFree( ref str );
  578. // //sqlite3_free(ref zErr);
  579. if ( sqlite3TestErrCode( interp, db, rc ) != 0 )
  580. return TCL.TCL_ERROR;
  581. return TCL.TCL_OK;
  582. }
  583. /*
  584. ** Usage: db_enter DB
  585. ** db_leave DB
  586. **
  587. ** Enter or leave the mutex on a database connection.
  588. */
  589. static int db_enter(
  590. object NotUsed,
  591. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  592. int argc, /* Number of arguments */
  593. Tcl_Obj[] argv /* Text of each argument */
  594. )
  595. {
  596. sqlite3 db = null;
  597. if ( argc != 2 )
  598. {
  599. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  600. " DB" );
  601. return TCL.TCL_ERROR;
  602. }
  603. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  604. return TCL.TCL_ERROR;
  605. sqlite3_mutex_enter( db.mutex );
  606. return TCL.TCL_OK;
  607. }
  608. static int db_leave(
  609. object NotUsed,
  610. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  611. int argc, /* Number of arguments */
  612. Tcl_Obj[] argv /* Text of each argument */
  613. )
  614. {
  615. sqlite3 db = null;
  616. if ( argc != 2 )
  617. {
  618. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  619. " DB" );
  620. return TCL.TCL_ERROR;
  621. }
  622. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  623. return TCL.TCL_ERROR;
  624. sqlite3_mutex_leave( db.mutex );
  625. return TCL.TCL_OK;
  626. }
  627. /*
  628. ** Usage: sqlite3_exec DB SQL
  629. **
  630. ** Invoke the sqlite3_exec interface using the open database DB
  631. */
  632. static int test_exec(
  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. TclObject str = TclString.newInstance( "" );
  641. int rc;
  642. string zErr = "";
  643. string zSql;
  644. int i, j;
  645. StringBuilder zBuf = new StringBuilder( 30 );
  646. if ( argc != 3 )
  647. {
  648. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  649. " DB SQL" );
  650. return TCL.TCL_ERROR;
  651. }
  652. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  653. return TCL.TCL_ERROR;
  654. TCL.Tcl_DStringInit( out str );
  655. zSql = sqlite3_mprintf( "%s", argv[2].ToString() );
  656. StringBuilder sb = new StringBuilder( zSql.Length );
  657. for ( i = 0; i < zSql.Length; i++ )
  658. {
  659. if ( zSql[i] == '%' )
  660. {
  661. sb.Append( (char)( ( testHexToInt( zSql[i + 1] ) << 4 ) + testHexToInt( zSql[i + 2] ) ) );
  662. i += 2;
  663. }
  664. else
  665. sb.Append( zSql[i] );
  666. }
  667. ////zSql[j] = 0;
  668. rc = sqlite3_exec( db, sb.ToString(), exec_printf_cb, str, ref zErr );
  669. sqlite3DbFree( db, ref zSql );
  670. sqlite3_snprintf( 30, zBuf, "%d", rc );
  671. TCL.Tcl_AppendElement( interp, zBuf );
  672. TCL.Tcl_AppendElement( interp, rc == SQLITE_OK ? str.ToString() : zErr );
  673. //TCL.Tcl_DStringFree(&str);
  674. if ( zErr != "" )
  675. sqlite3DbFree( db, ref zErr );
  676. if ( sqlite3TestErrCode( interp, db, rc ) != 0 )
  677. return TCL.TCL_ERROR;
  678. return TCL.TCL_OK;
  679. }
  680. /*
  681. ** Usage: sqlite3_exec_nr DB SQL
  682. **
  683. ** Invoke the sqlite3_exec interface using the open database DB. Discard
  684. ** all results
  685. */
  686. static int test_exec_nr(
  687. object NotUsed,
  688. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  689. int argc, /* Number of arguments */
  690. Tcl_Obj[] argv /* Text of each argument */
  691. )
  692. {
  693. sqlite3 db = null;
  694. int rc;
  695. string zErr = "";
  696. if ( argc != 3 )
  697. {
  698. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  699. " DB SQL" );
  700. return TCL.TCL_ERROR;
  701. }
  702. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  703. return TCL.TCL_ERROR;
  704. rc = sqlite3_exec( db, argv[2].ToString(), null, null, ref zErr );
  705. if ( sqlite3TestErrCode( interp, db, rc ) != 0 )
  706. return TCL.TCL_ERROR;
  707. return TCL.TCL_OK;
  708. }
  709. /*
  710. ** Usage: sqlite3_mprintf_z_test SEPARATOR ARG0 ARG1 ...
  711. **
  712. ** Test the %z format of sqlite_mprintf(). Use multiple mprintf() calls to
  713. ** concatenate arg0 through argn using separator as the separator.
  714. ** Return the result.
  715. */
  716. static int test_mprintf_z(
  717. object NotUsed,
  718. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  719. int argc, /* Number of arguments */
  720. Tcl_Obj[] argv /* Text of each argument */
  721. )
  722. {
  723. string zResult = "";
  724. int i;
  725. for ( i = 2; i < argc && ( i == 2 || zResult != "" ); i++ )
  726. {
  727. zResult = sqlite3_mprintf( "%z%s%s", zResult, argv[1].ToString(), argv[i].ToString() );
  728. }
  729. TCL.Tcl_AppendResult( interp, zResult );
  730. //sqlite3DbFree( db, zResult );
  731. return TCL.TCL_OK;
  732. }
  733. /*
  734. ** Usage: sqlite3_mprintf_n_test STRING
  735. **
  736. ** Test the %n format of sqlite_mprintf(). Return the length of the
  737. ** input string.
  738. */
  739. static int test_mprintf_n(
  740. object NotUsed,
  741. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  742. int argc, /* Number of arguments */
  743. Tcl_Obj[] argv /* Text of each argument */
  744. )
  745. {
  746. string zStr;
  747. int n = 0;
  748. zStr = sqlite3_mprintf( "%s%n", argv[1].ToString() );
  749. n = zStr.Length;
  750. //sqlite3DbFree( db, zStr );
  751. TCL.Tcl_SetObjResult( interp, TCL.Tcl_NewIntObj( n ) );
  752. return TCL.TCL_OK;
  753. }
  754. /*
  755. ** Usage: sqlite3_snprintf_int SIZE FORMAT INT
  756. **
  757. ** Test the of sqlite3_snprintf() routine. SIZE is the size of the
  758. ** output buffer in bytes. The maximum size is 100. FORMAT is the
  759. ** format string. INT is a single integer argument. The FORMAT
  760. ** string must require no more than this one integer argument. If
  761. ** You pass in a format string that requires more than one argument,
  762. ** bad things will happen.
  763. */
  764. static int test_snprintf_int(
  765. object NotUsed,
  766. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  767. int argc, /* Number of arguments */
  768. Tcl_Obj[] argv /* Text of each argument */
  769. )
  770. {
  771. StringBuilder zStr = new StringBuilder( 100 );
  772. int n = atoi( argv[1].ToString() );
  773. string zFormat = argv[2].ToString();
  774. int a1 = atoi( argv[3].ToString() );
  775. if ( n > zStr.Capacity )
  776. n = zStr.Capacity;// sizeof( zStr );
  777. zStr = new StringBuilder( "abcdefghijklmnopqrstuvwxyz" );
  778. sqlite3_snprintf( n, zStr, zFormat, a1 );
  779. TCL.Tcl_AppendResult( interp, zStr );
  780. return TCL.TCL_OK;
  781. }
  782. #if !SQLITE_OMIT_GET_TABLE
  783. /*
  784. ** Usage: sqlite3_get_table_printf DB FORMAT STRING ?--no-counts?
  785. **
  786. ** Invoke the sqlite3_get_table_printf() interface using the open database
  787. ** DB. The SQL is the string FORMAT. The format string should contain
  788. ** one %s or %q. STRING is the value inserted into %s or %q.
  789. */
  790. static int test_get_table_printf(
  791. object NotUsed,
  792. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  793. int argc, /* Number of arguments */
  794. Tcl_Obj[] argv /* Text of each argument */
  795. ){
  796. sqlite3 db=null;
  797. TCL.Tcl_DString str;
  798. int rc;
  799. string zErr = 0;
  800. int nRow, nCol;
  801. char **aResult;
  802. int i;
  803. char zBuf[30];
  804. string zSql;
  805. int resCount = -1;
  806. if( argc==5 ){
  807. if( TCL.Tcl_GetInt(interp, argv[4], out resCount) ) return TCL.TCL_ERROR;
  808. }
  809. if( argc!=4 && argc!=5 ){
  810. TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  811. " DB FORMAT STRING ?COUNT?", 0);
  812. return TCL.TCL_ERROR;
  813. }
  814. if( getDbPointer(interp, argv[1].ToString(), out db) !=0) return TCL.TCL_ERROR;
  815. TCL.Tcl_DStringInit(&str);
  816. zSql = sqlite3_mprintf(argv[2],argv[3]);
  817. if( argc==5 ){
  818. rc = sqlite3_get_table(db, zSql, aResult, 0, 0, zErr);
  819. }else{
  820. rc = sqlite3_get_table(db, zSql, aResult, nRow, nCol, zErr);
  821. resCount = (nRow+1)*nCol;
  822. }
  823. sqlite3DbFree(db,zSql);
  824. sqlite3_snprintf(zBuf, "%d", rc);
  825. TCL.Tcl_AppendElement(interp, zBuf);
  826. if( rc==SQLITE_OK ){
  827. if( argc==4 ){
  828. sqlite3_snprintf(zBuf, "%d", nRow);
  829. TCL.Tcl_AppendElement(interp, zBuf);
  830. sqlite3_snprintf(zBuf, "%d", nCol);
  831. TCL.Tcl_AppendElement(interp, zBuf);
  832. }
  833. for(i=0; i<resCount; i++){
  834. TCL.Tcl_AppendElement(interp, aResult[i] ? aResult[i] : "NULL");
  835. }
  836. }else{
  837. TCL.Tcl_AppendElement(interp, zErr);
  838. }
  839. //sqlite3_free_table(aResult);
  840. if( zErr ) sqlite3DbFree(db,zErr);
  841. if( sqlite3TestErrCode(interp, db, rc) ) return TCL.TCL_ERROR;
  842. return TCL.TCL_OK;
  843. }
  844. #endif //* SQLITE_OMIT_GET_TABLE*/
  845. /*
  846. ** Usage: sqlite3_last_insert_rowid DB
  847. **
  848. ** Returns the integer ROWID of the most recent insert.
  849. */
  850. //static int test_last_rowid(
  851. // object NotUsed,
  852. // Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  853. // int argc, /* Number of arguments */
  854. // Tcl_Obj[] argv /* Text of each argument */
  855. //){
  856. // sqlite3 db=null;
  857. // char zBuf[30];
  858. // if( argc!=2 ){
  859. // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " DB\"");
  860. // return TCL.TCL_ERROR;
  861. // }
  862. // if( getDbPointer(interp, argv[1].ToString(), out db) !=0) return TCL.TCL_ERROR;
  863. // sqlite3_snprintf(zBuf, "%lld", sqlite3_last_insert_rowid(db));
  864. // TCL.Tcl_AppendResult(interp, zBuf);
  865. // return SQLITE_OK;
  866. //}
  867. /*
  868. ** Usage: sqlite3_key DB KEY
  869. **
  870. ** Set the codec key.
  871. */
  872. static int test_key(
  873. object NotUsed,
  874. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  875. int argc, /* Number of arguments */
  876. Tcl_Obj[] argv /* Text of each argument */
  877. )
  878. {
  879. sqlite3 db = null;
  880. string zKey;
  881. int nKey;
  882. if ( argc != 3 )
  883. {
  884. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  885. " FILENAME\"" );
  886. return TCL.TCL_ERROR;
  887. }
  888. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  889. return TCL.TCL_ERROR;
  890. zKey = argv[2].ToString();
  891. nKey = zKey.Length;
  892. #if SQLITE_HAS_CODEC
  893. sqlite3_key( db, zKey, nKey );
  894. #endif
  895. return TCL.TCL_OK;
  896. }
  897. /*
  898. ** Usage: sqlite3_rekey DB KEY
  899. **
  900. ** Change the codec key.
  901. */
  902. static int test_rekey(
  903. object NotUsed,
  904. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  905. int argc, /* Number of arguments */
  906. Tcl_Obj[] argv /* Text of each argument */
  907. )
  908. {
  909. sqlite3 db = null;
  910. string zKey;
  911. int nKey;
  912. if ( argc != 3 )
  913. {
  914. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  915. " FILENAME\"" );
  916. return TCL.TCL_ERROR;
  917. }
  918. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  919. return TCL.TCL_ERROR;
  920. zKey = argv[2].ToString();
  921. nKey = zKey.Length;
  922. #if SQLITE_HAS_CODEC
  923. sqlite3_rekey( db, zKey, nKey );
  924. #endif
  925. return TCL.TCL_OK;
  926. }
  927. /*
  928. ** Usage: sqlite3_close DB
  929. **
  930. ** Closes the database opened by sqlite3_open.
  931. */
  932. static int sqlite_test_close(
  933. object NotUsed,
  934. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  935. int argc, /* Number of arguments */
  936. Tcl_Obj[] argv /* Text of each argument */
  937. )
  938. {
  939. sqlite3 db = null;
  940. int rc;
  941. if ( argc != 2 )
  942. {
  943. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  944. " FILENAME\"" );
  945. return TCL.TCL_ERROR;
  946. }
  947. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  948. return TCL.TCL_ERROR;
  949. rc = sqlite3_close( db );
  950. TCL.Tcl_SetResult( interp, t1ErrorName( rc ), TCL.TCL_STATIC );
  951. return TCL.TCL_OK;
  952. }
  953. /*
  954. ** Implementation of the x_coalesce() function.
  955. ** Return the first argument non-NULL argument.
  956. */
  957. static void t1_ifnullFunc(
  958. sqlite3_context context,
  959. int argc,
  960. sqlite3_value[] argv
  961. )
  962. {
  963. int i;
  964. for ( i = 0; i < argc; i++ )
  965. {
  966. if ( SQLITE_NULL != sqlite3_value_type( argv[i] ) )
  967. {
  968. int n = sqlite3_value_bytes( argv[i] );
  969. sqlite3_result_text( context, sqlite3_value_text( argv[i] ),
  970. n, SQLITE_TRANSIENT );
  971. break;
  972. }
  973. }
  974. }
  975. /*
  976. ** These are test functions. hex8() interprets its argument as
  977. ** UTF8 and returns a hex encoding. hex16le() interprets its argument
  978. ** as UTF16le and returns a hex encoding.
  979. */
  980. static void hex8Func( sqlite3_context p, int argc, sqlite3_value[] argv )
  981. {
  982. string z;
  983. int i;
  984. StringBuilder zBuf = new StringBuilder( 200 );
  985. z = sqlite3_value_text( argv[0] );
  986. StringBuilder zTemp = new StringBuilder( 200 );
  987. for ( i = 0; i < zBuf.Capacity / 2 - 2 && i < argv[0].n; i++ )
  988. {
  989. sqlite3_snprintf( 4, zTemp, "%02x", z[i] & 0xff );
  990. zBuf.Append( zTemp );
  991. }
  992. //zBuf[i*2] = 0;
  993. sqlite3_result_text( p, zBuf, -1, SQLITE_TRANSIENT );
  994. }
  995. #if !SQLITE_OMIT_UTF16
  996. static void hex16Func(sqlite3_context p, int argc, sqlite3_value[] argv){
  997. Debugger.Break (); //TODO --
  998. // const unsigned short int *z;
  999. // int i;
  1000. // char zBuf[400];
  1001. // z = sqlite3_value_text16(argv[0]);
  1002. // for(i=0; i<sizeof(zBuf)/4 - 4 && z[i]; i++){
  1003. // sqlite3_snprintf(&zBuf[i*4], "%04x", z[i]&0xff);
  1004. // }
  1005. // zBuf[i*4] = 0;
  1006. // sqlite3_result_text(p, (char)zBuf, -1, SQLITE_TRANSIENT);
  1007. }
  1008. #endif
  1009. /*
  1010. ** A structure into which to accumulate text.
  1011. */
  1012. struct dstr
  1013. {
  1014. public int nAlloc; /* Space allocated */
  1015. public int nUsed; /* Space used */
  1016. public StringBuilder z; /* The space */
  1017. };
  1018. /*
  1019. ** Append text to a dstr
  1020. */
  1021. static void dstrAppend( dstr p, string z, int divider )
  1022. {
  1023. int n = z.Length;// strlen( z );
  1024. // if( p.nUsed + n + 2 > p.nAlloc ){
  1025. // string zNew;
  1026. p.nAlloc = p.nAlloc * 2 + n + 200;
  1027. p.z.Capacity = p.nAlloc;
  1028. // zNew = sqlite3_realloc(p.z, p.nAlloc);
  1029. // if( zNew==0 ){
  1030. // sqlite3DbFree(db,p.z);
  1031. // memset(p, 0, sizeof(*p));
  1032. // return;
  1033. // }
  1034. // p.z = zNew;
  1035. // }
  1036. // if( divider && p.nUsed>0 ){
  1037. // p.z[p.nUsed++] = divider;
  1038. // }
  1039. // memcpy(p.z[p.nUsed], z, n+1);
  1040. p.nUsed += n;
  1041. p.z.Append( divider + z );
  1042. }
  1043. /*
  1044. ** Invoked for each callback from sqlite3ExecFunc
  1045. */
  1046. static int execFuncCallback( object pData, sqlite3_int64 argc, object _argv, object NotUsed )
  1047. {
  1048. Tcl_Obj[] argv = (Tcl_Obj[])_argv;
  1049. dstr p = (dstr)pData;
  1050. int i;
  1051. for ( i = 0; i < argc; i++ )
  1052. {
  1053. if ( argv[i] == null )
  1054. {
  1055. dstrAppend( p, "NULL", ' ' );
  1056. }
  1057. else
  1058. {
  1059. dstrAppend( p, argv[i].ToString(), ' ' );
  1060. }
  1061. }
  1062. return 0;
  1063. }
  1064. /*
  1065. ** Implementation of the x_sqlite_exec() function. This function takes
  1066. ** a single argument and attempts to execute that argument as SQL code.
  1067. ** This is illegal and should set the SQLITE_MISUSE flag on the database.
  1068. **
  1069. ** 2004-Jan-07: We have changed this to make it legal to call sqlite3_exec()
  1070. ** from within a function call.
  1071. **
  1072. ** This routine simulates the effect of having two threads attempt to
  1073. ** use the same database at the same time.
  1074. */
  1075. static void sqlite3ExecFunc(
  1076. sqlite3_context context,
  1077. int argc,
  1078. sqlite3_value[] argv
  1079. )
  1080. {
  1081. dstr x = new dstr();
  1082. //memset(&x, 0, sizeof(x));
  1083. string sDummy = "";
  1084. sqlite3_exec( (sqlite3)sqlite3_context_db_handle( context ),
  1085. sqlite3_value_text( argv[0] ),
  1086. (dxCallback)execFuncCallback, (object)x, ref sDummy );
  1087. sqlite3_result_text( context, x.z, x.nUsed, SQLITE_TRANSIENT );
  1088. x.z = null;// sqlite3DbFree( db, ref x.z );
  1089. }
  1090. /*
  1091. ** Implementation of tkt2213func(), a scalar function that takes exactly
  1092. ** one argument. It has two interesting features:
  1093. **
  1094. ** * It calls sqlite3_value_text() 3 times on the argument sqlite3_value*.
  1095. ** If the three pointers returned are not the same an SQL error is raised.
  1096. **
  1097. ** * Otherwise it returns a copy of the text representation of its
  1098. ** argument in such a way as the VDBE representation is a Mem* cell
  1099. ** with the MEM_Term flag clear.
  1100. **
  1101. ** Ticket #2213 can therefore be tested by evaluating the following
  1102. ** SQL expression:
  1103. **
  1104. ** tkt2213func(tkt2213func('a string'));
  1105. */
  1106. static void tkt2213Function(
  1107. sqlite3_context context,
  1108. int argc,
  1109. sqlite3_value[] argv
  1110. )
  1111. {
  1112. int nText;
  1113. string zText1;
  1114. string zText2;
  1115. string zText3;
  1116. nText = sqlite3_value_bytes( argv[0] );
  1117. zText1 = sqlite3_value_text( argv[0] );
  1118. zText2 = sqlite3_value_text( argv[0] );
  1119. zText3 = sqlite3_value_text( argv[0] );
  1120. if ( zText1 != zText2 || zText2 != zText3 )
  1121. {
  1122. sqlite3_result_error( context, "tkt2213 is not fixed", -1 );
  1123. }
  1124. else
  1125. {
  1126. //string zCopy = (char )sqlite3Malloc(nText);
  1127. //memcpy(zCopy, zText1, nText);
  1128. sqlite3_result_text( context, zText1, nText, null ); //sqlite3_free );
  1129. }
  1130. }
  1131. /*
  1132. ** The following SQL function takes 4 arguments. The 2nd and
  1133. ** 4th argument must be one of these strings: 'text', 'text16',
  1134. ** or 'blob' corresponding to API functions
  1135. **
  1136. ** sqlite3_value_text()
  1137. ** sqlite3_value_text16()
  1138. ** sqlite3_value_blob()
  1139. **
  1140. ** The third argument is a string, either 'bytes' or 'bytes16' or 'noop',
  1141. ** corresponding to APIs:
  1142. **
  1143. ** sqlite3_value_bytes()
  1144. ** sqlite3_value_bytes16()
  1145. ** noop
  1146. **
  1147. ** The APIs designated by the 2nd through 4th arguments are applied
  1148. ** to the first argument in order. If the pointers returned by the
  1149. ** second and fourth are different, this routine returns 1. Otherwise,
  1150. ** this routine returns 0.
  1151. **
  1152. ** This function is used to test to see when returned pointers from
  1153. ** the _text(), _text16() and _blob() APIs become invalidated.
  1154. */
  1155. static void ptrChngFunction(
  1156. sqlite3_context context,
  1157. int argc,
  1158. sqlite3_value[] argv
  1159. )
  1160. {
  1161. sqlite3_result_int( context, 0 );
  1162. return;
  1163. //Debugger.Break(); //TODO --
  1164. //string p1 = "", p2 = "";
  1165. //string zCmd;
  1166. //if ( argc != 4 )
  1167. // return;
  1168. //zCmd = sqlite3_value_text( argv[1] );
  1169. //if ( zCmd == null )
  1170. // return;
  1171. // if( strcmp(zCmd,"text")==0 ){
  1172. // p1 = (const void)sqlite3_value_text(argv[0]);
  1173. //#if !SQLITE_OMIT_UTF16
  1174. // }else if( strcmp(zCmd, "text16")==0 ){
  1175. // p1 = (const void)sqlite3_value_text16(argv[0]);
  1176. //#endif
  1177. // }else if( strcmp(zCmd, "blob")==0 ){
  1178. // p1 = (const void)sqlite3_value_blob(argv[0]);
  1179. // }else{
  1180. // return;
  1181. // }
  1182. // zCmd = (const char)sqlite3_value_text(argv[2]);
  1183. // if( zCmd==0 ) return;
  1184. // if( strcmp(zCmd,"bytes")==0 ){
  1185. // sqlite3_value_bytes(argv[0]);
  1186. //#if !SQLITE_OMIT_UTF16
  1187. // }else if( strcmp(zCmd, "bytes16")==0 ){
  1188. // sqlite3_value_bytes16(argv[0]);
  1189. //#endif
  1190. // }else if( strcmp(zCmd, "noop")==0 ){
  1191. // /* do nothing */
  1192. // }else{
  1193. // return;
  1194. // }
  1195. // zCmd = (const char)sqlite3_value_text(argv[3]);
  1196. // if( zCmd==0 ) return;
  1197. // if( strcmp(zCmd,"text")==0 ){
  1198. // p2 = (const void)sqlite3_value_text(argv[0]);
  1199. //#if !SQLITE_OMIT_UTF16
  1200. // }else if( strcmp(zCmd, "text16")==0 ){
  1201. // p2 = (const void)sqlite3_value_text16(argv[0]);
  1202. //#endif
  1203. // }else if( strcmp(zCmd, "blob")==0 ){
  1204. // p2 = (const void)sqlite3_value_blob(argv[0]);
  1205. // }else{
  1206. // return;
  1207. // }
  1208. //sqlite3_result_int( context, p1 != p2 ? 1 : 0 );
  1209. }
  1210. /*
  1211. ** Usage: sqlite_test_create_function DB
  1212. **
  1213. ** Call the sqlite3_create_function API on the given database in order
  1214. ** to create a function named "x_coalesce". This function does the same thing
  1215. ** as the "coalesce" function. This function also registers an SQL function
  1216. ** named "x_sqlite_exec" that invokes sqlite3_exec(). Invoking sqlite3_exec()
  1217. ** in this way is illegal recursion and should raise an SQLITE_MISUSE error.
  1218. ** The effect is similar to trying to use the same database connection from
  1219. ** two threads at the same time.
  1220. **
  1221. ** The original motivation for this routine was to be able to call the
  1222. ** sqlite3_create_function function while a query is in progress in order
  1223. ** to test the SQLITE_MISUSE detection logic.
  1224. */
  1225. static int test_create_function(
  1226. object NotUsed,
  1227. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  1228. int argc, /* Number of arguments */
  1229. Tcl_Obj[] argv /* Text of each argument */
  1230. )
  1231. {
  1232. int rc;
  1233. sqlite3 db = null;
  1234. if ( argc != 2 )
  1235. {
  1236. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  1237. " DB\"" );
  1238. return TCL.TCL_ERROR;
  1239. }
  1240. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  1241. return TCL.TCL_ERROR;
  1242. rc = sqlite3_create_function( db, "x_coalesce", -1, SQLITE_ANY, 0,
  1243. t1_ifnullFunc, null, null );
  1244. if ( rc == SQLITE_OK )
  1245. {
  1246. rc = sqlite3_create_function( db, "hex8", 1, SQLITE_ANY, 0,
  1247. hex8Func, null, null );
  1248. }
  1249. #if !SQLITE_OMIT_UTF16
  1250. if( rc==SQLITE_OK ){
  1251. rc = sqlite3_create_function(db, "hex16", 1, SQLITE_ANY, null, hex16Func, null,null);
  1252. }
  1253. #endif
  1254. if ( rc == SQLITE_OK )
  1255. {
  1256. rc = sqlite3_create_function( db, "tkt2213func", 1, SQLITE_ANY, 0,
  1257. tkt2213Function, null, null );
  1258. }
  1259. if ( rc == SQLITE_OK )
  1260. {
  1261. rc = sqlite3_create_function( db, "pointer_change", 4, SQLITE_ANY, 0,
  1262. ptrChngFunction, null, null );
  1263. }
  1264. #if !SQLITE_OMIT_UTF16
  1265. /* Use the sqlite3_create_function16() API here. Mainly for fun, but also
  1266. ** because it is not tested anywhere else. */
  1267. if( rc==SQLITE_OK ){
  1268. string zUtf16;
  1269. sqlite3_value pVal;
  1270. sqlite3_mutex_enter(db.mutex);
  1271. pVal = sqlite3ValueNew(db);
  1272. sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
  1273. zUtf16 = sqlite3ValueText(pVal, SQLITE_UTF16NATIVE);
  1274. if( db.mallocFailed !=0{
  1275. rc = SQLITE_NOMEM;
  1276. }else{
  1277. rc = sqlite3_create_function16(db, zUtf16, 1, SQLITE_UTF16, db, sqlite3ExecFunc,null,null );
  1278. }
  1279. sqlite3ValueFree(ref pVal);
  1280. sqlite3_mutex_leave(db.mutex);
  1281. }
  1282. #endif
  1283. if ( sqlite3TestErrCode( interp, db, rc ) != 0 )
  1284. return TCL.TCL_ERROR;
  1285. TCL.Tcl_SetResult( interp, sqlite3TestErrorName( rc ), 0 );
  1286. return TCL.TCL_OK;
  1287. }
  1288. /*
  1289. ** Routines to implement the x_count() aggregate function.
  1290. **
  1291. ** x_count() counts the number of non-null arguments. But there are
  1292. ** some twists for testing purposes.
  1293. **
  1294. ** If the argument to x_count() is 40 then a UTF-8 error is reported
  1295. ** on the step function. If x_count(41) is seen, then a UTF-16 error
  1296. ** is reported on the step function. If the total count is 42, then
  1297. ** a UTF-8 error is reported on the finalize function.
  1298. */
  1299. //typedef struct t1CountCtx t1CountCtx;
  1300. static void t1CountStep(
  1301. sqlite3_context context,
  1302. int argc,
  1303. sqlite3_value[] argv
  1304. )
  1305. {
  1306. SumCtx p;
  1307. Mem pMem = sqlite3_aggregate_context( context, 1 );//sizeof(*p));
  1308. if ( pMem._SumCtx == null )
  1309. pMem._SumCtx = new SumCtx();
  1310. p = pMem._SumCtx;
  1311. if ( p.Context == null )
  1312. p.Context = pMem;
  1313. if ( ( argc == 0 || SQLITE_NULL != sqlite3_value_type( argv[0] ) ) && p != null )
  1314. {
  1315. p.cnt++;
  1316. }
  1317. if ( argc > 0 )
  1318. {
  1319. int v = sqlite3_value_int( argv[0] );
  1320. if ( v == 40 )
  1321. {
  1322. sqlite3_result_error( context, "value of 40 handed to x_count", -1 );
  1323. #if !SQLITE_OMIT_UTF16
  1324. }else if( v==41 ){
  1325. Debugger.Break (); // TODO --
  1326. //const char zUtf16ErrMsg[] = { 0, 0x61, 0, 0x62, 0, 0x63, 0, 0, 0};
  1327. //sqlite3_result_error16(context, zUtf16ErrMsg[1-SQLITE_BIGENDIAN], -1);
  1328. #endif
  1329. }
  1330. }
  1331. }
  1332. static void t1CountFinalize( sqlite3_context context )
  1333. {
  1334. SumCtx p;
  1335. Mem pMem = sqlite3_aggregate_context( context, 0 );//sizeof(*p));
  1336. p = pMem._SumCtx;
  1337. if ( p != null )
  1338. {
  1339. if ( p.cnt == 42 )
  1340. {
  1341. sqlite3_result_error( context, "x_count totals to 42", -1 );
  1342. }
  1343. else
  1344. {
  1345. sqlite3_result_int( context, p != null ? (int)p.cnt : 0 );
  1346. }
  1347. }
  1348. }
  1349. #if !SQLITE_OMIT_DEPRECATED
  1350. static void legacyCountStep(
  1351. sqlite3_context context,
  1352. int argc,
  1353. sqlite3_value[] argv
  1354. )
  1355. {
  1356. /* no-op */
  1357. }
  1358. static void legacyCountFinalize( sqlite3_context context )
  1359. {
  1360. sqlite3_result_int( context, sqlite3_aggregate_count( context ) );
  1361. }
  1362. #endif
  1363. /*
  1364. ** Usage: sqlite3_create_aggregate DB
  1365. **
  1366. ** Call the sqlite3_create_function API on the given database in order
  1367. ** to create a function named "x_count". This function is similar
  1368. ** to the built-in count() function, with a few special quirks
  1369. ** for testing the sqlite3_result_error() APIs.
  1370. **
  1371. ** The original motivation for this routine was to be able to call the
  1372. ** sqlite3_create_aggregate function while a query is in progress in order
  1373. ** to test the SQLITE_MISUSE detection logic. See misuse.test.
  1374. **
  1375. ** This routine was later extended to test the use of sqlite3_result_error()
  1376. ** within aggregate functions.
  1377. **
  1378. ** Later: It is now also extended to register the aggregate function
  1379. ** "legacy_count()" with the supplied database handle. This is used
  1380. ** to test the deprecated sqlite3_aggregate_count() API.
  1381. */
  1382. static int test_create_aggregate(
  1383. object NotUsed,
  1384. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  1385. int argc, /* Number of arguments */
  1386. Tcl_Obj[] argv /* Text of each argument */
  1387. )
  1388. {
  1389. sqlite3 db = new sqlite3();
  1390. int rc;
  1391. if ( argc != 2 )
  1392. {
  1393. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0].ToString(),
  1394. " FILENAME\"" );
  1395. return TCL.TCL_ERROR;
  1396. }
  1397. if ( getDbPointer( interp, argv[1].ToString(), out db ) != 0 )
  1398. return TCL.TCL_ERROR;
  1399. rc = sqlite3_create_function( db, "x_count", 0, SQLITE_UTF8, 0, null,
  1400. t1CountStep, t1CountFinalize );
  1401. if ( rc == SQLITE_OK )
  1402. {
  1403. rc = sqlite3_create_function( db, "x_count", 1, SQLITE_UTF8, 0, null,
  1404. t1CountStep, t1CountFinalize );
  1405. }
  1406. #if !SQLITE_OMIT_DEPRECATED
  1407. if ( rc == SQLITE_OK )
  1408. {
  1409. rc = sqlite3_create_function( db, "legacy_count", 0, SQLITE_ANY, 0, null,
  1410. legacyCountStep, legacyCountFinalize
  1411. );
  1412. }
  1413. #endif
  1414. if ( sqlite3TestErrCode( interp, db, rc ) != 0 )
  1415. return TCL.TCL_ERROR;
  1416. TCL.Tcl_SetResult( interp, t1ErrorName( rc ), 0 );
  1417. return TCL.TCL_OK;
  1418. }
  1419. /*
  1420. ** Usage: printf TEXT
  1421. **
  1422. ** Send output to printf. Use this rather than puts to merge the output
  1423. ** in the correct sequence with debugging printfs inserted into C code.
  1424. ** Puts uses a separate buffer and debugging statements will be out of
  1425. ** sequence if it is used.
  1426. */
  1427. //static int test_printf(
  1428. // object NotUsed,
  1429. // Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  1430. // int argc, /* Number of arguments */
  1431. // Tcl_Obj[] argv /* Text of each argument */
  1432. //){
  1433. // if( argc!=2 ){
  1434. // TCL.Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  1435. // " TEXT\"");
  1436. // return TCL.TCL_ERROR;
  1437. // }
  1438. // printf("%s\n", argv[1]);
  1439. // return TCL.TCL_OK;
  1440. //}
  1441. /*
  1442. ** Usage: sqlite3_mprintf_int FORMAT INTEGER INTEGER INTEGER
  1443. **
  1444. ** Call mprintf with three integer arguments
  1445. */
  1446. static int sqlite3_mprintf_int(
  1447. object NotUsed,
  1448. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  1449. int argc, /* Number of arguments */
  1450. Tcl_Obj[] argv /* Text of each argument */
  1451. )
  1452. {
  1453. long[] a = new long[3];
  1454. int i;
  1455. string z;
  1456. if ( argc != 5 )
  1457. {
  1458. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  1459. " FORMAT INT INT INT\"" );
  1460. return TCL.TCL_ERROR;
  1461. }
  1462. for ( i = 2; i < 5; i++ )
  1463. {
  1464. if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 2] ) )
  1465. return TCL.TCL_ERROR;
  1466. }
  1467. z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] );
  1468. TCL.Tcl_AppendResult( interp, z );
  1469. //sqlite3DbFree(db,z);
  1470. return TCL.TCL_OK;
  1471. }
  1472. /*
  1473. ** Usage: sqlite3_mprintf_int64 FORMAT INTEGER INTEGER INTEGER
  1474. **
  1475. ** Call mprintf with three 64-bit integer arguments
  1476. */
  1477. static int sqlite3_mprintf_int64(
  1478. object NotUsed,
  1479. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  1480. int argc, /* Number of arguments */
  1481. Tcl_Obj[] argv /* Text of each argument */
  1482. )
  1483. {
  1484. int i;
  1485. sqlite3_int64[] a = new sqlite3_int64[3];
  1486. string z;
  1487. if ( argc != 5 )
  1488. {
  1489. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  1490. " FORMAT INT INT INT\"" );
  1491. return TCL.TCL_ERROR;
  1492. }
  1493. for ( i = 2; i < 5; i++ )
  1494. {
  1495. if ( sqlite3Atoi64( argv[i].ToString(), ref a[i - 2], argv[i].ToString().Length, SQLITE_UTF8 ) != 0 )
  1496. {
  1497. TCL.Tcl_AppendResult( interp, "argument is not a valid 64-bit integer" );
  1498. return TCL.TCL_ERROR;
  1499. }
  1500. }
  1501. z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] );
  1502. TCL.Tcl_AppendResult( interp, z );
  1503. //sqlite3DbFree(db,z);
  1504. return TCL.TCL_OK;
  1505. }
  1506. /*
  1507. ** Usage: sqlite3_mprintf_long FORMAT INTEGER INTEGER INTEGER
  1508. **
  1509. ** Call mprintf with three long integer arguments. This might be the
  1510. ** same as sqlite3_mprintf_int or sqlite3_mprintf_int64, depending on
  1511. ** platform.
  1512. */
  1513. static int sqlite3_mprintf_long(
  1514. object NotUsed,
  1515. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  1516. int argc, /* Number of arguments */
  1517. Tcl_Obj[] argv /* Text of each argument */
  1518. )
  1519. {
  1520. int i;
  1521. long[] a = new long[3];
  1522. long[] b = new long[3];
  1523. string z;
  1524. if ( argc != 5 )
  1525. {
  1526. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  1527. " FORMAT INT INT INT\"" );
  1528. return TCL.TCL_ERROR;
  1529. }
  1530. for ( i = 2; i < 5; i++ )
  1531. {
  1532. if ( TCL.Tcl_GetLong( interp, argv[i], out b[i - 2] ) )
  1533. return TCL.TCL_ERROR;
  1534. a[i - 2] = b[i - 2];
  1535. //a[i-2] &= (((u64)1)<<(sizeof(int)*8))-1;
  1536. }
  1537. z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], a[2] );
  1538. TCL.Tcl_AppendResult( interp, z );
  1539. ////sqlite3_free(z);
  1540. return TCL.TCL_OK;
  1541. }
  1542. /*
  1543. ** Usage: sqlite3_mprintf_str FORMAT INTEGER INTEGER STRING
  1544. **
  1545. ** Call mprintf with two integer arguments and one string argument
  1546. */
  1547. static int sqlite3_mprintf_str(
  1548. object NotUsed,
  1549. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  1550. int argc, /* Number of arguments */
  1551. Tcl_Obj[] argv /* Text of each argument */
  1552. )
  1553. {
  1554. long[] a = new long[3];
  1555. int i;
  1556. string z;
  1557. if ( argc < 4 || argc > 5 )
  1558. {
  1559. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  1560. " FORMAT INT INT ?STRING?\"" );
  1561. return TCL.TCL_ERROR;
  1562. }
  1563. for ( i = 2; i < 4; i++ )
  1564. {
  1565. if ( TCL.Tcl_GetLong( interp, argv[i], out a[i - 2] ) )
  1566. return TCL.TCL_ERROR;
  1567. }
  1568. z = sqlite3_mprintf( argv[1].ToString(), a[0], a[1], argc > 4 ? argv[4].ToString() : null );
  1569. TCL.Tcl_AppendResult( interp, z );
  1570. //sqlite3DbFree(db,z);
  1571. return TCL.TCL_OK;
  1572. }
  1573. /*
  1574. ** Usage: sqlite3_snprintf_str INTEGER FORMAT INTEGER INTEGER STRING
  1575. **
  1576. ** Call mprintf with two integer arguments and one string argument
  1577. */
  1578. static int sqlite3_snprintf_str(
  1579. object NotUsed,
  1580. Tcl_Interp interp, /* The TCL interpreter that invoked this command */
  1581. int argc, /* Number of arguments */
  1582. Tcl_Obj[] argv /* Text of each argument */
  1583. )
  1584. {
  1585. long[] a = new long[3];
  1586. int i;
  1587. int n = 0;
  1588. StringBuilder z;
  1589. if ( argc < 5 || argc > 6 )
  1590. {
  1591. TCL.Tcl_AppendResult( interp, "wrong # args: should be \"", argv[0],
  1592. " INT FORMAT INT INT ?STRING?\"" );
  1593. return TCL.TCL_ERROR;
  1594. }
  1595. i

Large files files are truncated, but you can click here to view the full file