~ubuntu-branches/ubuntu/karmic/gears/karmic

« back to all changes in this revision

Viewing changes to third_party/sqlite_google/src/test_schema.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Lesicnik
  • Date: 2009-04-30 19:15:25 UTC
  • Revision ID: james.westby@ubuntu.com-20090430191525-0790sb5wzg8ou0xb
Tags: upstream-0.5.21.0~svn3334+dfsg
ImportĀ upstreamĀ versionĀ 0.5.21.0~svn3334+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
** 2006 June 10
 
3
**
 
4
** The author disclaims copyright to this source code.  In place of
 
5
** a legal notice, here is a blessing:
 
6
**
 
7
**    May you do good and not evil.
 
8
**    May you find forgiveness for yourself and forgive others.
 
9
**    May you share freely, never taking more than you give.
 
10
**
 
11
*************************************************************************
 
12
** Code for testing the virtual table interfaces.  This code
 
13
** is not included in the SQLite library.  It is used for automated
 
14
** testing of the SQLite library.
 
15
**
 
16
** $Id: test_schema.c,v 1.15 2008/07/07 14:50:14 drh Exp $
 
17
*/
 
18
 
 
19
/* The code in this file defines a sqlite3 virtual-table module that
 
20
** provides a read-only view of the current database schema. There is one
 
21
** row in the schema table for each column in the database schema.
 
22
*/
 
23
#define SCHEMA \
 
24
"CREATE TABLE x("                                                            \
 
25
  "database,"          /* Name of database (i.e. main, temp etc.) */         \
 
26
  "tablename,"         /* Name of table */                                   \
 
27
  "cid,"               /* Column number (from left-to-right, 0 upward) */    \
 
28
  "name,"              /* Column name */                                     \
 
29
  "type,"              /* Specified type (i.e. VARCHAR(32)) */               \
 
30
  "not_null,"          /* Boolean. True if NOT NULL was specified */         \
 
31
  "dflt_value,"        /* Default value for this column */                   \
 
32
  "pk"                 /* True if this column is part of the primary key */  \
 
33
")"
 
34
 
 
35
/* If SQLITE_TEST is defined this code is preprocessed for use as part
 
36
** of the sqlite test binary "testfixture". Otherwise it is preprocessed
 
37
** to be compiled into an sqlite dynamic extension.
 
38
*/
 
39
#ifdef SQLITE_TEST
 
40
  #include "sqliteInt.h"
 
41
  #include "tcl.h"
 
42
#else
 
43
  #include "sqlite3ext.h"
 
44
  SQLITE_EXTENSION_INIT1
 
45
#endif
 
46
 
 
47
#include <stdlib.h>
 
48
#include <string.h>
 
49
#include <assert.h>
 
50
 
 
51
typedef struct schema_vtab schema_vtab;
 
52
typedef struct schema_cursor schema_cursor;
 
53
 
 
54
/* A schema table object */
 
55
struct schema_vtab {
 
56
  sqlite3_vtab base;
 
57
  sqlite3 *db;
 
58
};
 
59
 
 
60
/* A schema table cursor object */
 
61
struct schema_cursor {
 
62
  sqlite3_vtab_cursor base;
 
63
  sqlite3_stmt *pDbList;
 
64
  sqlite3_stmt *pTableList;
 
65
  sqlite3_stmt *pColumnList;
 
66
  int rowid;
 
67
};
 
68
 
 
69
/*
 
70
** None of this works unless we have virtual tables.
 
71
*/
 
72
#ifndef SQLITE_OMIT_VIRTUALTABLE
 
73
 
 
74
/*
 
75
** Table destructor for the schema module.
 
76
*/
 
77
static int schemaDestroy(sqlite3_vtab *pVtab){
 
78
  sqlite3_free(pVtab);
 
79
  return 0;
 
80
}
 
81
 
 
82
/*
 
83
** Table constructor for the schema module.
 
84
*/
 
85
static int schemaCreate(
 
86
  sqlite3 *db,
 
87
  void *pAux,
 
88
  int argc, const char *const*argv,
 
89
  sqlite3_vtab **ppVtab,
 
90
  char **pzErr
 
91
){
 
92
  int rc = SQLITE_NOMEM;
 
93
  schema_vtab *pVtab = sqlite3_malloc(sizeof(schema_vtab));
 
94
  if( pVtab ){
 
95
    memset(pVtab, 0, sizeof(schema_vtab));
 
96
    pVtab->db = db;
 
97
#ifndef SQLITE_OMIT_VIRTUALTABLE
 
98
    rc = sqlite3_declare_vtab(db, SCHEMA);
 
99
#endif
 
100
  }
 
101
  *ppVtab = (sqlite3_vtab *)pVtab;
 
102
  return rc;
 
103
}
 
104
 
 
105
/*
 
106
** Open a new cursor on the schema table.
 
107
*/
 
108
static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
 
109
  int rc = SQLITE_NOMEM;
 
110
  schema_cursor *pCur;
 
111
  pCur = sqlite3_malloc(sizeof(schema_cursor));
 
112
  if( pCur ){
 
113
    memset(pCur, 0, sizeof(schema_cursor));
 
114
    *ppCursor = (sqlite3_vtab_cursor *)pCur;
 
115
    rc = SQLITE_OK;
 
116
  }
 
117
  return rc;
 
118
}
 
119
 
 
120
/*
 
121
** Close a schema table cursor.
 
122
*/
 
123
static int schemaClose(sqlite3_vtab_cursor *cur){
 
124
  schema_cursor *pCur = (schema_cursor *)cur;
 
125
  sqlite3_finalize(pCur->pDbList);
 
126
  sqlite3_finalize(pCur->pTableList);
 
127
  sqlite3_finalize(pCur->pColumnList);
 
128
  sqlite3_free(pCur);
 
129
  return SQLITE_OK;
 
130
}
 
131
 
 
132
/*
 
133
** Retrieve a column of data.
 
134
*/
 
135
static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
 
136
  schema_cursor *pCur = (schema_cursor *)cur;
 
137
  switch( i ){
 
138
    case 0:
 
139
      sqlite3_result_value(ctx, sqlite3_column_value(pCur->pDbList, 1));
 
140
      break;
 
141
    case 1:
 
142
      sqlite3_result_value(ctx, sqlite3_column_value(pCur->pTableList, 0));
 
143
      break;
 
144
    default:
 
145
      sqlite3_result_value(ctx, sqlite3_column_value(pCur->pColumnList, i-2));
 
146
      break;
 
147
  }
 
148
  return SQLITE_OK;
 
149
}
 
150
 
 
151
/*
 
152
** Retrieve the current rowid.
 
153
*/
 
154
static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
 
155
  schema_cursor *pCur = (schema_cursor *)cur;
 
156
  *pRowid = pCur->rowid;
 
157
  return SQLITE_OK;
 
158
}
 
159
 
 
160
static int finalize(sqlite3_stmt **ppStmt){
 
161
  int rc = sqlite3_finalize(*ppStmt);
 
162
  *ppStmt = 0;
 
163
  return rc;
 
164
}
 
165
 
 
166
static int schemaEof(sqlite3_vtab_cursor *cur){
 
167
  schema_cursor *pCur = (schema_cursor *)cur;
 
168
  return (pCur->pDbList ? 0 : 1);
 
169
}
 
170
 
 
171
/*
 
172
** Advance the cursor to the next row.
 
173
*/
 
174
static int schemaNext(sqlite3_vtab_cursor *cur){
 
175
  int rc = SQLITE_OK;
 
176
  schema_cursor *pCur = (schema_cursor *)cur;
 
177
  schema_vtab *pVtab = (schema_vtab *)(cur->pVtab);
 
178
  char *zSql = 0;
 
179
 
 
180
  while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){
 
181
    if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit;
 
182
 
 
183
    while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){
 
184
      if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit;
 
185
 
 
186
      assert(pCur->pDbList);
 
187
      while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){
 
188
        rc = finalize(&pCur->pDbList);
 
189
        goto next_exit;
 
190
      }
 
191
 
 
192
      /* Set zSql to the SQL to pull the list of tables from the 
 
193
      ** sqlite_master (or sqlite_temp_master) table of the database
 
194
      ** identfied by the row pointed to by the SQL statement pCur->pDbList
 
195
      ** (iterating through a "PRAGMA database_list;" statement).
 
196
      */
 
197
      if( sqlite3_column_int(pCur->pDbList, 0)==1 ){
 
198
        zSql = sqlite3_mprintf(
 
199
            "SELECT name FROM sqlite_temp_master WHERE type='table'"
 
200
        );
 
201
      }else{
 
202
        sqlite3_stmt *pDbList = pCur->pDbList;
 
203
        zSql = sqlite3_mprintf(
 
204
            "SELECT name FROM %Q.sqlite_master WHERE type='table'",
 
205
             sqlite3_column_text(pDbList, 1)
 
206
        );
 
207
      }
 
208
      if( !zSql ){
 
209
        rc = SQLITE_NOMEM;
 
210
        goto next_exit;
 
211
      }
 
212
 
 
213
      rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0);
 
214
      sqlite3_free(zSql);
 
215
      if( rc!=SQLITE_OK ) goto next_exit;
 
216
    }
 
217
 
 
218
    /* Set zSql to the SQL to the table_info pragma for the table currently
 
219
    ** identified by the rows pointed to by statements pCur->pDbList and
 
220
    ** pCur->pTableList.
 
221
    */
 
222
    zSql = sqlite3_mprintf("PRAGMA %Q.table_info(%Q)", 
 
223
        sqlite3_column_text(pCur->pDbList, 1),
 
224
        sqlite3_column_text(pCur->pTableList, 0)
 
225
    );
 
226
 
 
227
    if( !zSql ){
 
228
      rc = SQLITE_NOMEM;
 
229
      goto next_exit;
 
230
    }
 
231
    rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0);
 
232
    sqlite3_free(zSql);
 
233
    if( rc!=SQLITE_OK ) goto next_exit;
 
234
  }
 
235
  pCur->rowid++;
 
236
 
 
237
next_exit:
 
238
  /* TODO: Handle rc */
 
239
  return rc;
 
240
}
 
241
 
 
242
/*
 
243
** Reset a schema table cursor.
 
244
*/
 
245
static int schemaFilter(
 
246
  sqlite3_vtab_cursor *pVtabCursor, 
 
247
  int idxNum, const char *idxStr,
 
248
  int argc, sqlite3_value **argv
 
249
){
 
250
  int rc;
 
251
  schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab);
 
252
  schema_cursor *pCur = (schema_cursor *)pVtabCursor;
 
253
  pCur->rowid = 0;
 
254
  finalize(&pCur->pTableList);
 
255
  finalize(&pCur->pColumnList);
 
256
  finalize(&pCur->pDbList);
 
257
  rc = sqlite3_prepare(pVtab->db,"PRAGMA database_list", -1, &pCur->pDbList, 0);
 
258
  return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc);
 
259
}
 
260
 
 
261
/*
 
262
** Analyse the WHERE condition.
 
263
*/
 
264
static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
 
265
  return SQLITE_OK;
 
266
}
 
267
 
 
268
/*
 
269
** A virtual table module that merely echos method calls into TCL
 
270
** variables.
 
271
*/
 
272
static sqlite3_module schemaModule = {
 
273
  0,                           /* iVersion */
 
274
  schemaCreate,
 
275
  schemaCreate,
 
276
  schemaBestIndex,
 
277
  schemaDestroy,
 
278
  schemaDestroy,
 
279
  schemaOpen,                  /* xOpen - open a cursor */
 
280
  schemaClose,                 /* xClose - close a cursor */
 
281
  schemaFilter,                /* xFilter - configure scan constraints */
 
282
  schemaNext,                  /* xNext - advance a cursor */
 
283
  schemaEof,                   /* xEof */
 
284
  schemaColumn,                /* xColumn - read data */
 
285
  schemaRowid,                 /* xRowid - read data */
 
286
  0,                           /* xUpdate */
 
287
  0,                           /* xBegin */
 
288
  0,                           /* xSync */
 
289
  0,                           /* xCommit */
 
290
  0,                           /* xRollback */
 
291
  0,                           /* xFindMethod */
 
292
  0,                           /* xRename */
 
293
};
 
294
 
 
295
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */
 
296
 
 
297
#ifdef SQLITE_TEST
 
298
 
 
299
/*
 
300
** Decode a pointer to an sqlite3 object.
 
301
*/
 
302
extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb);
 
303
 
 
304
/*
 
305
** Register the schema virtual table module.
 
306
*/
 
307
static int register_schema_module(
 
308
  ClientData clientData, /* Not used */
 
309
  Tcl_Interp *interp,    /* The TCL interpreter that invoked this command */
 
310
  int objc,              /* Number of arguments */
 
311
  Tcl_Obj *CONST objv[]  /* Command arguments */
 
312
){
 
313
  sqlite3 *db;
 
314
  if( objc!=2 ){
 
315
    Tcl_WrongNumArgs(interp, 1, objv, "DB");
 
316
    return TCL_ERROR;
 
317
  }
 
318
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;
 
319
#ifndef SQLITE_OMIT_VIRTUALTABLE
 
320
  sqlite3_create_module(db, "schema", &schemaModule, 0);
 
321
#endif
 
322
  return TCL_OK;
 
323
}
 
324
 
 
325
/*
 
326
** Register commands with the TCL interpreter.
 
327
*/
 
328
int Sqlitetestschema_Init(Tcl_Interp *interp){
 
329
  static struct {
 
330
     char *zName;
 
331
     Tcl_ObjCmdProc *xProc;
 
332
     void *clientData;
 
333
  } aObjCmd[] = {
 
334
     { "register_schema_module", register_schema_module, 0 },
 
335
  };
 
336
  int i;
 
337
  for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){
 
338
    Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 
 
339
        aObjCmd[i].xProc, aObjCmd[i].clientData, 0);
 
340
  }
 
341
  return TCL_OK;
 
342
}
 
343
 
 
344
#else
 
345
 
 
346
/*
 
347
** Extension load function.
 
348
*/
 
349
int sqlite3_extension_init(
 
350
  sqlite3 *db, 
 
351
  char **pzErrMsg, 
 
352
  const sqlite3_api_routines *pApi
 
353
){
 
354
  SQLITE_EXTENSION_INIT2(pApi);
 
355
#ifndef SQLITE_OMIT_VIRTUALTABLE
 
356
  sqlite3_create_module(db, "schema", &schemaModule, 0);
 
357
#endif
 
358
  return 0;
 
359
}
 
360
 
 
361
#endif