15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2001 September 15
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** The author disclaims copyright to this source code.  In place of
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** a legal notice, here is a blessing:
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you do good and not evil.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you find forgiveness for yourself and forgive others.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**    May you share freely, never taking more than you give.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*************************************************************************
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Code for testing the pager.c module in SQLite.  This code
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** is not included in the SQLite library.  It is used for automated
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** testing of the SQLite library.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sqliteInt.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "tcl.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <ctype.h>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Interpret an SQLite error number
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static char *errorName(int rc){
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *zName;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch( rc ){
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_OK:         zName = "SQLITE_OK";          break;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_ERROR:      zName = "SQLITE_ERROR";       break;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_PERM:       zName = "SQLITE_PERM";        break;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_ABORT:      zName = "SQLITE_ABORT";       break;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_BUSY:       zName = "SQLITE_BUSY";        break;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_NOMEM:      zName = "SQLITE_NOMEM";       break;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_READONLY:   zName = "SQLITE_READONLY";    break;
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_INTERRUPT:  zName = "SQLITE_INTERRUPT";   break;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_IOERR:      zName = "SQLITE_IOERR";       break;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_CORRUPT:    zName = "SQLITE_CORRUPT";     break;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_FULL:       zName = "SQLITE_FULL";        break;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_CANTOPEN:   zName = "SQLITE_CANTOPEN";    break;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_PROTOCOL:   zName = "SQLITE_PROTOCOL";    break;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_EMPTY:      zName = "SQLITE_EMPTY";       break;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_SCHEMA:     zName = "SQLITE_SCHEMA";      break;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_CONSTRAINT: zName = "SQLITE_CONSTRAINT";  break;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_MISMATCH:   zName = "SQLITE_MISMATCH";    break;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_MISUSE:     zName = "SQLITE_MISUSE";      break;
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case SQLITE_NOLFS:      zName = "SQLITE_NOLFS";       break;
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    default:                zName = "SQLITE_Unknown";     break;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return zName;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Page size and reserved size used for testing.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int test_pagesize = 1024;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Dummy page reinitializer
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void pager_test_reiniter(DbPage *pNotUsed){
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_open FILENAME N-PAGE
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Open a new pager
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_open(
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  u32 pageSize;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nPage;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zBuf[100];
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=3 ){
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " FILENAME N-PAGE\"", 0);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetInt(interp, argv[2], &nPage) ) return TCL_ERROR;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerOpen(sqlite3_vfs_find(0), &pPager, argv[1], 0, 0,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_MAIN_DB,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pager_test_reiniter);
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3PagerSetCachesize(pPager, nPage);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pageSize = test_pagesize;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3PagerSetPagesize(pPager, &pageSize, -1);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPager);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, zBuf, 0);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_close ID
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close the given pager.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_close(
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID\"", 0);
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerClose(pPager);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_rollback ID
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Rollback changes
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_rollback(
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID\"", 0);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerRollback(pPager);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_commit ID
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Commit all changes
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_commit(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID\"", 0);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerCommitPhaseOne(pPager, 0, 0);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerCommitPhaseTwo(pPager);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_stmt_begin ID
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Start a new checkpoint.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_stmt_begin(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID\"", 0);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerOpenSavepoint(pPager, 1);
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_stmt_rollback ID
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Rollback changes to a checkpoint
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_stmt_rollback(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID\"", 0);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_ROLLBACK, 0);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_stmt_commit ID
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Commit changes to a checkpoint
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_stmt_commit(
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID\"", 0);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerSavepoint(pPager, SAVEPOINT_RELEASE, 0);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_stats ID
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return pager statistics.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_stats(
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i, *a;
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID\"", 0);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  a = sqlite3PagerStats(pPager);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<9; i++){
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static char *zName[] = {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "ref", "page", "max", "size", "state", "err",
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "hit", "miss", "ovfl",
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    };
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char zBuf[100];
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendElement(interp, zName[i]);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_snprintf(sizeof(zBuf),zBuf,"%d",a[i]);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendElement(interp, zBuf);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_pagecount ID
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the size of the database file.
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_pagecount(
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zBuf[100];
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nPage;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID\"", 0);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3PagerPagecount(pPager, &nPage);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", nPage);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, zBuf, 0);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   page_get ID PGNO
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a pointer to a page from the database.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int page_get(
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zBuf[100];
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbPage *pPage;
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pgno;
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=3 ){
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID PGNO\"", 0);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerSharedLock(pPager);
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc==SQLITE_OK ){
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    rc = sqlite3PagerGet(pPager, pgno, &pPage);
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, zBuf, 0);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   page_lookup ID PGNO
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return a pointer to a page if the page is already in cache.
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** If not in cache, return an empty string.
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int page_lookup(
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zBuf[100];
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbPage *pPage;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pgno;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=3 ){
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID PGNO\"", 0);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPage = sqlite3PagerLookup(pPager, pgno);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( pPage ){
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sqlite3_snprintf(sizeof(zBuf),zBuf,"%p",pPage);
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, zBuf, 0);
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   pager_truncate ID PGNO
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int pager_truncate(
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Pager *pPager;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pgno;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=3 ){
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " ID PGNO\"", 0);
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPager = sqlite3TestTextToPtr(argv[1]);
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetInt(interp, argv[2], &pgno) ) return TCL_ERROR;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3PagerTruncateImage(pPager, pgno);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   page_unref PAGE
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Drop a pointer to a page.
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int page_unref(
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbPage *pPage;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " PAGE\"", 0);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3PagerUnref(pPage);
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   page_read PAGE
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the content of a page
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int page_read(
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zBuf[100];
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbPage *pPage;
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " PAGE\"", 0);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPage = sqlite3TestTextToPtr(argv[1]);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(zBuf, sqlite3PagerGetData(pPage), sizeof(zBuf));
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, zBuf, 0);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   page_number PAGE
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Return the page number for a page.
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int page_number(
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char zBuf[100];
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbPage *pPage;
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " PAGE\"", 0);
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_snprintf(sizeof(zBuf), zBuf, "%d", sqlite3PagerPagenumber(pPage));
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_AppendResult(interp, zBuf, 0);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   page_write PAGE DATA
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write something into a page.
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int page_write(
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DbPage *pPage;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char *pData;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=3 ){
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " PAGE DATA\"", 0);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pPage = (DbPage *)sqlite3TestTextToPtr(argv[1]);
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3PagerWrite(pPage);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc!=SQLITE_OK ){
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, errorName(rc), 0);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pData = sqlite3PagerGetData(pPage);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  strncpy(pData, argv[2], test_pagesize-1);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pData[test_pagesize-1] = 0;
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_DISKIO
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Usage:   fake_big_file  N  FILENAME
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Write a few bytes at the N megabyte point of FILENAME.  This will
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** create a large file.  If the file was a valid SQLite database, then
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** the next time the database is opened, SQLite will begin allocating
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** new pages after N.  If N is 2096 or bigger, this will test the
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** ability of SQLite to write to large files.
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int fake_big_file(
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_vfs *pVfs;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3_file *fd = 0;
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int n;
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  i64 offset;
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=3 ){
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       " N-MEGABYTES FILE\"", 0);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetInt(interp, argv[1], &n) ) return TCL_ERROR;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pVfs = sqlite3_vfs_find(0);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3OsOpenMalloc(pVfs, argv[2], &fd,
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB), 0
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  );
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc ){
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "open failed: ", errorName(rc), 0);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  offset = n;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  offset *= 1024*1024;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3OsWrite(fd, "Hello, World!", 14, offset);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  sqlite3OsCloseFree(fd);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( rc ){
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "write failed: ", errorName(rc), 0);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** test_control_pending_byte  PENDING_BYTE
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Set the PENDING_BYTE using the sqlite3_test_control() interface.
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int testPendingByte(
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pbyte;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int rc;
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=2 ){
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     " PENDING-BYTE\"", (void*)0);
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TCL_ERROR;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetInt(interp, argv[1], &pbyte) ) return TCL_ERROR;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_test_control(SQLITE_TESTCTRL_PENDING_BYTE, pbyte);
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** sqlite3BitvecBuiltinTest SIZE PROGRAM
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)**
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Invoke the SQLITE_TESTCTRL_BITVEC_TEST operator on test_control.
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** See comments on sqlite3BitvecBuiltinTest() for additional information.
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int testBitvecBuiltinTest(
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void *NotUsed,
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int argc,              /* Number of arguments */
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char **argv      /* Text of each argument */
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int sz, rc;
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int nProg = 0;
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int aProg[100];
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char *z;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( argc!=3 ){
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     " SIZE PROGRAM\"", (void*)0);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if( Tcl_GetInt(interp, argv[1], &sz) ) return TCL_ERROR;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  z = argv[2];
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while( nProg<99 && *z ){
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while( *z && !sqlite3Isdigit(*z) ){ z++; }
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if( *z==0 ) break;
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    aProg[nProg++] = atoi(z);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while( sqlite3Isdigit(*z) ){ z++; }
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  aProg[nProg] = 0;
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  rc = sqlite3_test_control(SQLITE_TESTCTRL_BITVEC_TEST, sz, aProg);
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register commands with the TCL interpreter.
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetest2_Init(Tcl_Interp *interp){
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int sqlite3_io_error_persist;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int sqlite3_io_error_pending;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int sqlite3_io_error_hit;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int sqlite3_io_error_hardhit;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int sqlite3_diskfull_pending;
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extern int sqlite3_diskfull;
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static struct {
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    char *zName;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_CmdProc *xProc;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } aCmd[] = {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_open",              (Tcl_CmdProc*)pager_open          },
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_close",             (Tcl_CmdProc*)pager_close         },
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_commit",            (Tcl_CmdProc*)pager_commit        },
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_rollback",          (Tcl_CmdProc*)pager_rollback      },
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_stmt_begin",        (Tcl_CmdProc*)pager_stmt_begin    },
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_stmt_commit",       (Tcl_CmdProc*)pager_stmt_commit   },
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_stmt_rollback",     (Tcl_CmdProc*)pager_stmt_rollback },
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_stats",             (Tcl_CmdProc*)pager_stats         },
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_pagecount",         (Tcl_CmdProc*)pager_pagecount     },
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "page_get",                (Tcl_CmdProc*)page_get            },
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "page_lookup",             (Tcl_CmdProc*)page_lookup         },
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "page_unref",              (Tcl_CmdProc*)page_unref          },
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "page_read",               (Tcl_CmdProc*)page_read           },
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "page_write",              (Tcl_CmdProc*)page_write          },
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "page_number",             (Tcl_CmdProc*)page_number         },
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "pager_truncate",          (Tcl_CmdProc*)pager_truncate      },
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_DISKIO
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "fake_big_file",           (Tcl_CmdProc*)fake_big_file       },
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "sqlite3BitvecBuiltinTest",(Tcl_CmdProc*)testBitvecBuiltinTest     },
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { "sqlite3_test_control_pending_byte", (Tcl_CmdProc*)testPendingByte },
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int i;
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Tcl_CreateCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "sqlite_io_error_pending",
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     (char*)&sqlite3_io_error_pending, TCL_LINK_INT);
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "sqlite_io_error_persist",
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     (char*)&sqlite3_io_error_persist, TCL_LINK_INT);
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "sqlite_io_error_hit",
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     (char*)&sqlite3_io_error_hit, TCL_LINK_INT);
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "sqlite_io_error_hardhit",
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     (char*)&sqlite3_io_error_hardhit, TCL_LINK_INT);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "sqlite_diskfull_pending",
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     (char*)&sqlite3_diskfull_pending, TCL_LINK_INT);
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "sqlite_diskfull",
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     (char*)&sqlite3_diskfull, TCL_LINK_INT);
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_WSD
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tcl_LinkVar(interp, "sqlite_pending_byte",
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     (char*)&sqlite3PendingByte, TCL_LINK_INT | TCL_LINK_READ_ONLY);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return TCL_OK;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
684