/ Check-in [307b5500]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add new sqlite3_open() and sqlite3_open16() APIs. (CVS 1423)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:307b55006c401f10ec5fa5b12cc7d5ba860f9a46
User & Date: danielk1977 2004-05-21 01:47:27
Context
2004-05-21
02:11
Fix typo in bind.test that was causing a seg-fault. (CVS 1424) check-in: d1af1a4a user: danielk1977 tags: trunk
01:47
Add new sqlite3_open() and sqlite3_open16() APIs. (CVS 1423) check-in: 307b5500 user: danielk1977 tags: trunk
01:29
Sorting bug fixes. Now only 17 tests fail. (CVS 1422) check-in: 0736b7e8 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/main.c.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1051
1052
1053
1054
1055
1056
1057




1058






1059
1060
1061
1062
1063
1064




1065























1066
1067
1068
1069
1070
1071
1072
....
1207
1208
1209
1210
1211
1212
1213
















































































































1214
1215
1216
1217
1218
1219
1220
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.178 2004/05/20 22:16:29 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
  if( !zFilename ){
    btree_flags |= BTREE_MEMORY;
  }

  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags);
}





const char *sqlite3_errmsg(sqlite3 *db){






  if( db->zErrMsg ){
    return db->zErrMsg;
  }
  return sqlite3_error_string(db->errCode);
}





const void *sqlite3_errmsg16(sqlite3 *db){























  if( !db->zErrMsg16 ){
    char const *zErr8 = sqlite3_errmsg(db);
    if( SQLITE3_BIGENDIAN ){
      db->zErrMsg16 = sqlite3utf8to16be(zErr8, -1);
    }else{
      db->zErrMsg16 = sqlite3utf8to16le(zErr8, -1);
    }
................................................................................
    */
    int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
    *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
  }
 
  return rc;
}


















































































































#if 0

/*
** sqlite3_open
**







|







 







>
>
>
>

>
>
>
>
>
>






>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
....
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
....
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
**
*************************************************************************
** Main file for the SQLite library.  The routines in this file
** implement the programmer interface to the library.  Routines in
** other files are for internal use by SQLite and should not be
** accessed by users of the library.
**
** $Id: main.c,v 1.179 2004/05/21 01:47:27 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
................................................................................
  if( !zFilename ){
    btree_flags |= BTREE_MEMORY;
  }

  return sqlite3BtreeOpen(zFilename, ppBtree, nCache, btree_flags);
}

/*
** Return UTF-8 encoded English language explanation of the most recent
** error.
*/
const char *sqlite3_errmsg(sqlite3 *db){
  if( !db ){
    /* If db is NULL, then assume that a malloc() failed during an
    ** sqlite3_open() call.
    */
    return sqlite3_error_string(SQLITE_NOMEM);
  }
  if( db->zErrMsg ){
    return db->zErrMsg;
  }
  return sqlite3_error_string(db->errCode);
}

/*
** Return UTF-16 encoded English language explanation of the most recent
** error.
*/
const void *sqlite3_errmsg16(sqlite3 *db){
  if( !db ){
    /* If db is NULL, then assume that a malloc() failed during an
    ** sqlite3_open() call. We have a static version of the string 
    ** "out of memory" encoded using UTF-16 just for this purpose.
    **
    ** Because all the characters in the string are in the unicode
    ** range 0x00-0xFF, if we pad the big-endian string with a 
    ** zero byte, we can obtain the little-endian string with
    ** &big_endian[1].
    */
    static char outOfMemBe[] = {
      0, 'o', 0, 'u', 0, 't', 0, ' ', 
      0, 'o', 0, 'f', 0, ' ', 
      0, 'm', 0, 'e', 0, 'm', 0, 'o', 0, 'r', 0, 'y', 0, 0, 0
    };
    static char *outOfMemLe = &outOfMemBe[1];

    if( SQLITE3_BIGENDIAN ){
      return (void *)outOfMemBe;
    }else{
      return (void *)outOfMemLe;
    }
  }
  if( !db->zErrMsg16 ){
    char const *zErr8 = sqlite3_errmsg(db);
    if( SQLITE3_BIGENDIAN ){
      db->zErrMsg16 = sqlite3utf8to16be(zErr8, -1);
    }else{
      db->zErrMsg16 = sqlite3utf8to16le(zErr8, -1);
    }
................................................................................
    */
    int chars_parsed = sqlite3utf8CharLen(zSql8, zTail8-zSql8);
    *pzTail = (u8 *)zSql + sqlite3utf16ByteLen(zSql, chars_parsed);
  }
 
  return rc;
}

/*
** This routine does the work of opening a database on behalf of
** sqlite3_open() and sqlite3_open16(). The database filename "zFilename"  
** is UTF-8 encoded. The fourth argument, "def_enc" is one of the TEXT_*
** macros from sqliteInt.h. If we end up creating a new database file
** (not opening an existing one), the text encoding of the database
** will be set to this value.
*/
static int openDatabase(
  const char *zFilename, /* Database filename UTF-8 encoded */
  sqlite3 **ppDb,        /* OUT: Returned database handle */
  const char **options,  /* Null terminated list of db options, or null */
  u8 def_enc             /* One of TEXT_Utf8, TEXT_Utf16le or TEXT_Utf16be */
){
  sqlite3 *db;
  int rc, i;
  char *zErrMsg = 0;

  /* Allocate the sqlite data structure */
  db = sqliteMalloc( sizeof(sqlite) );
  if( db==0 ) goto opendb_out;
  db->onError = OE_Default;
  db->priorNewRowid = 0;
  db->magic = SQLITE_MAGIC_BUSY;
  db->nDb = 2;
  db->aDb = db->aDbStatic;
  /* db->flags |= SQLITE_ShortColNames; */
  sqlite3HashInit(&db->aFunc, SQLITE_HASH_STRING, 1);
  sqlite3HashInit(&db->aCollSeq, SQLITE_HASH_STRING, 0);
  for(i=0; i<db->nDb; i++){
    sqlite3HashInit(&db->aDb[i].tblHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].idxHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].trigHash, SQLITE_HASH_STRING, 0);
    sqlite3HashInit(&db->aDb[i].aFKey, SQLITE_HASH_STRING, 1);
  }
  db->pDfltColl =
     sqlite3ChangeCollatingFunction(db, "BINARY", 6, 0, binaryCollatingFunc);
  
  /* Open the backend database driver */
  if( zFilename[0]==':' && strcmp(zFilename,":memory:")==0 ){
    db->temp_store = 2;
  }
  rc = sqlite3BtreeFactory(db, zFilename, 0, MAX_PAGES, &db->aDb[0].pBt);
  if( rc!=SQLITE_OK ){
    /* FIX ME: sqlite3BtreeFactory() should call sqlite3Error(). */
    sqlite3Error(db, rc, 0);
    db->magic = SQLITE_MAGIC_CLOSED;
    goto opendb_out;
  }
  db->aDb[0].zName = "main";
  db->aDb[1].zName = "temp";

  /* Attempt to read the schema */
  sqlite3RegisterBuiltinFunctions(db);
  rc = sqlite3Init(db, &zErrMsg);
  if( sqlite3_malloc_failed ){
    sqlite3_close(db);
    db = 0;
    goto opendb_out;
  }else if( rc!=SQLITE_OK && rc!=SQLITE_BUSY ){
    sqlite3Error(db, rc, "%s", zErrMsg, 0);
    db->magic = SQLITE_MAGIC_CLOSED;
  }else{
    db->magic = SQLITE_MAGIC_OPEN;
  }
  if( zErrMsg ) sqliteFree(zErrMsg);

opendb_out:
  *ppDb = db;
  return sqlite3_errcode(db);
}

/*
** Open a new database handle.
*/
int sqlite3_open_new(
  const char *zFilename, 
  sqlite3 **ppDb, 
  const char **options
){
  return openDatabase(zFilename, ppDb, options, TEXT_Utf8);
}

/*
** Open a new database handle.
*/
int sqlite3_open16(
  const void *zFilename, 
  sqlite3 **ppDb, 
  const char **options
){
  char *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
  int rc;

  assert( ppDb );

  zFilename8 = sqlite3utf16to8(zFilename, -1);
  if( !zFilename8 ){
    *ppDb = 0;
    return SQLITE_NOMEM;
  }

  if( SQLITE3_BIGENDIAN ){
    rc = openDatabase(zFilename8, ppDb, options, TEXT_Utf16be);
  }else{
    rc = openDatabase(zFilename8, ppDb, options, TEXT_Utf16le);
  }

  sqliteFree(zFilename8);
  return rc;
}


#if 0

/*
** sqlite3_open
**

Changes to src/sqlite.h.in.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
...
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
...
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
...
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
...
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
....
1021
1022
1023
1024
1025
1026
1027





















1028
1029
1030
1031
1032
1033
1034
....
1036
1037
1038
1039
1040
1041
1042













1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.66 2004/05/20 11:00:52 danielk1977 Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
*/
/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */

/*
** Register a function that is called at every invocation of sqlite3_exec()
** or sqlite3_compile().  This function can be used (for example) to generate
** a log file of all SQL executed against a database.
*/
void *sqlite3_trace(sqlite*, void(*xTrace)(void*,const char*), void*);

/*** The Callback-Free API
** 
** The following routines implement a new way to access SQLite that does not
................................................................................
** If sqlite3_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_reset(sqlite_vm*, char **pzErrMsg);

/*
** If the SQL that was handed to sqlite3_compile contains variables that
** are represeted in the SQL text by a question mark ('?').  This routine
** is used to assign values to those variables.
**
** The first parameter is a virtual machine obtained from sqlite3_compile().
** The 2nd "idx" parameter determines which variable in the SQL statement
** to bind the value to.  The left most '?' is 1.  The 3rd parameter is
** the value to assign to that variable.  The 4th parameter is the number
** of bytes in the value, including the terminating \000 for strings.
** Finally, the 5th "copy" parameter is TRUE if SQLite should make its
** own private copy of this value, or false if the space that the 3rd
** parameter points to will be unchanging and can be used directly by
................................................................................
** Unbound variables are treated as having a value of NULL.  To explicitly
** set a variable to NULL, call this routine with the 3rd parameter as a
** NULL pointer.
**
** If the 4th "len" parameter is -1, then strlen() is used to find the
** length.
**
** This routine can only be called immediately after sqlite3_compile()
** or sqlite3_reset() and before any calls to sqlite3_step().
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_bind(sqlite_vm*, int idx, const char *value, int len, int copy);

/*
................................................................................

/* FIX ME */
typedef sqlite_vm sqlite3_stmt;
typedef sqlite sqlite3;

/*
** This routine is used to bind a 32-bit integer value to a variable
** in an SQL statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously
** obtained from a call to sqlite3_compile(). The second parameter "i"
** determines the parameter to bind the value "iValue" to.
*/
int sqlite3_bind_int32(sqlite3_stmt*, int i, int iValue);

/*
** This routine is used to bind a 64-bit integer value to a variable
** in an SQL statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously
** obtained from a call to sqlite3_compile(). The second parameter "i"
** determines the parameter to bind the value "iValue" to.
*/
int sqlite3_bind_int64(sqlite3_stmt*, int i, long long int iValue);

/*
** This routine is used to bind a real (floating point) value to a variable
** in an SQL statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_compile(). The second parameter "i" determines
** the parameter to bind the value "iValue" to. Internally, SQLite will
** manipulate the value as a 64-bit IEEE float.
*/
int sqlite3_bind_double(sqlite3_stmt*, int i, double iValue);

/*
** This routine is used to bind a NULL value to a variable in an SQL
** statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_compile(). The second parameter "i" determines
** the parameter to bind the NULL value to.
*/
int sqlite3_bind_null(sqlite3_stmt*, int i);

/*
** This routine is used to bind a UTF-8 string value to a variable in an
** SQL statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_compile(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer
** to the UTF-8 string. 
**
** The fourth "n" parameter is the number of bytes (not characters) in the
** string pointed to by "z". "n" may or may not include any nul terminator
** character. If "n" is less than zero, then SQLite assumes that "z" is
** a nul terminated string.
................................................................................
** string data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_text(sqlite3_stmt*, int i, const char* z, int n, int eCopy);

/*
** This routine is used to bind a UTF-16 string value to a variable in an
** SQL statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_compile(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer to
** the UTF-16 string. If the string does not begin with a byte-order-mark,
** it is assumed to be encoded in the native byte order of the machine.
**
** The fourth "n" parameter is the number of bytes (not characters) in the
** string pointed to by "z". "n" may or may not include any nul terminator
** character. If "n" is less than zero, then SQLite assumes that "z" is
................................................................................
** string data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_text16(sqlite3_stmt*, int i, const void *z, int, int eCopy);

/*
** This routine is used to bind a blob value to a variable in an
** SQL statement compiled by sqlite3_compile(). See comments for
** sqlite3_compile() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_compile(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer to
** the blob of data.
**
** The fourth "n" parameter is the number of bytes in the blob pointed to
** by "z". "n" may not be less than zero.
**
** If paramater "eCopy" is true, then SQLite makes a copy of the blob
................................................................................
** The returned string is always terminated by a pair of 0x00 bytes.
**
** The string "not an error" is returned when the most recent API call was
** successful.
*/
const void *sqlite3_errmsg16(sqlite3*);






















int sqlite3_prepare(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nBytes,             /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
................................................................................
int sqlite3_prepare16(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nBytes,             /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);














#if 0

int sqlite3_open(const char*, sqlite3**, const char**);
int sqlite3_open16(const void*, sqlite3**, const char**);
int sqlite3_close(sqlite3*);

int sqlite3_finalize(sqlite3_stmt*);
int sqlite3_reset(sqlite3_stmt*);

int sqlite3_step(sqlite3_stmt*);








|







 







|







 







|



|







 







|







 







|
|


|






|
|


|






|
|


|







|
|


|






|
|


|







 







|
|


|







 







|
|


|







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>



<
<







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
...
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
...
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
...
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
...
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
....
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
....
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079


1080
1081
1082
1083
1084
1085
1086
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This header file defines the interface that the SQLite library
** presents to client programs.
**
** @(#) $Id: sqlite.h.in,v 1.67 2004/05/21 01:47:27 danielk1977 Exp $
*/
#ifndef _SQLITE_H_
#define _SQLITE_H_
#include <stdarg.h>     /* Needed for the definition of va_list */

/*
** Make sure we can call this stuff from C++.
................................................................................
*/
/* #define SQLITE_OK  0   // Allow access (This is actually defined above) */
#define SQLITE_DENY   1   /* Abort the SQL statement with an error */
#define SQLITE_IGNORE 2   /* Don't allow access, but don't generate an error */

/*
** Register a function that is called at every invocation of sqlite3_exec()
** or sqlite3_prepare().  This function can be used (for example) to generate
** a log file of all SQL executed against a database.
*/
void *sqlite3_trace(sqlite*, void(*xTrace)(void*,const char*), void*);

/*** The Callback-Free API
** 
** The following routines implement a new way to access SQLite that does not
................................................................................
** If sqlite3_reset() returns SQLITE_SCHEMA, then *ppVm is set to NULL.
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_reset(sqlite_vm*, char **pzErrMsg);

/*
** If the SQL that was handed to sqlite3_prepare contains variables that
** are represeted in the SQL text by a question mark ('?').  This routine
** is used to assign values to those variables.
**
** The first parameter is a virtual machine obtained from sqlite3_prepare().
** The 2nd "idx" parameter determines which variable in the SQL statement
** to bind the value to.  The left most '?' is 1.  The 3rd parameter is
** the value to assign to that variable.  The 4th parameter is the number
** of bytes in the value, including the terminating \000 for strings.
** Finally, the 5th "copy" parameter is TRUE if SQLite should make its
** own private copy of this value, or false if the space that the 3rd
** parameter points to will be unchanging and can be used directly by
................................................................................
** Unbound variables are treated as having a value of NULL.  To explicitly
** set a variable to NULL, call this routine with the 3rd parameter as a
** NULL pointer.
**
** If the 4th "len" parameter is -1, then strlen() is used to find the
** length.
**
** This routine can only be called immediately after sqlite3_prepare()
** or sqlite3_reset() and before any calls to sqlite3_step().
**
******* THIS IS AN EXPERIMENTAL API AND IS SUBJECT TO CHANGE ******
*/
int sqlite3_bind(sqlite_vm*, int idx, const char *value, int len, int copy);

/*
................................................................................

/* FIX ME */
typedef sqlite_vm sqlite3_stmt;
typedef sqlite sqlite3;

/*
** This routine is used to bind a 32-bit integer value to a variable
** in an SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously
** obtained from a call to sqlite3_prepare(). The second parameter "i"
** determines the parameter to bind the value "iValue" to.
*/
int sqlite3_bind_int32(sqlite3_stmt*, int i, int iValue);

/*
** This routine is used to bind a 64-bit integer value to a variable
** in an SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously
** obtained from a call to sqlite3_prepare(). The second parameter "i"
** determines the parameter to bind the value "iValue" to.
*/
int sqlite3_bind_int64(sqlite3_stmt*, int i, long long int iValue);

/*
** This routine is used to bind a real (floating point) value to a variable
** in an SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the value "iValue" to. Internally, SQLite will
** manipulate the value as a 64-bit IEEE float.
*/
int sqlite3_bind_double(sqlite3_stmt*, int i, double iValue);

/*
** This routine is used to bind a NULL value to a variable in an SQL
** statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the NULL value to.
*/
int sqlite3_bind_null(sqlite3_stmt*, int i);

/*
** This routine is used to bind a UTF-8 string value to a variable in an
** SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer
** to the UTF-8 string. 
**
** The fourth "n" parameter is the number of bytes (not characters) in the
** string pointed to by "z". "n" may or may not include any nul terminator
** character. If "n" is less than zero, then SQLite assumes that "z" is
** a nul terminated string.
................................................................................
** string data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_text(sqlite3_stmt*, int i, const char* z, int n, int eCopy);

/*
** This routine is used to bind a UTF-16 string value to a variable in an
** SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer to
** the UTF-16 string. If the string does not begin with a byte-order-mark,
** it is assumed to be encoded in the native byte order of the machine.
**
** The fourth "n" parameter is the number of bytes (not characters) in the
** string pointed to by "z". "n" may or may not include any nul terminator
** character. If "n" is less than zero, then SQLite assumes that "z" is
................................................................................
** string data remains stable until after the SQL statement has been
** finalised or another value bound to variable "i".
*/
int sqlite3_bind_text16(sqlite3_stmt*, int i, const void *z, int, int eCopy);

/*
** This routine is used to bind a blob value to a variable in an
** SQL statement compiled by sqlite3_prepare(). See comments for
** sqlite3_prepare() for more details on SQL statement variables.
**
** The first argument is a pointer to an SQL statement previously obtained
** from a call to sqlite3_prepare(). The second parameter "i" determines
** the parameter to bind the value to. Parameter three "z" is a pointer to
** the blob of data.
**
** The fourth "n" parameter is the number of bytes in the blob pointed to
** by "z". "n" may not be less than zero.
**
** If paramater "eCopy" is true, then SQLite makes a copy of the blob
................................................................................
** The returned string is always terminated by a pair of 0x00 bytes.
**
** The string "not an error" is returned when the most recent API call was
** successful.
*/
const void *sqlite3_errmsg16(sqlite3*);

/*
** To execute an SQL query, it must first be compiled into a byte-code
** program using this routine. The first parameter "db" is an SQLite
** database handle. The second parameter "zSql" is the statement
** to be compiled, encoded as UTF-8 text. If the next parameter, "nBytes",
** is less than zero, then zSql is read up to the first nul terminator.
** If "nBytes" is not less than zero, then it is the length of the
** string zSql, in bytes (not characters).
**
** *pzTail is made to point to the first character past the end of the first
** SQL statement in zSql.  This routine only compiles the first statement
** in zSql, so *pzTail is left pointing to what remains uncompiled.
**
** *ppStmt is left pointing to a compiled SQL statement that can be
** executed using sqlite3_step().  Or if there is an error, *ppStmt may be
** set to NULL.  If the input text contained no SQL (if the input is and
** empty string or a comment) then *ppStmt is set to NULL.
**
** On success, SQLITE_OK is returned.  Otherwise an error code is returned.
** 
*/
int sqlite3_prepare(
  sqlite3 *db,            /* Database handle */
  const char *zSql,       /* SQL statement, UTF-8 encoded */
  int nBytes,             /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const char **pzTail     /* OUT: Pointer to unused portion of zSql */
);
................................................................................
int sqlite3_prepare16(
  sqlite3 *db,            /* Database handle */
  const void *zSql,       /* SQL statement, UTF-16 encoded */
  int nBytes,             /* Length of zSql in bytes. */
  sqlite3_stmt **ppStmt,  /* OUT: Statement handle */
  const void **pzTail     /* OUT: Pointer to unused portion of zSql */
);

int sqlite3_open_new(
  const char *filename,   /* Database filename (UTF-8) */
  sqlite3 **ppDb,         /* OUT: SQLite db handle */
  const char **args       /* Null terminated array of option strings */
);

int sqlite3_open16(
  const void *filename,   /* Database filename (UTF-16) */
  sqlite3 **ppDb,         /* OUT: SQLite db handle */
  const char **args       /* Null terminated array of option strings */
);


#if 0



int sqlite3_close(sqlite3*);

int sqlite3_finalize(sqlite3_stmt*);
int sqlite3_reset(sqlite3_stmt*);

int sqlite3_step(sqlite3_stmt*);

Changes to src/sqliteInt.h.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
278
279
280
281
282
283
284

285
286
287
288
289
290
291
...
311
312
313
314
315
316
317






318
319
320
321
322
323
324
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.242 2004/05/21 01:29:06 drh Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u16 flags;           /* Flags associated with this database */
  void *pAux;          /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */

};

/*
** These macros can be used to test, set, or clear bits in the 
** Db.flags field.
*/
#define DbHasProperty(D,I,P)     (((D)->aDb[I].flags&(P))==(P))
................................................................................
** changes and so the view will need to be reset.
*/
#define DB_Locked          0x0001  /* OP_Transaction opcode has been emitted */
#define DB_Cookie          0x0002  /* OP_VerifyCookie opcode has been emiited */
#define DB_SchemaLoaded    0x0004  /* The schema has been loaded */
#define DB_UnresetViews    0x0008  /* Some views have defined column names */








/*
** Each database is an instance of the following structure.
**
** The sqlite.file_format is initialized by the database file
** and helps determines how the data in the database file is
** represented.  This field allows newer versions of the library







|







 







>







 







>
>
>
>
>
>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Internal interface definitions for SQLite.
**
** @(#) $Id: sqliteInt.h,v 1.243 2004/05/21 01:47:27 danielk1977 Exp $
*/
#include "config.h"
#include "sqlite.h"
#include "hash.h"
#include "parse.h"
#include <stdio.h>
#include <stdlib.h>
................................................................................
  Hash idxHash;        /* All (named) indices indexed by name */
  Hash trigHash;       /* All triggers indexed by name */
  Hash aFKey;          /* Foreign keys indexed by to-table */
  u8 inTrans;          /* 0: not writable.  1: Transaction.  2: Checkpoint */
  u16 flags;           /* Flags associated with this database */
  void *pAux;          /* Auxiliary data.  Usually NULL */
  void (*xFreeAux)(void*);  /* Routine to free pAux */
  u8 textEnc;          /* Text encoding for this database. */
};

/*
** These macros can be used to test, set, or clear bits in the 
** Db.flags field.
*/
#define DbHasProperty(D,I,P)     (((D)->aDb[I].flags&(P))==(P))
................................................................................
** changes and so the view will need to be reset.
*/
#define DB_Locked          0x0001  /* OP_Transaction opcode has been emitted */
#define DB_Cookie          0x0002  /* OP_VerifyCookie opcode has been emiited */
#define DB_SchemaLoaded    0x0004  /* The schema has been loaded */
#define DB_UnresetViews    0x0008  /* Some views have defined column names */

/*
** Possible values for the Db.textEnc field.
*/
#define TEXT_Utf8             1
#define TEXT_Utf16le          2
#define TEXT_Utf16be          3

/*
** Each database is an instance of the following structure.
**
** The sqlite.file_format is initialized by the database file
** and helps determines how the data in the database file is
** represented.  This field allows newer versions of the library

Changes to src/test1.c.

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
...
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
....
1326
1327
1328
1329
1330
1331
1332

1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352





1353


1354
1355

1356
1357
1358
1359
1360
1361
1362
....
1396
1397
1398
1399
1400
1401
1402
1403
1404

1405

1406
1407
1408
1409























































1410
1411
1412
1413
1414
1415
1416
....
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
....
1500
1501
1502
1503
1504
1505
1506


1507
1508
1509
1510
1511
1512
1513
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.43 2004/05/20 22:16:30 drh Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
         "SQLite and what computer you are running on.", 0);
      return TCL_ERROR;
    }
  }
  return TCL_OK;
}

/*
** Usage:   sqlite3_open filename
**
** Returns:  The name of an open database.
*/
static int sqlite_test_open(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite *db;
  char *zErr = 0;
  char zBuf[100];
  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  db = sqlite3_open(argv[1], 0666, &zErr);
  if( db==0 ){
    Tcl_AppendResult(interp, zErr, 0);
    free(zErr);
    return TCL_ERROR;
  }
  if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

/*
** The callback routine for sqlite3_exec_printf().
*/
static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){
  Tcl_DString *str = (Tcl_DString*)pArg;
  int i;

................................................................................
  if( rc!=0 && rc!=SQLITE_ABORT ){
    Tcl_AppendResult(interp, sqlite3_error_string(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}

/*
** Usage:  sqlite3_compile  DB  SQL  ?TAILVAR?
**
** Attempt to compile an SQL statement.  Return a pointer to the virtual
** machine used to execute that statement.  Unprocessed SQL is written
** into TAILVAR.
*/
static int test_compile(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  char **argv            /* Text of each argument */
){
  sqlite *db;
  sqlite_vm *vm;
  int rc;
  char *zErr = 0;
  const char *zTail;
  char zBuf[50];
  if( argc!=3 && argc!=4 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], 
       " DB SQL TAILVAR", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  rc = sqlite3_compile(db, argv[2], argc==4 ? &zTail : 0, &vm, &zErr);
  if( argc==4 ) Tcl_SetVar(interp, argv[3], zTail, 0);
  if( rc ){
    assert( vm==0 );
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, zErr, 0);
    sqlite3_freemem(zErr);
    return TCL_ERROR;
  }
  if( vm ){
    if( makePointerStr(interp, zBuf, vm) ) return TCL_ERROR;
    Tcl_AppendResult(interp, zBuf, 0);
  }
  return TCL_OK;
}

/*
** Usage:  sqlite3_step  VM  ?NVAR?  ?VALUEVAR?  ?COLNAMEVAR?
**
** Step a virtual machine.  Return a the result code as a string.
** Column results are written into three variables.
*/
static int test_step(
................................................................................
){
  sqlite3 *db;
  const char *zSql;
  int bytes;
  const char *zTail = 0;
  sqlite3_stmt *pStmt = 0;
  char zBuf[50];


  if( objc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSql = Tcl_GetString(objv[2]);
  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;

  if( SQLITE_OK!=sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail) ){
    return TCL_ERROR;
  }

  if( zTail ){
    if( bytes>=0 ){
      bytes = bytes - (zTail-zSql);
    }
    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
  }








  if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);

  return TCL_OK;
}

/*
** Usage: sqlite3_prepare DB sql bytes tailvar
**
** Compile up to <bytes> bytes of the supplied SQL string <sql> using
................................................................................
    objlen = objlen - ((u8 *)zTail-(u8 *)zSql);
  }else{
    objlen = 0;
  }
  pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
  Tcl_IncrRefCount(pTail);
  Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
  // Tcl_DecrRefCount(pTail);


  if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;

  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

























































/*
** This is a collating function named "REVERSE" which sorts text
** in reverse order.
*/
static int reverseCollatingFunc(
  void *NotUsed,
................................................................................
     Tcl_CmdProc *xProc;
  } aCmd[] = {
     { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
     { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
     { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
     { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
     { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
     { "sqlite3_open",                  (Tcl_CmdProc*)sqlite_test_open      },
     { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
     { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
     { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
     { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
     { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
     { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
     { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
     { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
     { "sqlite_datatypes",              (Tcl_CmdProc*)sqlite_datatypes      },
#ifdef MEMORY_DEBUG
     { "sqlite_malloc_fail",            (Tcl_CmdProc*)sqlite_malloc_fail    },
     { "sqlite_malloc_stat",            (Tcl_CmdProc*)sqlite_malloc_stat    },
#endif
     { "sqlite_compile",                (Tcl_CmdProc*)test_compile          },
     { "sqlite_step",                   (Tcl_CmdProc*)test_step             },
     { "sqlite_finalize",               (Tcl_CmdProc*)test_finalize         },
     { "sqlite_bind",                   (Tcl_CmdProc*)test_bind             },
     { "sqlite_reset",                  (Tcl_CmdProc*)test_reset            },
     { "breakpoint",                    (Tcl_CmdProc*)test_breakpoint       },
  };
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
  } aObjCmd[] = {
     { "sqlite3_bind_int32",            (Tcl_ObjCmdProc*)test_bind_int32    },
     { "sqlite3_bind_int64",            (Tcl_ObjCmdProc*)test_bind_int64    },
................................................................................
     { "sqlite3_bind_text16",           (Tcl_ObjCmdProc*)test_bind_text16   },
     { "sqlite3_bind_blob",             (Tcl_ObjCmdProc*)test_bind_blob     },
     { "sqlite3_errcode",               (Tcl_ObjCmdProc*)test_errcode       },
     { "sqlite3_errmsg",                (Tcl_ObjCmdProc*)test_errmsg        },
     { "sqlite3_errmsg16",              (Tcl_ObjCmdProc*)test_errmsg16      },
     { "sqlite3_prepare",               (Tcl_ObjCmdProc*)test_prepare       },
     { "sqlite3_prepare16",             (Tcl_ObjCmdProc*)test_prepare16     },


     { "add_reverse_collating_func",    (Tcl_ObjCmdProc*)reverse_collfunc   },
  };
  int i;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }







|







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







 







>










|
<
<
<






>
>
>
>
>
|
>
>
|
|
>







 







|

>
|
>




>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|













<
|
|
|
|
|







 







>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
...
128
129
130
131
132
133
134






























135
136
137
138
139
140
141
...
747
748
749
750
751
752
753









































754
755
756
757
758
759
760
....
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273



1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
....
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
....
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475

1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
....
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the printf() interface to SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test1.c,v 1.44 2004/05/21 01:47:27 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

................................................................................
         "SQLite and what computer you are running on.", 0);
      return TCL_ERROR;
    }
  }
  return TCL_OK;
}































/*
** The callback routine for sqlite3_exec_printf().
*/
static int exec_printf_cb(void *pArg, int argc, char **argv, char **name){
  Tcl_DString *str = (Tcl_DString*)pArg;
  int i;

................................................................................
  if( rc!=0 && rc!=SQLITE_ABORT ){
    Tcl_AppendResult(interp, sqlite3_error_string(rc), 0);
    return TCL_ERROR;
  }
  return TCL_OK;
}










































/*
** Usage:  sqlite3_step  VM  ?NVAR?  ?VALUEVAR?  ?COLNAMEVAR?
**
** Step a virtual machine.  Return a the result code as a string.
** Column results are written into three variables.
*/
static int test_step(
................................................................................
){
  sqlite3 *db;
  const char *zSql;
  int bytes;
  const char *zTail = 0;
  sqlite3_stmt *pStmt = 0;
  char zBuf[50];
  int rc;

  if( objc!=5 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " DB sql bytes tailvar", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  zSql = Tcl_GetString(objv[2]);
  if( Tcl_GetIntFromObj(interp, objv[3], &bytes) ) return TCL_ERROR;

  rc = sqlite3_prepare(db, zSql, bytes, &pStmt, &zTail);



  if( zTail ){
    if( bytes>=0 ){
      bytes = bytes - (zTail-zSql);
    }
    Tcl_ObjSetVar2(interp, objv[4], 0, Tcl_NewStringObj(zTail, bytes), 0);
  }
  if( rc!=SQLITE_OK ){
    assert( pStmt==0 );
    sprintf(zBuf, "(%d) ", rc);
    Tcl_AppendResult(interp, zBuf, sqlite3_errmsg(db), 0);
    return TCL_ERROR;
  }

  if( pStmt ){
    if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
    Tcl_AppendResult(interp, zBuf, 0);
  }
  return TCL_OK;
}

/*
** Usage: sqlite3_prepare DB sql bytes tailvar
**
** Compile up to <bytes> bytes of the supplied SQL string <sql> using
................................................................................
    objlen = objlen - ((u8 *)zTail-(u8 *)zSql);
  }else{
    objlen = 0;
  }
  pTail = Tcl_NewByteArrayObj((u8 *)zTail, objlen);
  Tcl_IncrRefCount(pTail);
  Tcl_ObjSetVar2(interp, objv[4], 0, pTail, 0);
  Tcl_DecrRefCount(pTail);

  if( pStmt ){
    if( makePointerStr(interp, zBuf, pStmt) ) return TCL_ERROR;
  }
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

/*
** Usage: sqlite3_open filename ?options-list?
*/
static int test_open(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  const char *zFilename;
  sqlite3 *db;
  int rc;
  char zBuf[100];

  if( objc!=3 && objc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " filename options-list", 0);
    return TCL_ERROR;
  }

  zFilename = Tcl_GetString(objv[1]);
  rc = sqlite3_open_new(zFilename, &db, 0);
  
  if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

/*
** Usage: sqlite3_open16 filename options
*/
static int test_open16(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  const void *zFilename;
  sqlite3 *db;
  int rc;
  char zBuf[100];

  if( objc!=3 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", 
       Tcl_GetString(objv[0]), " filename options-list", 0);
    return TCL_ERROR;
  }

  zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
  rc = sqlite3_open16(zFilename, &db, 0);
  
  if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

/*
** This is a collating function named "REVERSE" which sorts text
** in reverse order.
*/
static int reverseCollatingFunc(
  void *NotUsed,
................................................................................
     Tcl_CmdProc *xProc;
  } aCmd[] = {
     { "sqlite3_mprintf_int",           (Tcl_CmdProc*)sqlite3_mprintf_int    },
     { "sqlite3_mprintf_str",           (Tcl_CmdProc*)sqlite3_mprintf_str    },
     { "sqlite3_mprintf_double",        (Tcl_CmdProc*)sqlite3_mprintf_double },
     { "sqlite3_mprintf_scaled",        (Tcl_CmdProc*)sqlite3_mprintf_scaled },
     { "sqlite3_mprintf_z_test",        (Tcl_CmdProc*)test_mprintf_z        },
//     { "sqlite3_open",                  (Tcl_CmdProc*)sqlite_test_open      },
     { "sqlite3_last_insert_rowid",     (Tcl_CmdProc*)test_last_rowid       },
     { "sqlite3_exec_printf",           (Tcl_CmdProc*)test_exec_printf      },
     { "sqlite3_get_table_printf",      (Tcl_CmdProc*)test_get_table_printf },
     { "sqlite3_close",                 (Tcl_CmdProc*)sqlite_test_close     },
     { "sqlite3_create_function",       (Tcl_CmdProc*)test_create_function  },
     { "sqlite3_create_aggregate",      (Tcl_CmdProc*)test_create_aggregate },
     { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func    },
     { "sqlite_abort",                  (Tcl_CmdProc*)sqlite_abort          },
     { "sqlite_datatypes",              (Tcl_CmdProc*)sqlite_datatypes      },
#ifdef MEMORY_DEBUG
     { "sqlite_malloc_fail",            (Tcl_CmdProc*)sqlite_malloc_fail    },
     { "sqlite_malloc_stat",            (Tcl_CmdProc*)sqlite_malloc_stat    },
#endif

     { "sqlite_step",                    (Tcl_CmdProc*)test_step             },
     { "sqlite_finalize",                (Tcl_CmdProc*)test_finalize         },
     { "sqlite_bind",                    (Tcl_CmdProc*)test_bind             },
     { "sqlite_reset",                   (Tcl_CmdProc*)test_reset            },
     { "breakpoint",                     (Tcl_CmdProc*)test_breakpoint       },
  };
  static struct {
     char *zName;
     Tcl_ObjCmdProc *xProc;
  } aObjCmd[] = {
     { "sqlite3_bind_int32",            (Tcl_ObjCmdProc*)test_bind_int32    },
     { "sqlite3_bind_int64",            (Tcl_ObjCmdProc*)test_bind_int64    },
................................................................................
     { "sqlite3_bind_text16",           (Tcl_ObjCmdProc*)test_bind_text16   },
     { "sqlite3_bind_blob",             (Tcl_ObjCmdProc*)test_bind_blob     },
     { "sqlite3_errcode",               (Tcl_ObjCmdProc*)test_errcode       },
     { "sqlite3_errmsg",                (Tcl_ObjCmdProc*)test_errmsg        },
     { "sqlite3_errmsg16",              (Tcl_ObjCmdProc*)test_errmsg16      },
     { "sqlite3_prepare",               (Tcl_ObjCmdProc*)test_prepare       },
     { "sqlite3_prepare16",             (Tcl_ObjCmdProc*)test_prepare16     },
     { "sqlite3_open",                  (Tcl_ObjCmdProc*)test_open          },
     { "sqlite3_open16",                (Tcl_ObjCmdProc*)test_open16        },
     { "add_reverse_collating_func",    (Tcl_ObjCmdProc*)reverse_collfunc   },
  };
  int i;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }

Changes to test/attach2.test.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: attach2.test,v 1.7 2004/05/13 11:34:17 danielk1977 Exp $
#


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Ticket #354
................................................................................
} {1 {cannot commit - no transaction is active}}

# Ticket #574:  Make sure it works usingi the non-callback API
#
do_test attach2-3.1 {
  db close
  set DB [sqlite db test.db]
  set rc [catch {sqlite_compile $DB "ATTACH 'test2.db' AS t2" TAIL} VM]
  if {$rc} {lappend rc $VM}
  sqlite_finalize $VM
  set rc
} {0}
do_test attach2-3.2 {
  set rc [catch {sqlite_compile $DB "DETACH t2" TAIL} VM]
  if {$rc} {lappend rc $VM}
  sqlite_finalize $VM
  set rc
} {0}

db close
for {set i 2} {$i<=15} {incr i} {
  catch {db$i close}
}
file delete -force test2.db


finish_test







|







 







|





|













8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script is testing the ATTACH and DETACH commands
# and related functionality.
#
# $Id: attach2.test,v 1.8 2004/05/21 01:47:27 danielk1977 Exp $
#


set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Ticket #354
................................................................................
} {1 {cannot commit - no transaction is active}}

# Ticket #574:  Make sure it works usingi the non-callback API
#
do_test attach2-3.1 {
  db close
  set DB [sqlite db test.db]
  set rc [catch {sqlite3_prepare $DB "ATTACH 'test2.db' AS t2" -1 TAIL} VM]
  if {$rc} {lappend rc $VM}
  sqlite_finalize $VM
  set rc
} {0}
do_test attach2-3.2 {
  set rc [catch {sqlite3_prepare $DB "DETACH t2" -1 TAIL} VM]
  if {$rc} {lappend rc $VM}
  sqlite_finalize $VM
  set rc
} {0}

db close
for {set i 2} {$i<=15} {incr i} {
  catch {db$i close}
}
file delete -force test2.db


finish_test

Changes to test/bind.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the sqlite_bind API.
#
# $Id: bind.test,v 1.3 2004/05/20 11:00:53 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test bind-1.1 {
  db close
  set DB [sqlite db test.db]
  execsql {CREATE TABLE t1(a,b,c)}
  set VM [sqlite_compile $DB {INSERT INTO t1 VALUES(?,?,?)} TAIL]
  set TAIL
} {}
do_test bind-1.2 {
  sqlite_step $VM N VALUES COLNAMES
} {SQLITE_DONE}
do_test bind-1.3 {
  execsql {SELECT rowid, * FROM t1}
................................................................................
  sqlite_finalize $VM
} {}

do_test bind-2.1 {
  execsql {
    DELETE FROM t1;
  }
  set VM [sqlite_compile $DB {INSERT INTO t1 VALUES(?,?,?)} TAIL]
  set TAIL
} {}

# 32 bit Integers
do_test bind-2.2 {
  sqlite3_bind_int32 $VM 1 123
  sqlite3_bind_int32 $VM 2 456







|









|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the sqlite_bind API.
#
# $Id: bind.test,v 1.4 2004/05/21 01:47:27 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

do_test bind-1.1 {
  db close
  set DB [sqlite db test.db]
  execsql {CREATE TABLE t1(a,b,c)}
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(?,?,?)} -1 TAIL]
  set TAIL
} {}
do_test bind-1.2 {
  sqlite_step $VM N VALUES COLNAMES
} {SQLITE_DONE}
do_test bind-1.3 {
  execsql {SELECT rowid, * FROM t1}
................................................................................
  sqlite_finalize $VM
} {}

do_test bind-2.1 {
  execsql {
    DELETE FROM t1;
  }
  set VM [sqlite3_bind_int32 $DB {INSERT INTO t1 VALUES(?,?,?)} TAIL]
  set TAIL
} {}

# 32 bit Integers
do_test bind-2.2 {
  sqlite3_bind_int32 $VM 1 123
  sqlite3_bind_int32 $VM 2 456

Changes to test/capi2.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.10 2003/08/05 13:13:38 drh Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Check basic functionality
#
do_test capi2-1.1 {
  db close
  set DB [sqlite db test.db]
  execsql {CREATE TABLE t1(a,b,c)}
  set VM [sqlite_compile $DB {SELECT name, rowid FROM sqlite_master} TAIL]
  set TAIL
} {}
do_test capi2-1.2 {
  sqlite_step $VM N VALUES COLNAMES
} {SQLITE_ROW}
do_test capi2-1.3 {
  set N
................................................................................
  list $N $VALUES $COLNAMES
} {0 {} {}}
do_test capi2-1.10 {
  sqlite_finalize $VM
} {}

# Check to make sure that the "tail" of a multi-statement SQL script
# is returned by sqlite_compile.
#
do_test capi2-2.1 {
  set SQL {
    SELECT name, rowid FROM sqlite_master;
    SELECT name, rowid FROM sqlite_temp_master;
    -- A comment at the end
  }
  set VM [sqlite_compile $DB $SQL SQL]
  set SQL
} {
    SELECT name, rowid FROM sqlite_temp_master;
    -- A comment at the end
  }
do_test capi2-2.2 {
  set r [sqlite_step $VM n val colname]
................................................................................
  set r [sqlite_step $VM n val colname]
  lappend r $n $val $colname
} {SQLITE_DONE 2 {} {name rowid text INTEGER}}
do_test capi2-2.4 {
  sqlite_finalize $VM
} {}
do_test capi2-2.5 {
  set VM [sqlite_compile $DB $SQL SQL]
  set SQL
} {
    -- A comment at the end
  }
do_test capi2-2.6 {
  set r [sqlite_step $VM n val colname]
  lappend r $n $val $colname
} {SQLITE_DONE 2 {} {name rowid text INTEGER}}
do_test capi2-2.7 {
  sqlite_finalize $VM
} {}
do_test capi2-2.8 {
  set VM [sqlite_compile $DB $SQL SQL]
  list $SQL $VM
} {{} {}}

# Check the error handling.
#
do_test capi2-3.1 {
  set rc [catch {
      sqlite_compile $DB {select bogus from sqlite_master} TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {}}
do_test capi2-3.2 {
  set rc [catch {
      sqlite_compile $DB {select bogus from } TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) near " ": syntax error} {}}
do_test capi2-3.3 {
  set rc [catch {
      sqlite_compile $DB {;;;;select bogus from sqlite_master} TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {}}
do_test capi2-3.4 {
  set rc [catch {
      sqlite_compile $DB {select bogus from sqlite_master;x;} TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {x;}}
do_test capi2-3.5 {
  set rc [catch {
      sqlite_compile $DB {select bogus from sqlite_master;;;x;} TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {;;x;}}
do_test capi2-3.6 {
  set rc [catch {
      sqlite_compile $DB {select 5/0} TAIL
  } VM]
  lappend rc $TAIL
} {0 {}}
do_test capi2-3.7 {
  set N {}
  set VALUE {}
  set COLNAME {}
................................................................................
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ROW 1 {{}} {5/0 NUMERIC}}
do_test capi2-3.8 {
  sqlite_finalize $VM
} {}
do_test capi2-3.9 {
  execsql {CREATE UNIQUE INDEX i1 ON t1(a)}
  set VM [sqlite_compile $DB {INSERT INTO t1 VALUES(1,2,3)} TAIL]
  set TAIL
} {}
do_test capi2-3.9b {db changes} {0}
do_test capi2-3.10 {
  set N {}
  set VALUE {}
  set COLNAME {}
................................................................................
  sqlite_finalize $VM
} {}
do_test capi2-3.11b {db changes} {1}
do_test capi2-3.12 {
  list [catch {sqlite_finalize $VM} msg] [set msg]
} {1 {(21) library routine called out of sequence}}
do_test capi2-3.13 {
  set VM [sqlite_compile $DB {INSERT INTO t1 VALUES(1,3,4)} TAIL]
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ERROR 0 {} {}}
do_test capi2-3.13b {db changes} {0}
do_test capi2-3.14 {
  list [catch {sqlite_finalize $VM} msg] [set msg]
} {1 {(19) column a is not unique}}
do_test capi2-3.15 {
  set VM [sqlite_compile $DB {CREATE TABLE t2(a NOT NULL, b)} TAIL]
  set TAIL
} {}
do_test capi2-3.16 {
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_DONE 0 {} {}}
do_test capi2-3.17 {
  list [catch {sqlite_finalize $VM} msg] [set msg]
} {0 {}}
do_test capi2-3.18 {
  set VM [sqlite_compile $DB {INSERT INTO t2 VALUES(NULL,2)} TAIL]
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ERROR 0 {} {}}
do_test capi2-3.19 {
  list [catch {sqlite_finalize $VM} msg] [set msg]
} {1 {(19) t2.a may not be NULL}}

# Two or more virtual machines exists at the same time.
#
do_test capi2-4.1 {
  set VM1 [sqlite_compile $DB {INSERT INTO t2 VALUES(1,2)} TAIL]
  set TAIL
} {}
do_test capi2-4.2 {
  set VM2 [sqlite_compile $DB {INSERT INTO t2 VALUES(2,3)} TAIL]
  set TAIL
} {}
do_test capi2-4.3 {
  set VM3 [sqlite_compile $DB {INSERT INTO t2 VALUES(3,4)} TAIL]
  set TAIL
} {}
do_test capi2-4.4 {
  list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_DONE 0 {} {}}
do_test capi2-4.5 {
  execsql {SELECT * FROM t2 ORDER BY a}
................................................................................
do_test capi2-4.12 {
  list [catch {sqlite_finalize $VM1} msg] [set msg]
} {0 {}}  

# Interleaved SELECTs
#
do_test capi2-5.1 {
  set VM1 [sqlite_compile $DB {SELECT * FROM t2} TAIL]
  set VM2 [sqlite_compile $DB {SELECT * FROM t2} TAIL]
  set VM3 [sqlite_compile $DB {SELECT * FROM t2} TAIL]
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.2 {
  list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.3 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
................................................................................
    INSERT INTO t3 VALUES(1);
    INSERT INTO t3 VALUES(2);
    INSERT INTO t3 SELECT x+2 FROM t3;
    INSERT INTO t3 SELECT x+4 FROM t3;
    INSERT INTO t3 SELECT x+8 FROM t3;
    COMMIT;
  }
  set VM1 [sqlite_compile $DB {SELECT * FROM t3} TAIL]
  sqlite db2 test.db
  execsql {BEGIN} db2
} {}
do_test capi2-6.2 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_BUSY 0 {} {}}
do_test capi2-6.3 {
................................................................................
  set x [stepsql $DB {EXPLAIN SELECT * FROM t1}]
  lindex $x 0
} {0}

# Ticket #261 - make sure we can finalize before the end of a query.
#
do_test capi2-8.1 {
  set VM1 [sqlite_compile $DB {SELECT * FROM t2} TAIL]
  sqlite_finalize $VM1
} {}
  
# Tickets #384 and #385 - make sure the TAIL argument to sqlite_compile
# and all of the return pointers in sqlite_step can be null.
#
do_test capi2-9.1 {
  set VM1 [sqlite_compile $DB {SELECT * FROM t2}]
  sqlite_step $VM1
  sqlite_finalize $VM1
} {}

db2 close

finish_test







|











|







 







|







|







 







|












|







|





|





|





|





|





|







 







|







 







|







|









|









|



|



|







 







|
|
|







 







|







 







|



|



|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
..
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
..
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
...
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
...
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi2.test,v 1.11 2004/05/21 01:47:27 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Check basic functionality
#
do_test capi2-1.1 {
  db close
  set DB [sqlite db test.db]
  execsql {CREATE TABLE t1(a,b,c)}
  set VM [sqlite3_prepare $DB {SELECT name, rowid FROM sqlite_master} -1 TAIL]
  set TAIL
} {}
do_test capi2-1.2 {
  sqlite_step $VM N VALUES COLNAMES
} {SQLITE_ROW}
do_test capi2-1.3 {
  set N
................................................................................
  list $N $VALUES $COLNAMES
} {0 {} {}}
do_test capi2-1.10 {
  sqlite_finalize $VM
} {}

# Check to make sure that the "tail" of a multi-statement SQL script
# is returned by sqlite3_prepare.
#
do_test capi2-2.1 {
  set SQL {
    SELECT name, rowid FROM sqlite_master;
    SELECT name, rowid FROM sqlite_temp_master;
    -- A comment at the end
  }
  set VM [sqlite3_prepare $DB $SQL -1 SQL]
  set SQL
} {
    SELECT name, rowid FROM sqlite_temp_master;
    -- A comment at the end
  }
do_test capi2-2.2 {
  set r [sqlite_step $VM n val colname]
................................................................................
  set r [sqlite_step $VM n val colname]
  lappend r $n $val $colname
} {SQLITE_DONE 2 {} {name rowid text INTEGER}}
do_test capi2-2.4 {
  sqlite_finalize $VM
} {}
do_test capi2-2.5 {
  set VM [sqlite3_prepare $DB $SQL -1 SQL]
  set SQL
} {
    -- A comment at the end
  }
do_test capi2-2.6 {
  set r [sqlite_step $VM n val colname]
  lappend r $n $val $colname
} {SQLITE_DONE 2 {} {name rowid text INTEGER}}
do_test capi2-2.7 {
  sqlite_finalize $VM
} {}
do_test capi2-2.8 {
  set VM [sqlite3_prepare $DB $SQL -1 SQL]
  list $SQL $VM
} {{} {}}

# Check the error handling.
#
do_test capi2-3.1 {
  set rc [catch {
      sqlite3_prepare $DB {select bogus from sqlite_master} -1 TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {}}
do_test capi2-3.2 {
  set rc [catch {
      sqlite3_prepare $DB {select bogus from } -1 TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) near " ": syntax error} {}}
do_test capi2-3.3 {
  set rc [catch {
      sqlite3_prepare $DB {;;;;select bogus from sqlite_master} -1 TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {}}
do_test capi2-3.4 {
  set rc [catch {
      sqlite3_prepare $DB {select bogus from sqlite_master;x;} -1 TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {x;}}
do_test capi2-3.5 {
  set rc [catch {
      sqlite3_prepare $DB {select bogus from sqlite_master;;;x;} -1 TAIL
  } msg]
  lappend rc $msg $TAIL
} {1 {(1) no such column: bogus} {;;x;}}
do_test capi2-3.6 {
  set rc [catch {
      sqlite3_prepare $DB {select 5/0} -1 TAIL
  } VM]
  lappend rc $TAIL
} {0 {}}
do_test capi2-3.7 {
  set N {}
  set VALUE {}
  set COLNAME {}
................................................................................
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ROW 1 {{}} {5/0 NUMERIC}}
do_test capi2-3.8 {
  sqlite_finalize $VM
} {}
do_test capi2-3.9 {
  execsql {CREATE UNIQUE INDEX i1 ON t1(a)}
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,2,3)} -1 TAIL]
  set TAIL
} {}
do_test capi2-3.9b {db changes} {0}
do_test capi2-3.10 {
  set N {}
  set VALUE {}
  set COLNAME {}
................................................................................
  sqlite_finalize $VM
} {}
do_test capi2-3.11b {db changes} {1}
do_test capi2-3.12 {
  list [catch {sqlite_finalize $VM} msg] [set msg]
} {1 {(21) library routine called out of sequence}}
do_test capi2-3.13 {
  set VM [sqlite3_prepare $DB {INSERT INTO t1 VALUES(1,3,4)} -1 TAIL]
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ERROR 0 {} {}}
do_test capi2-3.13b {db changes} {0}
do_test capi2-3.14 {
  list [catch {sqlite_finalize $VM} msg] [set msg]
} {1 {(19) column a is not unique}}
do_test capi2-3.15 {
  set VM [sqlite3_prepare $DB {CREATE TABLE t2(a NOT NULL, b)} -1 TAIL]
  set TAIL
} {}
do_test capi2-3.16 {
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_DONE 0 {} {}}
do_test capi2-3.17 {
  list [catch {sqlite_finalize $VM} msg] [set msg]
} {0 {}}
do_test capi2-3.18 {
  set VM [sqlite3_prepare $DB {INSERT INTO t2 VALUES(NULL,2)} -1 TAIL]
  list [sqlite_step $VM N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ERROR 0 {} {}}
do_test capi2-3.19 {
  list [catch {sqlite_finalize $VM} msg] [set msg]
} {1 {(19) t2.a may not be NULL}}

# Two or more virtual machines exists at the same time.
#
do_test capi2-4.1 {
  set VM1 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(1,2)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.2 {
  set VM2 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(2,3)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.3 {
  set VM3 [sqlite3_prepare $DB {INSERT INTO t2 VALUES(3,4)} -1 TAIL]
  set TAIL
} {}
do_test capi2-4.4 {
  list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_DONE 0 {} {}}
do_test capi2-4.5 {
  execsql {SELECT * FROM t2 ORDER BY a}
................................................................................
do_test capi2-4.12 {
  list [catch {sqlite_finalize $VM1} msg] [set msg]
} {0 {}}  

# Interleaved SELECTs
#
do_test capi2-5.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  set VM2 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  set VM3 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.2 {
  list [sqlite_step $VM2 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_ROW 2 {2 3} {a b {} {}}}
do_test capi2-5.3 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
................................................................................
    INSERT INTO t3 VALUES(1);
    INSERT INTO t3 VALUES(2);
    INSERT INTO t3 SELECT x+2 FROM t3;
    INSERT INTO t3 SELECT x+4 FROM t3;
    INSERT INTO t3 SELECT x+8 FROM t3;
    COMMIT;
  }
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t3} -1 TAIL]
  sqlite db2 test.db
  execsql {BEGIN} db2
} {}
do_test capi2-6.2 {
  list [sqlite_step $VM1 N VALUE COLNAME] [set N] [set VALUE] [set COLNAME]
} {SQLITE_BUSY 0 {} {}}
do_test capi2-6.3 {
................................................................................
  set x [stepsql $DB {EXPLAIN SELECT * FROM t1}]
  lindex $x 0
} {0}

# Ticket #261 - make sure we can finalize before the end of a query.
#
do_test capi2-8.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 TAIL]
  sqlite_finalize $VM1
} {}
  
# Tickets #384 and #385 - make sure the TAIL argument to sqlite3_prepare
# and all of the return pointers in sqlite_step can be null.
#
do_test capi2-9.1 {
  set VM1 [sqlite3_prepare $DB {SELECT * FROM t2} -1 DUMMY]
  sqlite_step $VM1
  sqlite_finalize $VM1
} {}

db2 close

finish_test

Changes to test/capi3.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
41
42
43
44
45
46
47


48
49
50
51
52
53
54
...
100
101
102
103
104
105
106
107
















































108
109
110
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.1 2004/05/20 11:00:53 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
}

# These tests complement those in capi2.test. They are organized
# as follows:
#
# capi3-1.*: Test sqlite3_prepare 
# capi3-2.*: Test sqlite3_prepare16


#

db close
set DB [sqlite db test.db]

do_test capi3-1.1 {
  set STMT [sqlite3_prepare $DB {SELECT name FROM sqlite_master} -1 TAIL]
................................................................................
} {1}
do_test capi3-2.4 {
  sqlite3_errcode $DB
} {SQLITE_ERROR}
do_test capi3-2.5 {
  sqlite3_errmsg $DB
} {no such column: namex}

















































finish_test









|







 







>
>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
..
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this script testing the callback-free C/C++ API.
#
# $Id: capi3.test,v 1.2 2004/05/21 01:47:27 danielk1977 Exp $
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl

# Return the UTF-16 representation of the supplied UTF-8 string $str.
# If $nt is true, append two 0x00 bytes as a nul terminator.
................................................................................
}

# These tests complement those in capi2.test. They are organized
# as follows:
#
# capi3-1.*: Test sqlite3_prepare 
# capi3-2.*: Test sqlite3_prepare16
# capi3-3.*: Test sqlite3_open
# capi3-4.*: Test sqlite3_open16
#

db close
set DB [sqlite db test.db]

do_test capi3-1.1 {
  set STMT [sqlite3_prepare $DB {SELECT name FROM sqlite_master} -1 TAIL]
................................................................................
} {1}
do_test capi3-2.4 {
  sqlite3_errcode $DB
} {SQLITE_ERROR}
do_test capi3-2.5 {
  sqlite3_errmsg $DB
} {no such column: namex}

# rename sqlite3_open sqlite3_open_old
# proc sqlite3_open {fname options} {sqlite3_open_new $fname $options}

do_test capi3-3.1 {
  set db2 [sqlite3_open test.db {}]
  sqlite3_errcode $db2
} {SQLITE_OK}
# FIX ME: Should test the db handle works.
do_test capi3-3.2 {
  sqlite3_close $db2
} {}
do_test capi3-3.3 {
  catch {
    set db2 [sqlite3_open /bogus/path/test.db {}]
  }
  sqlite3_errcode $db2
} {SQLITE_CANTOPEN}
do_test capi3-3.4 {
  sqlite3_errmsg $db2
} {unable to open database file}
do_test capi3-3.4 {
  sqlite3_close $db2
} {}

# rename sqlite3_open ""
# rename sqlite3_open_old sqlite3_open

do_test capi3-4.1 {
  set db2 [sqlite3_open16 [utf16 test.db] {}]
  sqlite3_errcode $db2
} {SQLITE_OK}
# FIX ME: Should test the db handle works.
do_test capi3-4.2 {
  sqlite3_close $db2
} {}
do_test capi3-4.3 {
  catch {
    set db2 [sqlite3_open16 [utf16 /bogus/path/test.db] {}]
  }
  sqlite3_errcode $db2
} {SQLITE_CANTOPEN}
do_test capi3-4.4 {
  utf8 [sqlite3_errmsg16 $db2]
} {unable to open database file}
do_test capi3-4.4 {
  sqlite3_close $db2
} {}

finish_test


Changes to test/tester.tcl.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.33 2004/05/20 22:16:31 drh Exp $

# Make sure tclsqlite was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
................................................................................

# Use the non-callback API to execute multiple SQL statements
#
proc stepsql {dbptr sql} {
  set sql [string trim $sql]
  set r 0
  while {[string length $sql]>0} {
    if {[catch {sqlite_compile $dbptr $sql sqltail} vm]} {
      return [list 1 $vm]
    }
    set sql [string trim $sqltail]
    while {[sqlite_step $vm N VAL COL]=="SQLITE_ROW"} {
      foreach v $VAL {lappend r $v}
    }
    if {[catch {sqlite_finalize $vm} errmsg]} {







|







 







|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements some common TCL routines used for regression
# testing the SQLite library
#
# $Id: tester.tcl,v 1.34 2004/05/21 01:47:27 danielk1977 Exp $

# Make sure tclsqlite was compiled correctly.  Abort now with an
# error message if not.
#
if {[sqlite -tcl-uses-utf]} {
  if {"\u1234"=="u1234"} {
    puts stderr "***** BUILD PROBLEM *****"
................................................................................

# Use the non-callback API to execute multiple SQL statements
#
proc stepsql {dbptr sql} {
  set sql [string trim $sql]
  set r 0
  while {[string length $sql]>0} {
    if {[catch {sqlite3_prepare $dbptr $sql -1 sqltail} vm]} {
      return [list 1 $vm]
    }
    set sql [string trim $sqltail]
    while {[sqlite_step $vm N VAL COL]=="SQLITE_ROW"} {
      foreach v $VAL {lappend r $v}
    }
    if {[catch {sqlite_finalize $vm} errmsg]} {

Changes to test/vacuum.test.

7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the VACUUM statement.
#
# $Id: vacuum.test,v 1.15 2004/02/14 16:31:04 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc cksum {{db db}} {
  set txt [$db eval {SELECT name, type, sql FROM sqlite_master}]\n
  foreach tbl [$db eval {SELECT name FROM sqlite_master WHERE type='table'}] {
................................................................................
  sqlite db test.db
  execsql {
    PRAGMA empty_result_callbacks=on;
    VACUUM;
  }
} {}

# Ticket #464.  Make sure VACUUM works with the sqlite_compile() API.
#
do_test vacuum-4.1 {
  db close
  set DB [sqlite db test.db]
  set VM [sqlite_compile $DB {VACUUM} TAIL]
  sqlite_step $VM N VALUES COLNAMES
} {SQLITE_DONE}
do_test vacuum-4.2 {
  sqlite_finalize $VM
} {}

# Ticket #515.  VACUUM after deleting and recreating the table that







|







 







|




|







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the VACUUM statement.
#
# $Id: vacuum.test,v 1.16 2004/05/21 01:47:27 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl

proc cksum {{db db}} {
  set txt [$db eval {SELECT name, type, sql FROM sqlite_master}]\n
  foreach tbl [$db eval {SELECT name FROM sqlite_master WHERE type='table'}] {
................................................................................
  sqlite db test.db
  execsql {
    PRAGMA empty_result_callbacks=on;
    VACUUM;
  }
} {}

# Ticket #464.  Make sure VACUUM works with the sqlite3_prepare() API.
#
do_test vacuum-4.1 {
  db close
  set DB [sqlite db test.db]
  set VM [sqlite3_prepare $DB {VACUUM} -1 TAIL]
  sqlite_step $VM N VALUES COLNAMES
} {SQLITE_DONE}
do_test vacuum-4.2 {
  sqlite_finalize $VM
} {}

# Ticket #515.  VACUUM after deleting and recreating the table that