1/*
2** Read an SQLite database file and analyze its space utilization.  Generate
3** text on standard output.
4*/
5#define TCLSH_INIT_PROC sqlite3_checker_init_proc
6#define SQLITE_ENABLE_DBPAGE_VTAB 1
7#define SQLITE_ENABLE_JSON1 1
8#undef SQLITE_THREADSAFE
9#define SQLITE_THREADSAFE 0
10#undef SQLITE_ENABLE_COLUMN_METADATA
11#define SQLITE_OMIT_DECLTYPE 1
12#define SQLITE_OMIT_DEPRECATED 1
13#define SQLITE_OMIT_PROGRESS_CALLBACK 1
14#define SQLITE_OMIT_SHARED_CACHE 1
15#define SQLITE_DEFAULT_MEMSTATUS 0
16#define SQLITE_MAX_EXPR_DEPTH 0
17INCLUDE sqlite3.c
18INCLUDE $ROOT/src/tclsqlite.c
19INCLUDE $ROOT/ext/misc/btreeinfo.c
20INCLUDE $ROOT/ext/repair/checkindex.c
21INCLUDE $ROOT/ext/repair/checkfreelist.c
22
23/*
24** Decode a pointer to an sqlite3 object.
25*/
26int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb){
27  struct SqliteDb *p;
28  Tcl_CmdInfo cmdInfo;
29  if( Tcl_GetCommandInfo(interp, zA, &cmdInfo) ){
30    p = (struct SqliteDb*)cmdInfo.objClientData;
31    *ppDb = p->db;
32    return TCL_OK;
33  }else{
34    *ppDb = 0;
35    return TCL_ERROR;
36  }
37  return TCL_OK;
38}
39
40/*
41**   sqlite3_imposter db main rootpage {CREATE TABLE...}  ;# setup an imposter
42**   sqlite3_imposter db main                             ;# rm all imposters
43*/
44static int sqlite3_imposter(
45  void *clientData,
46  Tcl_Interp *interp,
47  int objc,
48  Tcl_Obj *CONST objv[]
49){
50  sqlite3 *db;
51  const char *zSchema;
52  int iRoot;
53  const char *zSql;
54
55  if( objc!=3 && objc!=5 ){
56    Tcl_WrongNumArgs(interp, 1, objv, "DB SCHEMA [ROOTPAGE SQL]");
57    return TCL_ERROR;
58  }
59  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
60  zSchema = Tcl_GetString(objv[2]);
61  if( objc==3 ){
62    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 0, 1);
63  }else{
64    if( Tcl_GetIntFromObj(interp, objv[3], &iRoot) ) return TCL_ERROR;
65    zSql = Tcl_GetString(objv[4]);
66    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 1, iRoot);
67    sqlite3_exec(db, zSql, 0, 0, 0);
68    sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, db, zSchema, 0, 0);
69  }
70  return TCL_OK;
71}
72
73#include <stdio.h>
74
75const char *sqlite3_checker_init_proc(Tcl_Interp *interp){
76  Tcl_CreateObjCommand(interp, "sqlite3_imposter",
77                       (Tcl_ObjCmdProc*)sqlite3_imposter, 0, 0);
78  sqlite3_auto_extension((void(*)(void))sqlite3_btreeinfo_init);
79  sqlite3_auto_extension((void(*)(void))sqlite3_checkindex_init);
80  sqlite3_auto_extension((void(*)(void))sqlite3_checkfreelist_init);
81  return
82BEGIN_STRING
83INCLUDE $ROOT/ext/repair/sqlite3_checker.tcl
84END_STRING
85;
86}
87