SQLite

Check-in [15a084e9ea]
Login

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

Overview
Comment:Test cases intended to improve coverage of main.c. (CVS 1763)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 15a084e9ea14d093f75c54a321f146c18f4453d7
User & Date: danielk1977 2004-06-29 13:18:24.000
Context
2004-06-29
13:41
Ensure the tcl interface returns an error when sqlite3_create_function() fails. (CVS 1764) (check-in: 357a82cd22 user: danielk1977 tags: trunk)
13:18
Test cases intended to improve coverage of main.c. (CVS 1763) (check-in: 15a084e9ea user: danielk1977 tags: trunk)
13:04
Improved test coverage of table.c and printf.c. (CVS 1762) (check-in: ba87834d86 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** 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.241 2004/06/29 11:26:59 drh Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
**
*************************************************************************
** 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.242 2004/06/29 13:18:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "os.h"
#include <ctype.h>

/*
** A pointer to this structure is used to communicate information
890
891
892
893
894
895
896

897


898
899
900
901
902
903
904
    0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
  };

  if( db && db->pErr ){

    if( db->magic==SQLITE_MAGIC_ERROR ){


      return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
    }
    if( !sqlite3_value_text16(db->pErr) ){
      sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
          SQLITE_UTF8, SQLITE_STATIC);
    }
    if( sqlite3_value_text16(db->pErr) ){







>
|
>
>







890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
    0, 'c', 0, 'a', 0, 'l', 0, 'l', 0, 'e', 0, 'd', 0, ' ', 
    0, 'o', 0, 'u', 0, 't', 0, ' ', 
    0, 'o', 0, 'f', 0, ' ', 
    0, 's', 0, 'e', 0, 'q', 0, 'u', 0, 'e', 0, 'n', 0, 'c', 0, 'e', 0, 0, 0
  };

  if( db && db->pErr ){
    if( db->magic!=SQLITE_MAGIC_OPEN && 
        db->magic!=SQLITE_MAGIC_BUSY &&
        db->magic!=SQLITE_MAGIC_CLOSED 
    ){
      return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
    }
    if( !sqlite3_value_text16(db->pErr) ){
      sqlite3ValueSetStr(db->pErr, -1, sqlite3ErrStr(db->errCode),
          SQLITE_UTF8, SQLITE_STATIC);
    }
    if( sqlite3_value_text16(db->pErr) ){
1273
1274
1275
1276
1277
1278
1279

1280
1281
1282
1283
1284
1285
1286
  }
  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
  if( 0==pColl ){
   rc = SQLITE_NOMEM;
  }else{
    pColl->xCmp = xCompare;
    pColl->pUser = pCtx;

  }
  sqlite3Error(db, rc, 0);
  return rc;
}

/*
** Register a new collation sequence with the database handle db.







>







1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
  }
  pColl = sqlite3FindCollSeq(db, (u8)enc, zName, strlen(zName), 1);
  if( 0==pColl ){
   rc = SQLITE_NOMEM;
  }else{
    pColl->xCmp = xCompare;
    pColl->pUser = pCtx;
    pColl->enc = enc;
  }
  sqlite3Error(db, rc, 0);
  return rc;
}

/*
** Register a new collation sequence with the database handle db.
Changes to src/test1.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    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.89 2004/06/26 09:50:12 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>








|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    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.90 2004/06/29 13:18:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

72
73
74
75
76
77
78

79
80
81
82
83
84
85
    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
    case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;
    case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;
    case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;
    case SQLITE_ROW:        zName = "SQLITE_ROW";         break;
    case SQLITE_DONE:       zName = "SQLITE_DONE";        break;

    default:                zName = "SQLITE_Unknown";     break;
  }
  return zName;
}

/*
** Decode a pointer to an sqlite object.







>







72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
    case SQLITE_AUTH:       zName = "SQLITE_AUTH";        break;
    case SQLITE_FORMAT:     zName = "SQLITE_FORMAT";      break;
    case SQLITE_RANGE:      zName = "SQLITE_RANGE";       break;
    case SQLITE_ROW:        zName = "SQLITE_ROW";         break;
    case SQLITE_DONE:       zName = "SQLITE_DONE";        break;
    case SQLITE_NOTADB:     zName = "SQLITE_NOTADB";        break;
    default:                zName = "SQLITE_Unknown";     break;
  }
  return zName;
}

/*
** Decode a pointer to an sqlite object.
433
434
435
436
437
438
439

440

441
442
443
444
445
446
447
448

449




450

451
452
453
454
455
456
457
static int test_create_function(
  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;

  extern void Md5_Register(sqlite*);

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sqlite3_create_function(db, "x_coalesce", -1, SQLITE_UTF8, 0, 
      ifnullFunc, 0, 0);

  sqlite3_create_function(db, "x_sqlite_exec", 1, SQLITE_UTF8, db,




      sqlite3ExecFunc, 0, 0);

  return TCL_OK;
}

/*
** Routines to implement the x_count() aggregate function.
*/
typedef struct CountCtx CountCtx;







>

>






|

>
|
>
>
>
>
|
>







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
static int test_create_function(
  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;
  sqlite3_value *pVal;
  extern void Md5_Register(sqlite*);

  if( argc!=2 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " FILENAME\"", 0);
    return TCL_ERROR;
  }
  if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR;
  sqlite3_create_function(db, "x_coalesce", -1, SQLITE_ANY, 0, 
      ifnullFunc, 0, 0);

  /* Use the sqlite3_create_function16() API here. Mainly for fun, but also 
  ** because it is not tested anywhere else. */
  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, "x_sqlite_exec", SQLITE_UTF8, SQLITE_STATIC);
  sqlite3_create_function16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE),
      1, SQLITE_UTF16, db, sqlite3ExecFunc, 0, 0);
  sqlite3ValueFree(pVal);
  return TCL_OK;
}

/*
** Routines to implement the x_count() aggregate function.
*/
typedef struct CountCtx CountCtx;
980
981
982
983
984
985
986

987
988
989
990
991
992
993
994
995
996
997
998


999

1000

1001
1002
1003
1004
1005
1006
1007
1008
































1009
1010
1011
1012
1013
1014
1015
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db;
  int val;


  if( objc!=5 ) goto bad_args;
  pTestCollateInterp = interp;
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;

  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
  sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 
        (void *)SQLITE_UTF8, val?test_collate_func:0);
  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
  sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 
        (void *)SQLITE_UTF16LE, val?test_collate_func:0);
  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;


  sqlite3_create_collation(db, "test_collate", SQLITE_UTF16BE, 

        (void *)SQLITE_UTF16BE, val?test_collate_func:0);

  
  return TCL_OK;

bad_args:
  Tcl_AppendResult(interp, "wrong # args: should be \"",
      Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
  return TCL_ERROR;
}

































/*
** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be>
**
** This function is used to test that SQLite selects the correct user
** function callback when multiple versions (for different text encodings)
** are available.







>












>
>
|
>
|
>








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







989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
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
1056
1057
1058
1059
1060
1061
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db;
  int val;
  sqlite3_value *pVal;

  if( objc!=5 ) goto bad_args;
  pTestCollateInterp = interp;
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;

  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[2], &val) ) return TCL_ERROR;
  sqlite3_create_collation(db, "test_collate", SQLITE_UTF8, 
        (void *)SQLITE_UTF8, val?test_collate_func:0);
  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR;
  sqlite3_create_collation(db, "test_collate", SQLITE_UTF16LE, 
        (void *)SQLITE_UTF16LE, val?test_collate_func:0);
  if( TCL_OK!=Tcl_GetBooleanFromObj(interp, objv[4], &val) ) return TCL_ERROR;

  pVal = sqlite3ValueNew();
  sqlite3ValueSetStr(pVal, -1, "test_collate", SQLITE_UTF8, SQLITE_STATIC);
  sqlite3_create_collation16(db, sqlite3ValueText(pVal, SQLITE_UTF16NATIVE), 
        SQLITE_UTF16BE, (void *)SQLITE_UTF16BE, val?test_collate_func:0);
  sqlite3ValueFree(pVal);
  
  return TCL_OK;

bad_args:
  Tcl_AppendResult(interp, "wrong # args: should be \"",
      Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
  return TCL_ERROR;
}

static void test_collate_needed_cb(
  void *pCtx, 
  sqlite3 *db,
  int eTextRep,
  const void *notUsed
){
  int enc = db->enc;
  sqlite3_create_collation(
      db, "test_collate", db->enc, (void *)enc, test_collate_func);
}

/*
** Usage: add_test_collate_needed DB
*/
static int test_collate_needed(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  sqlite3 *db;

  if( objc!=2 ) goto bad_args;
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
  sqlite3_collation_needed16(db, 0, test_collate_needed_cb);
  return TCL_OK;

bad_args:
  Tcl_WrongNumArgs(interp, 1, objv, "DB");
  return TCL_ERROR;
}

/*
** Usage: add_test_function <db ptr> <utf8> <utf16le> <utf16be>
**
** This function is used to test that SQLite selects the correct user
** function callback when multiple versions (for different text encodings)
** are available.
1131
1132
1133
1134
1135
1136
1137




























1138
1139
1140
1141
1142
1143
1144

  return TCL_OK;
bad_args:
  Tcl_AppendResult(interp, "wrong # args: should be \"",
      Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
  return TCL_ERROR;
}





























static int sqlite3_crashparams(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){







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







1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218

  return TCL_OK;
bad_args:
  Tcl_AppendResult(interp, "wrong # args: should be \"",
      Tcl_GetStringFromObj(objv[0], 0), " <DB> <utf8> <utf16le> <utf16be>", 0);
  return TCL_ERROR;
}

/*
** Usage:         test_errstr <err code>
**
** Test that the english language string equivalents for sqlite error codes
** are sane. The parameter is an integer representing an sqlite error code.
** The result is a list of two elements, the string representation of the
** error code and the english language explanation.
*/
static int test_errstr(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  char *zCode;
  int i;
  if( objc!=1 ){
    Tcl_WrongNumArgs(interp, 1, objv, "<error code>");
  }

  zCode = Tcl_GetString(objv[1]);
  for(i=0; i<200; i++){
    if( 0==strcmp(errorName(i), zCode) ) break;
  }
  Tcl_SetResult(interp, (char *)sqlite3ErrStr(i), 0);
  return TCL_OK;
}

static int sqlite3_crashparams(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
2215
2216
2217
2218
2219
2220
2221


2222
2223

2224
2225

2226
2227
2228
2229
2230
2231
2232
     { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16},
     { "sqlite3_column_name16",     test_stmt_utf16, sqlite3_column_name16    },

     /* Functions from os.h */
     { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
     { "sqlite3OsClose",        test_sqlite3OsClose, 0 },
     { "sqlite3OsLock",         test_sqlite3OsLock, 0 },


     { "sqlite3OsUnlock",       test_sqlite3OsUnlock, 0 },
     { "add_test_collate",      test_collate, 0         },

     { "add_test_function",     test_function, 0         },
     { "sqlite3_crashparams",     sqlite3_crashparams, 0         },


  };
  int i;
  extern int sqlite3_os_trace;

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







>
>
|
|
>
|
|
>







2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
     { "sqlite3_column_decltype16", test_stmt_utf16, sqlite3_column_decltype16},
     { "sqlite3_column_name16",     test_stmt_utf16, sqlite3_column_name16    },

     /* Functions from os.h */
     { "sqlite3OsOpenReadWrite",test_sqlite3OsOpenReadWrite, 0 },
     { "sqlite3OsClose",        test_sqlite3OsClose, 0 },
     { "sqlite3OsLock",         test_sqlite3OsLock, 0 },
   
     /* Custom test interfaces */
     { "sqlite3OsUnlock",         test_sqlite3OsUnlock, 0    },
     { "add_test_collate",        test_collate, 0            },
     { "add_test_collate_needed", test_collate_needed, 0     },
     { "add_test_function",       test_function, 0           },
     { "sqlite3_crashparams",     sqlite3_crashparams, 0     },
     { "sqlite3_test_errstr",     test_errstr, 0             },

  };
  int i;
  extern int sqlite3_os_trace;

  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
Changes to src/test3.c.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.45 2004/06/26 08:38:25 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "btree.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
**    May you share freely, never taking more than you give.
**
*************************************************************************
** Code for testing the btree.c module in SQLite.  This code
** is not included in the SQLite library.  It is used for automated
** testing of the SQLite library.
**
** $Id: test3.c,v 1.46 2004/06/29 13:18:24 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "pager.h"
#include "btree.h"
#include "tcl.h"
#include <stdlib.h>
#include <string.h>
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

766
767
768
769
770
771
772
773
774

775
776
777
778
779






780
781
782
783
784
785
786
787
788
/*
** Usage:   btree_insert ID KEY DATA
**
** Create a new entry with the given key and data.  If an entry already
** exists with the same key the old entry is overwritten.
*/
static int btree_insert(
  void *NotUsed,
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
  int argc,              /* Number of arguments */
  const char **argv      /* Text of each argument */
){
  BtCursor *pCur;
  int rc;

  if( argc!=4 ){
    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
       " ID KEY DATA\"", 0);
    return TCL_ERROR;
  }

  if( Tcl_GetInt(interp, argv[1], (int*)&pCur) ) return TCL_ERROR;
  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){
/*
    int iKey;
    if( Tcl_GetInt(interp, argv[2], &iKey) ) return TCL_ERROR;
*/
    i64 iKey;
    Tcl_Obj *obj = Tcl_NewStringObj(argv[2], -1);
    Tcl_IncrRefCount(obj);

    if( Tcl_GetWideIntFromObj(interp, obj, &iKey) ) return TCL_ERROR;
    Tcl_DecrRefCount(obj);

    rc = sqlite3BtreeInsert(pCur, 0, iKey, argv[3], strlen(argv[3]));
  }else{






    rc = sqlite3BtreeInsert(pCur, argv[2], strlen(argv[2]),
                         argv[3], strlen(argv[3]));
  }
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return SQLITE_OK;
}







|
|
|
|




|
<
|


>
|

<
<
<
<

<
|
>
|
<
|
|

>
>
>
>
>
>
|
<







746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

762
763
764
765
766
767




768

769
770
771

772
773
774
775
776
777
778
779
780
781

782
783
784
785
786
787
788
/*
** Usage:   btree_insert ID KEY DATA
**
** Create a new entry with the given key and data.  If an entry already
** exists with the same key the old entry is overwritten.
*/
static int btree_insert(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  BtCursor *pCur;
  int rc;

  if( objc!=4 ){

    Tcl_WrongNumArgs(interp, 1, objv, "ID KEY DATA");
    return TCL_ERROR;
  }

  if( Tcl_GetIntFromObj(interp, objv[1], (int*)&pCur) ) return TCL_ERROR;
  if( sqlite3BtreeFlags(pCur) & BTREE_INTKEY ){




    i64 iKey;

    int len;
    unsigned char *pBuf;
    if( Tcl_GetWideIntFromObj(interp, objv[2], &iKey) ) return TCL_ERROR;

    pBuf = Tcl_GetByteArrayFromObj(objv[3], &len);
    rc = sqlite3BtreeInsert(pCur, 0, iKey, pBuf, len);
  }else{
    int keylen;
    int dlen;
    unsigned char *pKBuf;
    unsigned char *pDBuf;
    pKBuf = Tcl_GetByteArrayFromObj(objv[2], &keylen);
    pDBuf = Tcl_GetByteArrayFromObj(objv[3], &dlen);
    rc = sqlite3BtreeInsert(pCur, pKBuf, keylen, pDBuf, dlen);

  }
  if( rc ){
    Tcl_AppendResult(interp, errorName(rc), 0);
    return TCL_ERROR;
  }
  return SQLITE_OK;
}
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
     { "btree_tree_dump",          (Tcl_CmdProc*)btree_tree_dump          },
     { "btree_pager_stats",        (Tcl_CmdProc*)btree_pager_stats        },
     { "btree_pager_ref_dump",     (Tcl_CmdProc*)btree_pager_ref_dump     },
     { "btree_cursor",             (Tcl_CmdProc*)btree_cursor             },
     { "btree_close_cursor",       (Tcl_CmdProc*)btree_close_cursor       },
     { "btree_move_to",            (Tcl_CmdProc*)btree_move_to            },
     { "btree_delete",             (Tcl_CmdProc*)btree_delete             },
     { "btree_insert",             (Tcl_CmdProc*)btree_insert             },
     { "btree_next",               (Tcl_CmdProc*)btree_next               },
     { "btree_prev",               (Tcl_CmdProc*)btree_prev               },
     { "btree_eof",                (Tcl_CmdProc*)btree_eof                },
     { "btree_keysize",            (Tcl_CmdProc*)btree_keysize            },
     { "btree_key",                (Tcl_CmdProc*)btree_key                },
     { "btree_data",               (Tcl_CmdProc*)btree_data               },
     { "btree_fetch_key",          (Tcl_CmdProc*)btree_fetch_key          },







<







1315
1316
1317
1318
1319
1320
1321

1322
1323
1324
1325
1326
1327
1328
     { "btree_tree_dump",          (Tcl_CmdProc*)btree_tree_dump          },
     { "btree_pager_stats",        (Tcl_CmdProc*)btree_pager_stats        },
     { "btree_pager_ref_dump",     (Tcl_CmdProc*)btree_pager_ref_dump     },
     { "btree_cursor",             (Tcl_CmdProc*)btree_cursor             },
     { "btree_close_cursor",       (Tcl_CmdProc*)btree_close_cursor       },
     { "btree_move_to",            (Tcl_CmdProc*)btree_move_to            },
     { "btree_delete",             (Tcl_CmdProc*)btree_delete             },

     { "btree_next",               (Tcl_CmdProc*)btree_next               },
     { "btree_prev",               (Tcl_CmdProc*)btree_prev               },
     { "btree_eof",                (Tcl_CmdProc*)btree_eof                },
     { "btree_keysize",            (Tcl_CmdProc*)btree_keysize            },
     { "btree_key",                (Tcl_CmdProc*)btree_key                },
     { "btree_data",               (Tcl_CmdProc*)btree_data               },
     { "btree_fetch_key",          (Tcl_CmdProc*)btree_fetch_key          },
1345
1346
1347
1348
1349
1350
1351






1352
1353
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager3_refinfo_enable,
     TCL_LINK_INT);
  Tcl_LinkVar(interp, "btree_trace", (char*)&sqlite3_btree_trace,
     TCL_LINK_INT);






  return TCL_OK;
}







>
>
>
>
>
>


1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  }
  Tcl_LinkVar(interp, "pager_refinfo_enable", (char*)&pager3_refinfo_enable,
     TCL_LINK_INT);
  Tcl_LinkVar(interp, "btree_trace", (char*)&sqlite3_btree_trace,
     TCL_LINK_INT);

  /* The btree_insert command is implemented using the tcl 'object'
  ** interface, not the string interface like the other commands in this
  ** file. This is so binary data can be inserted into btree tables.
  */
  Tcl_CreateObjCommand(interp, "btree_insert", btree_insert, 0, 0);
  return TCL_OK;
}
Changes to test/capi3.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2003 January 29
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    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.
#
#***********************************************************************
# 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.15 2004/06/29 08:59:35 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.













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2003 January 29
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    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.
#
#***********************************************************************
# 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.16 2004/06/29 13:18:24 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.
131
132
133
134
135
136
137






138
139
140
141
142
143
144
} {unable to open database file}
do_test capi3-3.5 {
  sqlite3_close $db2
} {SQLITE_OK}
do_test capi3-3.6 {
  sqlite3_close $db2
} {SQLITE_MISUSE}







# rename sqlite3_open ""
# rename sqlite3_open_old sqlite3_open

do_test capi3-4.1 {
  set db2 [sqlite3_open16 [utf16 test.db] {}]
  sqlite3_errcode $db2







>
>
>
>
>
>







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
} {unable to open database file}
do_test capi3-3.5 {
  sqlite3_close $db2
} {SQLITE_OK}
do_test capi3-3.6 {
  sqlite3_close $db2
} {SQLITE_MISUSE}
do_test capi3-3.6 {
  sqlite3_errmsg $db2
} {library routine called out of sequence}
do_test capi3-3.6 {
  utf8 [sqlite3_errmsg16 $db2]
} {library routine called out of sequence}

# rename sqlite3_open ""
# rename sqlite3_open_old sqlite3_open

do_test capi3-4.1 {
  set db2 [sqlite3_open16 [utf16 test.db] {}]
  sqlite3_errcode $db2
470
471
472
473
474
475
476
















































































































477



do_test capi3-7.2 {
  sqlite3 db test.db
  catchsql {
    SELECT * FROM sqlite_master;
  }
} {1 {unsupported file format}}

















































































































finish_test










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

>
>
>
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
do_test capi3-7.2 {
  sqlite3 db test.db
  catchsql {
    SELECT * FROM sqlite_master;
  }
} {1 {unsupported file format}}

# Now test that the library correctly handles bogus entries in the
# sqlite_master table (schema corruption).
do_test capi3-8.1 {
  db close
  file delete -force test.db
  sqlite3 db test.db
  execsql {
    CREATE TABLE t1(a);
  }
  db close
} {}
do_test capi3-8.2 {
  set ::bt [btree_open test.db 10 0]
  btree_begin_transaction $::bt
  set ::bc [btree_cursor $::bt 1 1]

  # Build a 5-field row record consisting of 5 null records. This is
  # officially black magic.
  set data [binary format c6 {6 0 0 0 0 0}]
  btree_insert $::bc 5 $data

  btree_close_cursor $::bc
  btree_commit $::bt
  btree_close $::bt
} {}
do_test capi3-8.3 {
  sqlite3 db test.db
  catchsql {
    SELECT * FROM sqlite_master;
  }
} {1 {malformed database schema}}
do_test capi3-8.4 {
  set ::bt [btree_open test.db 10 0]
  btree_begin_transaction $::bt
  set ::bc [btree_cursor $::bt 1 1]

  # Build a 5-field row record. The first field is a string 'table', and
  # subsequent fields are all NULL. Replace the other broken record with
  # this one and try to read the schema again.
  set data [binary format c6a5 {6 23 0 0 0 0} table]
  btree_insert $::bc 5 $data

  btree_close_cursor $::bc
  btree_commit $::bt
  btree_close $::bt
} {}
do_test capi3-8.5 {
  db close 
  sqlite3 db test.db
  catchsql {
    SELECT * FROM sqlite_master;
  }
} {1 {malformed database schema}}
db close
file delete -force test.db

# Test the english language string equivalents for sqlite error codes
set code2english [list \
SQLITE_OK         {not an error} \
SQLITE_ERROR      {SQL logic error or missing database} \
SQLITE_INTERNAL   {internal SQLite implementation flaw} \
SQLITE_PERM       {access permission denied} \
SQLITE_ABORT      {callback requested query abort} \
SQLITE_BUSY       {database is locked} \
SQLITE_LOCKED     {database table is locked} \
SQLITE_NOMEM      {out of memory} \
SQLITE_READONLY   {attempt to write a readonly database} \
SQLITE_INTERRUPT  {interrupted} \
SQLITE_IOERR      {disk I/O error} \
SQLITE_CORRUPT    {database disk image is malformed} \
SQLITE_NOTFOUND   {table or record not found} \
SQLITE_FULL       {database is full} \
SQLITE_CANTOPEN   {unable to open database file} \
SQLITE_PROTOCOL   {database locking protocol failure} \
SQLITE_EMPTY      {table contains no data} \
SQLITE_SCHEMA     {database schema has changed} \
SQLITE_TOOBIG     {too much data for one table row} \
SQLITE_CONSTRAINT {constraint failed} \
SQLITE_MISMATCH   {datatype mismatch} \
SQLITE_MISUSE     {library routine called out of sequence} \
SQLITE_NOLFS      {kernel lacks large file support} \
SQLITE_AUTH       {authorization denied} \
SQLITE_FORMAT     {auxiliary database format error} \
SQLITE_RANGE      {bind index out of range} \
SQLITE_NOTADB     {file is encrypted or is not a database} \
unknownerror      {unknown error} \
]

set test_number 1
foreach {code english} $code2english {
  do_test capi3-9.$test_number "sqlite3_test_errstr $code" $english
  incr test_number
}

# Test the error message when a "real" out of memory occurs.
set sqlite_malloc_fail 1
do_test capi3-10-1 {
  set ::DB [sqlite3 db test.db]
  sqlite_malloc_fail 1
  catchsql {
    select * from sqlite_master;
  }
} {1 {out of memory}}
do_test capi3-10-2 {
  sqlite3_errmsg $::DB
} {out of memory}
do_test capi3-10-3 {
  utf8 [sqlite3_errmsg16 $::DB]
} {out of memory}
db close
sqlite_malloc_fail 0

finish_test



Changes to test/enc2.test.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The focus of
# this file is testing the SQLite routines used for converting between the
# various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
# UTF-16be).
#
# $Id: enc2.test,v 1.15 2004/06/28 11:52:46 drh Exp $

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

# The rough organisation of tests in this file is:
#
# enc2.1.*: Simple tests with a UTF-8 db.







|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The focus of
# this file is testing the SQLite routines used for converting between the
# various suported unicode encodings (UTF-8, UTF-16, UTF-16le and
# UTF-16be).
#
# $Id: enc2.test,v 1.16 2004/06/29 13:18:24 danielk1977 Exp $

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

# The rough organisation of tests in this file is:
#
# enc2.1.*: Simple tests with a UTF-8 db.
256
257
258
259
260
261
262













263
264
265
266
267
268
269
} {one two three four five UTF-16LE}
do_test enc2-5.11 {
  add_test_collate $DB 1 0 0
  set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
  lappend res $::test_collate_enc
} {one two three four five UTF-8}














db close
file delete -force test.db

# The following tests - enc2-5.* - test that SQLite selects the correct
# collation sequence when more than one is available.

proc test_function {enc arg} {







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







256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
} {one two three four five UTF-16LE}
do_test enc2-5.11 {
  add_test_collate $DB 1 0 0
  set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
  lappend res $::test_collate_enc
} {one two three four five UTF-8}

# Also test that a UTF-16 collation factory works.
do_test enc2-6-12 {
  add_test_collate $DB 0 0 0
  catchsql {
    SELECT * FROM t5 ORDER BY 1 COLLATE test_collate
  }
} {1 {no such collation sequence: test_collate}}
do_test enc2-5.13 {
  add_test_collate_needed $DB 
  set res [execsql {SELECT * FROM t5 ORDER BY 1 COLLATE test_collate}]
  lappend res $::test_collate_enc
} {one two three four five UTF-16BE}

db close
file delete -force test.db

# The following tests - enc2-5.* - test that SQLite selects the correct
# collation sequence when more than one is available.

proc test_function {enc arg} {
363
364
365
366
367
368
369

370
371
372
373
374
375
376
set DB [sqlite3 db test.db]
do_test enc2-6.10 {
  add_test_function $DB 0 0 1
  execsql {
    SELECT test_function('sqlite')
  }
} {{UTF-16BE sqlite}}


db close
file delete -force test.db

# The following tests - enc2-6.* - function as follows:
#
# 1: Open an empty database file assuming UTF-16 encoding.







>







376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
set DB [sqlite3 db test.db]
do_test enc2-6.10 {
  add_test_function $DB 0 0 1
  execsql {
    SELECT test_function('sqlite')
  }
} {{UTF-16BE sqlite}}


db close
file delete -force test.db

# The following tests - enc2-6.* - function as follows:
#
# 1: Open an empty database file assuming UTF-16 encoding.
Changes to test/func.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.26 2004/06/24 00:20:05 danielk1977 Exp $

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

# Create a table to work with.
#
do_test func-0.0 {













|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# 2001 September 15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    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.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing built-in functions.
#
# $Id: func.test,v 1.27 2004/06/29 13:18:24 danielk1977 Exp $

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

# Create a table to work with.
#
do_test func-0.0 {
435
436
437
438
439
440
441
442












443
  sqlite3_bind_text $STMT 1 hello -1
  set res [list]
  while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
    lappend res [sqlite3_column_text $STMT 0]
  }
  lappend res [sqlite3_finalize $STMT]
} {{0 0} {1 0} SQLITE_OK}













finish_test








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

435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
  sqlite3_bind_text $STMT 1 hello -1
  set res [list]
  while { "SQLITE_ROW"==[sqlite3_step $STMT] } {
    lappend res [sqlite3_column_text $STMT 0]
  }
  lappend res [sqlite3_finalize $STMT]
} {{0 0} {1 0} SQLITE_OK}

# Make sure that a function with a very long name is rejected
do_test func-14.1 {
  catch {
    db function [string repeat X 254] {return "hello"}
  } 
} {0}
do_test func-14.2 {
  catch {
    db function [string repeat X 256] {return "hello"}
  }
} {1}

finish_test