SQLite

Check-in [fa19c77bf0]
Login

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

Overview
Comment:Fixes for compiler warnings. Also more coverage. (CVS 1775)
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: fa19c77bf045787faa4cdc40bcfbd9eeae8594ae
User & Date: danielk1977 2004-06-30 08:20:16.000
Context
2004-06-30
09:49
Coverage tests for vacuum.c (CVS 1776) (check-in: 152e9940b9 user: danielk1977 tags: trunk)
08:20
Fixes for compiler warnings. Also more coverage. (CVS 1775) (check-in: fa19c77bf0 user: danielk1977 tags: trunk)
06:30
Add some tests for overlapping SELECT, COMMIT and ROLLBACK commands. (CVS 1774) (check-in: d256c14943 user: danielk1977 tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to main.mk.
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
where.o:	$(TOP)/src/where.c $(HDR)
	$(TCCX) -c $(TOP)/src/where.c

# Rules for building test programs and for running tests
#
tclsqlite3:	$(TOP)/src/tclsqlite.c libsqlite3.a
	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
		$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL)

testfixture$(EXE):	$(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC)
	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 -DSQLITE_TEST=1 -o testfixture$(EXE) \
		$(TESTSRC) $(TOP)/src/tclsqlite.c \
		libsqlite3.a $(LIBTCL) $(THREADLIB)

crashtest:	$(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TOP)/src/os_test.c







|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
where.o:	$(TOP)/src/where.c $(HDR)
	$(TCCX) -c $(TOP)/src/where.c

# Rules for building test programs and for running tests
#
tclsqlite3:	$(TOP)/src/tclsqlite.c libsqlite3.a
	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 -o tclsqlite3 \
		$(TOP)/src/tclsqlite.c libsqlite3.a $(LIBTCL) $(THREADLIB)

testfixture$(EXE):	$(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC)
	$(TCCX) $(TCL_FLAGS) -DTCLSH=1 -DSQLITE_TEST=1 -o testfixture$(EXE) \
		$(TESTSRC) $(TOP)/src/tclsqlite.c \
		libsqlite3.a $(LIBTCL) $(THREADLIB)

crashtest:	$(TOP)/src/tclsqlite.c libsqlite3.a $(TESTSRC) $(TOP)/src/os_test.c
Changes to src/btree.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.175 2004/06/30 01:07:02 drh Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
** 2004 April 6
**
** 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.
**
*************************************************************************
** $Id: btree.c,v 1.176 2004/06/30 08:20:16 danielk1977 Exp $
**
** This file implements a external (disk-based) database using BTrees.
** For a detailed discussion of BTrees, refer to
**
**     Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3:
**     "Sorting And Searching", pages 473-480. Addison-Wesley
**     Publishing Company, Reading, Massachusetts.
497
498
499
500
501
502
503

504
505
506
507
508

509
510
511
512
513
514
515

/*
** Compute the total number of bytes that a Cell needs in the cell
** data area of the btree-page.  The return number includes the cell
** data header and the local payload, but not any overflow page or
** the space used by the cell pointer.
*/

static int cellSize(MemPage *pPage, int iCell){
  CellInfo info;
  parseCell(pPage, iCell, &info);
  return info.nSize;
}

static int cellSizePtr(MemPage *pPage, u8 *pCell){
  CellInfo info;
  parseCellPtr(pPage, pCell, &info);
  return info.nSize;
}

/*







>





>







497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517

/*
** Compute the total number of bytes that a Cell needs in the cell
** data area of the btree-page.  The return number includes the cell
** data header and the local payload, but not any overflow page or
** the space used by the cell pointer.
*/
#ifndef NDEBUG
static int cellSize(MemPage *pPage, int iCell){
  CellInfo info;
  parseCell(pPage, iCell, &info);
  return info.nSize;
}
#endif
static int cellSizePtr(MemPage *pPage, u8 *pCell){
  CellInfo info;
  parseCellPtr(pPage, pCell, &info);
  return info.nSize;
}

/*
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
** The first byte of the new free block is pPage->aDisk[start]
** and the size of the block is "size" bytes.
**
** Most of the effort here is involved in coalesing adjacent
** free blocks into a single big free block.
*/
static void freeSpace(MemPage *pPage, int start, int size){
  int end = start + size;  /* End of the segment being freed */
  int addr, pbegin, hdr;
  unsigned char *data = pPage->aData;

  assert( pPage->pBt!=0 );
  assert( sqlite3pager_iswriteable(data) );
  assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
  assert( end<=pPage->pBt->usableSize );
  if( size<4 ) size = 4;

  /* Add the space back into the linked list of freeblocks */
  hdr = pPage->hdrOffset;
  addr = hdr + 1;
  while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
    assert( pbegin<=pPage->pBt->usableSize-4 );







<






|







717
718
719
720
721
722
723

724
725
726
727
728
729
730
731
732
733
734
735
736
737
** The first byte of the new free block is pPage->aDisk[start]
** and the size of the block is "size" bytes.
**
** Most of the effort here is involved in coalesing adjacent
** free blocks into a single big free block.
*/
static void freeSpace(MemPage *pPage, int start, int size){

  int addr, pbegin, hdr;
  unsigned char *data = pPage->aData;

  assert( pPage->pBt!=0 );
  assert( sqlite3pager_iswriteable(data) );
  assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
  assert( (start + size)<=pPage->pBt->usableSize );
  if( size<4 ) size = 4;

  /* Add the space back into the linked list of freeblocks */
  hdr = pPage->hdrOffset;
  addr = hdr + 1;
  while( (pbegin = get2byte(&data[addr]))<start && pbegin>0 ){
    assert( pbegin<=pPage->pBt->usableSize-4 );
Changes to src/pager.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.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.35 2004/06/26 08:38:25 danielk1977 Exp $
*/

/*
** The size of a page.
**
** You can change this value to another (reasonable) value you want.
** It need not be a power of two, though the interface to the disk







|







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.
**
*************************************************************************
** This header file defines the interface that the sqlite page cache
** subsystem.  The page cache subsystem reads and writes a file a page
** at a time and provides a journal for rollback.
**
** @(#) $Id: pager.h,v 1.36 2004/06/30 08:20:16 danielk1977 Exp $
*/

/*
** The size of a page.
**
** You can change this value to another (reasonable) value you want.
** It need not be a power of two, though the interface to the disk
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
void sqlite3pager_set_safety_level(Pager*,int);
const char *sqlite3pager_filename(Pager*);
const char *sqlite3pager_dirname(Pager*);
const char *sqlite3pager_journalname(Pager*);
int sqlite3pager_rename(Pager*, const char *zNewName);
void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);

#ifdef SQLITE_DEBUG
int sqlite3pager_lockstate(Pager*);
#endif

#ifdef SQLITE_TEST
void sqlite3pager_refdump(Pager*);
int pager3_refinfo_enable;
#endif







|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
void sqlite3pager_set_safety_level(Pager*,int);
const char *sqlite3pager_filename(Pager*);
const char *sqlite3pager_dirname(Pager*);
const char *sqlite3pager_journalname(Pager*);
int sqlite3pager_rename(Pager*, const char *zNewName);
void sqlite3pager_set_codec(Pager*,void(*)(void*,void*,Pgno,int),void*);

#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
int sqlite3pager_lockstate(Pager*);
#endif

#ifdef SQLITE_TEST
void sqlite3pager_refdump(Pager*);
int pager3_refinfo_enable;
#endif
Changes to src/shell.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.105 2004/06/19 09:08:16 danielk1977 Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
#include <ctype.h>







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
**
*************************************************************************
** This file contains code to implement the "sqlite" command line
** utility for accessing SQLite databases.
**
** $Id: shell.c,v 1.106 2004/06/30 08:20:16 danielk1977 Exp $
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "sqlite3.h"
#include <ctype.h>
78
79
80
81
82
83
84




















85
86
87
88
89
90
91
static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */


/*
** Determines if a string is a number of not.
*/
extern int sqlite3IsNumber(const char*, int*, unsigned char);





















/*
** This routine reads a line of text from standard input, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**







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







78
79
80
81
82
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
static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */


/*
** Determines if a string is a number of not.
*/
extern int sqlite3IsNumber(const char*, int*, unsigned char);

/*
** A global char* and an SQL function to access its current value 
** from within an SQL statement. This program used to use the 
** sqlite_exec_printf() API to substitue a string into an SQL statement.
** The correct way to do this with sqlite3 is to use the bind API, but
** since the shell is built around the callback paradigm it would be a lot
** of work. Instead just use this hack, which is quite harmless.
*/
static const char *zShellStatic = 0;
static void shellstaticFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  assert( 0==argc );
  assert( zShellStatic );
  sqlite3_result_text(context, zShellStatic, -1, SQLITE_STATIC);
}


/*
** This routine reads a line of text from standard input, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
617
618
619
620
621
622
623


624
625
626
627
628
629
630
    int n = p->zKey ? strlen(p->zKey) : 0;
    db = p->db = sqlite3_open_encrypted(p->zDbFilename, p->zKey, n, 0, &zErrMsg);
    assert(0); /* Encrypted databases are broken in SQLite 3 */
#else
    sqlite3_open(p->zDbFilename, &p->db);
    db = p->db;
#endif


    if( SQLITE_OK!=sqlite3_errcode(db) ){
      fprintf(stderr,"Unable to open database \"%s\": %s\n", 
          p->zDbFilename, sqlite3_errmsg(db));
      exit(1);
    }
  }
}







>
>







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
    int n = p->zKey ? strlen(p->zKey) : 0;
    db = p->db = sqlite3_open_encrypted(p->zDbFilename, p->zKey, n, 0, &zErrMsg);
    assert(0); /* Encrypted databases are broken in SQLite 3 */
#else
    sqlite3_open(p->zDbFilename, &p->db);
    db = p->db;
#endif
    sqlite3_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
        shellstaticFunc, 0, 0);
    if( SQLITE_OK!=sqlite3_errcode(db) ){
      fprintf(stderr,"Unable to open database \"%s\": %s\n", 
          p->zDbFilename, sqlite3_errmsg(db));
      exit(1);
    }
  }
}
693
694
695
696
697
698
699

700
701
702
703
704
705

706
707
708
709
710
711
712
        "WHERE type!='meta' AND sql NOT NULL "
        "ORDER BY substr(type,2,1), name",
        dump_callback, p, &zErrMsg
      );
    }else{
      int i;
      for(i=1; i<nArg && zErrMsg==0; i++){

        sqlite3_exec_printf(p->db,
          "SELECT name, type, sql FROM sqlite_master "
          "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOT NULL "
          "ORDER BY substr(type,2,1), name",
          dump_callback, p, &zErrMsg, azArg[i]
        );

      }
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }else{
      fprintf(p->out, "COMMIT;\n");







>
|

|

|

>







715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
        "WHERE type!='meta' AND sql NOT NULL "
        "ORDER BY substr(type,2,1), name",
        dump_callback, p, &zErrMsg
      );
    }else{
      int i;
      for(i=1; i<nArg && zErrMsg==0; i++){
        zShellStatic = azArg[i];
        sqlite3_exec(p->db,
          "SELECT name, type, sql FROM sqlite_master "
          "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOT NULL "
          "ORDER BY substr(type,2,1), name",
          dump_callback, p, &zErrMsg
        );
        zShellStatic = 0;
      }
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }else{
      fprintf(p->out, "COMMIT;\n");
798
799
800
801
802
803
804

805
806
807
808
809
810
811
812
813

814
815
816
817
818
819
820
  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_List;

    sqlite3_exec_printf(p->db,
      "SELECT name FROM sqlite_master "
      "WHERE type='index' AND tbl_name LIKE '%q' "
      "UNION ALL "
      "SELECT name FROM sqlite_temp_master "
      "WHERE type='index' AND tbl_name LIKE '%q' "
      "ORDER BY 1",
      callback, &data, &zErrMsg, azArg[1], azArg[1]
    );

    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
  }else

  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){







>
|

|


|

|

>







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
  if( c=='i' && strncmp(azArg[0], "indices", n)==0 && nArg>1 ){
    struct callback_data data;
    char *zErrMsg = 0;
    open_db(p);
    memcpy(&data, p, sizeof(data));
    data.showHeader = 0;
    data.mode = MODE_List;
    zShellStatic = azArg[1];
    sqlite3_exec(p->db,
      "SELECT name FROM sqlite_master "
      "WHERE type='index' AND tbl_name LIKE shellstatic() "
      "UNION ALL "
      "SELECT name FROM sqlite_temp_master "
      "WHERE type='index' AND tbl_name LIKE shellstatic() "
      "ORDER BY 1",
      callback, &data, &zErrMsg
    );
    zShellStatic = 0;
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
  }else

  if( c=='m' && strncmp(azArg[0], "mode", n)==0 && nArg>=2 ){
936
937
938
939
940
941
942

943
944
945
946
947
948
949

950
951
952
953
954
955
956
                      "  sql text\n"
                      ")";
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
      }else{

        sqlite3_exec_printf(p->db,
          "SELECT sql FROM "
          "  (SELECT * FROM sqlite_master UNION ALL"
          "   SELECT * FROM sqlite_temp_master) "
          "WHERE tbl_name LIKE '%q' AND type!='meta' AND sql NOTNULL "
          "ORDER BY substr(type,2,1), name",
          callback, &data, &zErrMsg, azArg[1]);

      }
    }else{
      sqlite3_exec(p->db,
         "SELECT sql FROM "
         "  (SELECT * FROM sqlite_master UNION ALL"
         "   SELECT * FROM sqlite_temp_master) "
         "WHERE type!='meta' AND sql NOTNULL "







>
|



|

|
>







962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
                      "  sql text\n"
                      ")";
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
      }else{
        zShellStatic = azArg[1];
        sqlite3_exec(p->db,
          "SELECT sql FROM "
          "  (SELECT * FROM sqlite_master UNION ALL"
          "   SELECT * FROM sqlite_temp_master) "
          "WHERE tbl_name LIKE shellstatic() AND type!='meta' AND sql NOTNULL "
          "ORDER BY substr(type,2,1), name",
          callback, &data, &zErrMsg);
        zShellStatic = 0;
      }
    }else{
      sqlite3_exec(p->db,
         "SELECT sql FROM "
         "  (SELECT * FROM sqlite_master UNION ALL"
         "   SELECT * FROM sqlite_temp_master) "
         "WHERE type!='meta' AND sql NOTNULL "
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
    }else{

      rc = sqlite3_get_table_printf(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') AND name LIKE '%%%q%%' "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg, azArg[1], azArg[1]
      );

    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
    if( rc==SQLITE_OK ){
      int len, maxlen = 0;







>
|

|


|

|

>







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
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
    }else{
      zShellStatic = azArg[1];
      rc = sqlite3_get_table(p->db,
        "SELECT name FROM sqlite_master "
        "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
        "UNION ALL "
        "SELECT name FROM sqlite_temp_master "
        "WHERE type IN ('table','view') AND name LIKE '%'||shellstatic()||'%' "
        "ORDER BY 1",
        &azResult, &nRow, 0, &zErrMsg
      );
      zShellStatic = 0;
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
    }
    if( rc==SQLITE_OK ){
      int len, maxlen = 0;
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.91 2004/06/30 04:02:12 drh 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.92 2004/06/30 08:20:16 danielk1977 Exp $
*/
#include "sqliteInt.h"
#include "tcl.h"
#include "os.h"
#include <stdlib.h>
#include <string.h>

1765
1766
1767
1768
1769
1770
1771
























1772
1773
1774
1775
1776
1777
1778
  zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
  rc = sqlite3_open16(zFilename, &db);
  
  if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

























/*
** Usage: sqlite3_step STMT
**
** Advance the statement to the next row.
*/
static int test_step(







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







1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
  zFilename = Tcl_GetByteArrayFromObj(objv[1], 0);
  rc = sqlite3_open16(zFilename, &db);
  
  if( makePointerStr(interp, zBuf, db) ) return TCL_ERROR;
  Tcl_AppendResult(interp, zBuf, 0);
  return TCL_OK;
}

/*
** Usage: sqlite3_complete16 <UTF-16 string>
**
** Return 1 if the supplied argument is a complete SQL statement, or zero
** otherwise.
*/
static int test_complete16(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  char *zBuf;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "<utf-16 sql>");
    return TCL_ERROR;
  }

  zBuf = Tcl_GetByteArrayFromObj(objv[1], 0);
  Tcl_SetObjResult(interp, Tcl_NewIntObj(sqlite3_complete16(zBuf)));
  return TCL_OK;
}

/*
** Usage: sqlite3_step STMT
**
** Advance the statement to the next row.
*/
static int test_step(
2272
2273
2274
2275
2276
2277
2278

2279
2280
2281
2282
2283
2284
2285
     { "sqlite3_bind_text16",           test_bind_text16   ,0 },
     { "sqlite3_bind_blob",             test_bind_blob     ,0 },
     { "sqlite3_errcode",               test_errcode       ,0 },
     { "sqlite3_errmsg",                test_errmsg        ,0 },
     { "sqlite3_errmsg16",              test_errmsg16      ,0 },
     { "sqlite3_open",                  test_open          ,0 },
     { "sqlite3_open16",                test_open16        ,0 },


     { "sqlite3_prepare",               test_prepare       ,0 },
     { "sqlite3_prepare16",             test_prepare16     ,0 },
     { "sqlite3_finalize",              test_finalize      ,0 },
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },







>







2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
     { "sqlite3_bind_text16",           test_bind_text16   ,0 },
     { "sqlite3_bind_blob",             test_bind_blob     ,0 },
     { "sqlite3_errcode",               test_errcode       ,0 },
     { "sqlite3_errmsg",                test_errmsg        ,0 },
     { "sqlite3_errmsg16",              test_errmsg16      ,0 },
     { "sqlite3_open",                  test_open          ,0 },
     { "sqlite3_open16",                test_open16        ,0 },
     { "sqlite3_complete16",            test_complete16    ,0 },

     { "sqlite3_prepare",               test_prepare       ,0 },
     { "sqlite3_prepare16",             test_prepare16     ,0 },
     { "sqlite3_finalize",              test_finalize      ,0 },
     { "sqlite3_reset",                 test_reset         ,0 },
     { "sqlite3_changes",               test_changes       ,0 },
     { "sqlite3_step",                  test_step          ,0 },
Changes to test/all.test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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 runs all tests.
#
# $Id: all.test,v 1.20 2004/06/26 19:35:30 drh Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {memleak_check}

if {[file exists ./sqlite_test_count]} {












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 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 runs all tests.
#
# $Id: all.test,v 1.21 2004/06/30 08:20:16 danielk1977 Exp $

set testdir [file dirname $argv0]
source $testdir/tester.tcl
rename finish_test really_finish_test
proc finish_test {} {memleak_check}

if {[file exists ./sqlite_test_count]} {
101
102
103
104
105
106
107
108



109
110

111
112
113
114
115
# Run the crashtest only on unix and only once.
#
if {$tcl_platform(platform)=="unix"} {
  source $testdir/crash.test
}

# Run the malloc tests and the misuse test after memory leak detection.
# Both tests leak memory.



#
catch {source $testdir/misuse.test}

catch {source $testdir/malloc.test}

catch {db close}
set sqlite_open_file_count 0
really_finish_test







|
>
>
>


>





101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# Run the crashtest only on unix and only once.
#
if {$tcl_platform(platform)=="unix"} {
  source $testdir/crash.test
}

# Run the malloc tests and the misuse test after memory leak detection.
# Both tests leak memory. Currently, misuse.test also leaks a handful of
# file descriptors. This is not considered a problem, but can cause tests
# in malloc.test to fail. So set the open-file count to zero before running
# malloc.test to get around this.
#
catch {source $testdir/misuse.test}
set sqlite_open_file_count 0
catch {source $testdir/malloc.test}

catch {db close}
set sqlite_open_file_count 0
really_finish_test
Changes to test/enc2.test.
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
34
35
36
37
38
#
#***********************************************************************
# 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.
# enc2.2.*: Simple tests with a UTF-16LE db.
# enc2.3.*: Simple tests with a UTF-16BE db.
# enc2.4.*: Test that attached databases must have the same text encoding
#           as the main database.
# enc2.5.*: Test the behaviour of the library when a collation sequence is
#           not available for the most desirable text encoding.

# enc2.6.*: Test that the VerifyCookie opcode protects against assuming the
#           wrong text encoding for the database.



db close

# Return the UTF-8 representation of the supplied UTF-16 string $str. 
proc utf8 {str} {
  # If $str ends in two 0x00 0x00 bytes, knock these off before
  # converting to UTF-8 using TCL.







|













>
|

>
>







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
34
35
36
37
38
39
40
41
#
#***********************************************************************
# 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.17 2004/06/30 08:20:16 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.
# enc2.2.*: Simple tests with a UTF-16LE db.
# enc2.3.*: Simple tests with a UTF-16BE db.
# enc2.4.*: Test that attached databases must have the same text encoding
#           as the main database.
# enc2.5.*: Test the behaviour of the library when a collation sequence is
#           not available for the most desirable text encoding.
# enc2.6.*: Similar test for user functions.
# enc2.7.*: Test that the VerifyCookie opcode protects against assuming the
#           wrong text encoding for the database.
# enc2.8.*: Test sqlite3_complete16()
#

db close

# Return the UTF-8 representation of the supplied UTF-16 string $str. 
proc utf8 {str} {
  # If $str ends in two 0x00 0x00 bytes, knock these off before
  # converting to UTF-8 using TCL.
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
283
284
285
286
287
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} {
  return "$enc $arg"
}

file delete -force test.db
set DB [sqlite3 db test.db]







|














|
|







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
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-5-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-6.* - test that SQLite selects the correct
# user function when more than one is available.

proc test_function {enc arg} {
  return "$enc $arg"
}

file delete -force test.db
set DB [sqlite3 db test.db]
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
  }
} {{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.
# 2: Open the same database with a different handle assuming UTF-8. Create
#    a table using this handle.
# 3: Read the sqlite_master table from the first handle. 
# 4: Ensure the first handle recognises the database encoding is UTF-8.
#







|







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
  }
} {{UTF-16BE sqlite}}


db close
file delete -force test.db

# The following tests - enc2-7.* - function as follows:
#
# 1: Open an empty database file assuming UTF-16 encoding.
# 2: Open the same database with a different handle assuming UTF-8. Create
#    a table using this handle.
# 3: Read the sqlite_master table from the first handle. 
# 4: Ensure the first handle recognises the database encoding is UTF-8.
#
423
424
425
426
427
428
429




430







431
    PRAGMA encoding;
  }
} {UTF-8}

db close
db2 close













finish_test







>
>
>
>
|
>
>
>
>
>
>
>

426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
    PRAGMA encoding;
  }
} {UTF-8}

db close
db2 close

proc utf16 {utf8} {
  set utf16 [encoding convertto unicode $utf8]
  append utf16 "\x00\x00"
  return $utf16
}
do_test enc2-8.1 {
  sqlite3_complete16 [utf16 "SELECT * FROM t1;"]
} {1}
do_test enc2-8.2 {
  sqlite3_complete16 [utf16 "SELECT * FROM"]
} {0}

finish_test