15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** 2006 June 10 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 virtual table interfaces. 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) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* The code in this file defines a sqlite3 virtual-table module that 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** provides a read-only view of the current database schema. There is one 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** row in the schema table for each column in the database schema. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SCHEMA \ 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)"CREATE TABLE x(" \ 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "database," /* Name of database (i.e. main, temp etc.) */ \ 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "tablename," /* Name of table */ \ 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "cid," /* Column number (from left-to-right, 0 upward) */ \ 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "name," /* Column name */ \ 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "type," /* Specified type (i.e. VARCHAR(32)) */ \ 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "not_null," /* Boolean. True if NOT NULL was specified */ \ 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "dflt_value," /* Default value for this column */ \ 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "pk" /* True if this column is part of the primary key */ \ 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)")" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* If SQLITE_TEST is defined this code is preprocessed for use as part 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** of the sqlite test binary "testfixture". Otherwise it is preprocessed 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** to be compiled into an sqlite dynamic extension. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #include "sqliteInt.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #include "tcl.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) #include "sqlite3ext.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SQLITE_EXTENSION_INIT1 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <assert.h> 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct schema_vtab schema_vtab; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct schema_cursor schema_cursor; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* A schema table object */ 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct schema_vtab { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab base; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* A schema table cursor object */ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct schema_cursor { 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab_cursor base; 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_stmt *pDbList; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_stmt *pTableList; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_stmt *pColumnList; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rowid; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** None of this works unless we have virtual tables. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Table destructor for the schema module. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaDestroy(sqlite3_vtab *pVtab){ 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pVtab); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Table constructor for the schema module. 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaCreate( 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *pAux, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, const char *const*argv, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab **ppVtab, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **pzErr 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_NOMEM; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_vtab *pVtab = sqlite3_malloc(sizeof(schema_vtab)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pVtab ){ 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pVtab, 0, sizeof(schema_vtab)); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pVtab->db = db; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_declare_vtab(db, SCHEMA); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppVtab = (sqlite3_vtab *)pVtab; 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Open a new cursor on the schema table. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){ 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_NOMEM; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_cursor *pCur; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCur = sqlite3_malloc(sizeof(schema_cursor)); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( pCur ){ 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(pCur, 0, sizeof(schema_cursor)); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppCursor = (sqlite3_vtab_cursor *)pCur; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = SQLITE_OK; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Close a schema table cursor. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaClose(sqlite3_vtab_cursor *cur){ 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_cursor *pCur = (schema_cursor *)cur; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_finalize(pCur->pDbList); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_finalize(pCur->pTableList); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_finalize(pCur->pColumnList); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(pCur); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Retrieve a column of data. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_cursor *pCur = (schema_cursor *)cur; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch( i ){ 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_result_value(ctx, sqlite3_column_value(pCur->pDbList, 1)); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_result_value(ctx, sqlite3_column_value(pCur->pTableList, 0)); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_result_value(ctx, sqlite3_column_value(pCur->pColumnList, i-2)); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Retrieve the current rowid. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_cursor *pCur = (schema_cursor *)cur; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *pRowid = pCur->rowid; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int finalize(sqlite3_stmt **ppStmt){ 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = sqlite3_finalize(*ppStmt); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ppStmt = 0; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaEof(sqlite3_vtab_cursor *cur){ 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_cursor *pCur = (schema_cursor *)cur; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (pCur->pDbList ? 0 : 1); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Advance the cursor to the next row. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaNext(sqlite3_vtab_cursor *cur){ 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc = SQLITE_OK; 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_cursor *pCur = (schema_cursor *)cur; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_vtab *pVtab = (schema_vtab *)(cur->pVtab); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zSql = 0; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( !pCur->pColumnList || SQLITE_ROW!=sqlite3_step(pCur->pColumnList) ){ 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( SQLITE_OK!=(rc = finalize(&pCur->pColumnList)) ) goto next_exit; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( !pCur->pTableList || SQLITE_ROW!=sqlite3_step(pCur->pTableList) ){ 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( SQLITE_OK!=(rc = finalize(&pCur->pTableList)) ) goto next_exit; 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(pCur->pDbList); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while( SQLITE_ROW!=sqlite3_step(pCur->pDbList) ){ 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = finalize(&pCur->pDbList); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto next_exit; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set zSql to the SQL to pull the list of tables from the 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** sqlite_master (or sqlite_temp_master) table of the database 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** identfied by the row pointed to by the SQL statement pCur->pDbList 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** (iterating through a "PRAGMA database_list;" statement). 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( sqlite3_column_int(pCur->pDbList, 0)==1 ){ 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql = sqlite3_mprintf( 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT name FROM sqlite_temp_master WHERE type='table'" 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }else{ 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_stmt *pDbList = pCur->pDbList; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql = sqlite3_mprintf( 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT name FROM %Q.sqlite_master WHERE type='table'", 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_column_text(pDbList, 1) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !zSql ){ 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = SQLITE_NOMEM; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto next_exit; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pTableList, 0); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(zSql); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ) goto next_exit; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Set zSql to the SQL to the table_info pragma for the table currently 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** identified by the rows pointed to by statements pCur->pDbList and 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ** pCur->pTableList. 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) zSql = sqlite3_mprintf("PRAGMA %Q.table_info(%Q)", 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_column_text(pCur->pDbList, 1), 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_column_text(pCur->pTableList, 0) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( !zSql ){ 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = SQLITE_NOMEM; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto next_exit; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_prepare(pVtab->db, zSql, -1, &pCur->pColumnList, 0); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_free(zSql); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( rc!=SQLITE_OK ) goto next_exit; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCur->rowid++; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)next_exit: 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: Handle rc */ 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rc; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Reset a schema table cursor. 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaFilter( 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_vtab_cursor *pVtabCursor, 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int idxNum, const char *idxStr, 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int argc, sqlite3_value **argv 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rc; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_vtab *pVtab = (schema_vtab *)(pVtabCursor->pVtab); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schema_cursor *pCur = (schema_cursor *)pVtabCursor; 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pCur->rowid = 0; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) finalize(&pCur->pTableList); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) finalize(&pCur->pColumnList); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) finalize(&pCur->pDbList); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rc = sqlite3_prepare(pVtab->db,"PRAGMA database_list", -1, &pCur->pDbList, 0); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (rc==SQLITE_OK ? schemaNext(pVtabCursor) : rc); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Analyse the WHERE condition. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int schemaBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){ 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SQLITE_OK; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** A virtual table module that merely echos method calls into TCL 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** variables. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static sqlite3_module schemaModule = { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* iVersion */ 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaCreate, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaCreate, 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaBestIndex, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaDestroy, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaDestroy, 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaOpen, /* xOpen - open a cursor */ 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaClose, /* xClose - close a cursor */ 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaFilter, /* xFilter - configure scan constraints */ 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaNext, /* xNext - advance a cursor */ 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaEof, /* xEof */ 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaColumn, /* xColumn - read data */ 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) schemaRowid, /* xRowid - read data */ 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xUpdate */ 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xBegin */ 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xSync */ 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xCommit */ 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xRollback */ 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xFindMethod */ 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0, /* xRename */ 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef SQLITE_TEST 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Decode a pointer to an sqlite3 object. 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extern int getDbPointer(Tcl_Interp *interp, const char *zA, sqlite3 **ppDb); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register the schema virtual table module. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int register_schema_module( 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientData clientData, /* Not used */ 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int objc, /* Number of arguments */ 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_Obj *CONST objv[] /* Command arguments */ 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( objc!=2 ){ 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_WrongNumArgs(interp, 1, objv, "DB"); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_ERROR; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_create_module(db, "schema", &schemaModule, 0); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Register commands with the TCL interpreter. 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int Sqlitetestschema_Init(Tcl_Interp *interp){ 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static struct { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *zName; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_ObjCmdProc *xProc; 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *clientData; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } aObjCmd[] = { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { "register_schema_module", register_schema_module, 0 }, 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for(i=0; i<sizeof(aObjCmd)/sizeof(aObjCmd[0]); i++){ 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tcl_CreateObjCommand(interp, aObjCmd[i].zName, 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) aObjCmd[i].xProc, aObjCmd[i].clientData, 0); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TCL_OK; 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)** Extension load function. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/ 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int sqlite3_extension_init( 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3 *db, 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char **pzErrMsg, 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sqlite3_api_routines *pApi 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)){ 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SQLITE_EXTENSION_INIT2(pApi); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SQLITE_OMIT_VIRTUALTABLE 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sqlite3_create_module(db, "schema", &schemaModule, 0); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 360