Fixes default log output to console for macOS
[sqlcipher.git] / ext / misc / templatevtab.c
blob5865f5214b7dc4ada935896d09e25b9abed6daa7
1 /*
2 ** 2018-04-19
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.
11 *************************************************************************
13 ** This file implements a template virtual-table.
14 ** Developers can make a copy of this file as a baseline for writing
15 ** new virtual tables and/or table-valued functions.
17 ** Steps for writing a new virtual table implementation:
19 ** (1) Make a copy of this file. Perhaps call it "mynewvtab.c"
21 ** (2) Replace this header comment with something appropriate for
22 ** the new virtual table
24 ** (3) Change every occurrence of "templatevtab" to some other string
25 ** appropriate for the new virtual table. Ideally, the new string
26 ** should be the basename of the source file: "mynewvtab". Also
27 ** globally change "TEMPLATEVTAB" to "MYNEWVTAB".
29 ** (4) Run a test compilation to make sure the unmodified virtual
30 ** table works.
32 ** (5) Begin making incremental changes, testing as you go, to evolve
33 ** the new virtual table to do what you want it to do.
35 ** This template is minimal, in the sense that it uses only the required
36 ** methods on the sqlite3_module object. As a result, templatevtab is
37 ** a read-only and eponymous-only table. Those limitation can be removed
38 ** by adding new methods.
40 ** This template implements an eponymous-only virtual table with a rowid and
41 ** two columns named "a" and "b". The table as 10 rows with fixed integer
42 ** values. Usage example:
44 ** SELECT rowid, a, b FROM templatevtab;
46 #if !defined(SQLITEINT_H)
47 #include "sqlite3ext.h"
48 #endif
49 SQLITE_EXTENSION_INIT1
50 #include <string.h>
51 #include <assert.h>
53 /* templatevtab_vtab is a subclass of sqlite3_vtab which is
54 ** underlying representation of the virtual table
56 typedef struct templatevtab_vtab templatevtab_vtab;
57 struct templatevtab_vtab {
58 sqlite3_vtab base; /* Base class - must be first */
59 /* Add new fields here, as necessary */
62 /* templatevtab_cursor is a subclass of sqlite3_vtab_cursor which will
63 ** serve as the underlying representation of a cursor that scans
64 ** over rows of the result
66 typedef struct templatevtab_cursor templatevtab_cursor;
67 struct templatevtab_cursor {
68 sqlite3_vtab_cursor base; /* Base class - must be first */
69 /* Insert new fields here. For this templatevtab we only keep track
70 ** of the rowid */
71 sqlite3_int64 iRowid; /* The rowid */
75 ** The templatevtabConnect() method is invoked to create a new
76 ** template virtual table.
78 ** Think of this routine as the constructor for templatevtab_vtab objects.
80 ** All this routine needs to do is:
82 ** (1) Allocate the templatevtab_vtab object and initialize all fields.
84 ** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the
85 ** result set of queries against the virtual table will look like.
87 static int templatevtabConnect(
88 sqlite3 *db,
89 void *pAux,
90 int argc, const char *const*argv,
91 sqlite3_vtab **ppVtab,
92 char **pzErr
94 templatevtab_vtab *pNew;
95 int rc;
97 rc = sqlite3_declare_vtab(db,
98 "CREATE TABLE x(a,b)"
100 /* For convenience, define symbolic names for the index to each column. */
101 #define TEMPLATEVTAB_A 0
102 #define TEMPLATEVTAB_B 1
103 if( rc==SQLITE_OK ){
104 pNew = sqlite3_malloc( sizeof(*pNew) );
105 *ppVtab = (sqlite3_vtab*)pNew;
106 if( pNew==0 ) return SQLITE_NOMEM;
107 memset(pNew, 0, sizeof(*pNew));
109 return rc;
113 ** This method is the destructor for templatevtab_vtab objects.
115 static int templatevtabDisconnect(sqlite3_vtab *pVtab){
116 templatevtab_vtab *p = (templatevtab_vtab*)pVtab;
117 sqlite3_free(p);
118 return SQLITE_OK;
122 ** Constructor for a new templatevtab_cursor object.
124 static int templatevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
125 templatevtab_cursor *pCur;
126 pCur = sqlite3_malloc( sizeof(*pCur) );
127 if( pCur==0 ) return SQLITE_NOMEM;
128 memset(pCur, 0, sizeof(*pCur));
129 *ppCursor = &pCur->base;
130 return SQLITE_OK;
134 ** Destructor for a templatevtab_cursor.
136 static int templatevtabClose(sqlite3_vtab_cursor *cur){
137 templatevtab_cursor *pCur = (templatevtab_cursor*)cur;
138 sqlite3_free(pCur);
139 return SQLITE_OK;
144 ** Advance a templatevtab_cursor to its next row of output.
146 static int templatevtabNext(sqlite3_vtab_cursor *cur){
147 templatevtab_cursor *pCur = (templatevtab_cursor*)cur;
148 pCur->iRowid++;
149 return SQLITE_OK;
153 ** Return values of columns for the row at which the templatevtab_cursor
154 ** is currently pointing.
156 static int templatevtabColumn(
157 sqlite3_vtab_cursor *cur, /* The cursor */
158 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
159 int i /* Which column to return */
161 templatevtab_cursor *pCur = (templatevtab_cursor*)cur;
162 switch( i ){
163 case TEMPLATEVTAB_A:
164 sqlite3_result_int(ctx, 1000 + pCur->iRowid);
165 break;
166 default:
167 assert( i==TEMPLATEVTAB_B );
168 sqlite3_result_int(ctx, 2000 + pCur->iRowid);
169 break;
171 return SQLITE_OK;
175 ** Return the rowid for the current row. In this implementation, the
176 ** rowid is the same as the output value.
178 static int templatevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
179 templatevtab_cursor *pCur = (templatevtab_cursor*)cur;
180 *pRowid = pCur->iRowid;
181 return SQLITE_OK;
185 ** Return TRUE if the cursor has been moved off of the last
186 ** row of output.
188 static int templatevtabEof(sqlite3_vtab_cursor *cur){
189 templatevtab_cursor *pCur = (templatevtab_cursor*)cur;
190 return pCur->iRowid>=10;
194 ** This method is called to "rewind" the templatevtab_cursor object back
195 ** to the first row of output. This method is always called at least
196 ** once prior to any call to templatevtabColumn() or templatevtabRowid() or
197 ** templatevtabEof().
199 static int templatevtabFilter(
200 sqlite3_vtab_cursor *pVtabCursor,
201 int idxNum, const char *idxStr,
202 int argc, sqlite3_value **argv
204 templatevtab_cursor *pCur = (templatevtab_cursor *)pVtabCursor;
205 pCur->iRowid = 1;
206 return SQLITE_OK;
210 ** SQLite will invoke this method one or more times while planning a query
211 ** that uses the virtual table. This routine needs to create
212 ** a query plan for each invocation and compute an estimated cost for that
213 ** plan.
215 static int templatevtabBestIndex(
216 sqlite3_vtab *tab,
217 sqlite3_index_info *pIdxInfo
219 pIdxInfo->estimatedCost = (double)10;
220 pIdxInfo->estimatedRows = 10;
221 return SQLITE_OK;
225 ** This following structure defines all the methods for the
226 ** virtual table.
228 static sqlite3_module templatevtabModule = {
229 /* iVersion */ 0,
230 /* xCreate */ 0,
231 /* xConnect */ templatevtabConnect,
232 /* xBestIndex */ templatevtabBestIndex,
233 /* xDisconnect */ templatevtabDisconnect,
234 /* xDestroy */ 0,
235 /* xOpen */ templatevtabOpen,
236 /* xClose */ templatevtabClose,
237 /* xFilter */ templatevtabFilter,
238 /* xNext */ templatevtabNext,
239 /* xEof */ templatevtabEof,
240 /* xColumn */ templatevtabColumn,
241 /* xRowid */ templatevtabRowid,
242 /* xUpdate */ 0,
243 /* xBegin */ 0,
244 /* xSync */ 0,
245 /* xCommit */ 0,
246 /* xRollback */ 0,
247 /* xFindMethod */ 0,
248 /* xRename */ 0,
249 /* xSavepoint */ 0,
250 /* xRelease */ 0,
251 /* xRollbackTo */ 0,
252 /* xShadowName */ 0,
253 /* xIntegrity */ 0
257 #ifdef _WIN32
258 __declspec(dllexport)
259 #endif
260 int sqlite3_templatevtab_init(
261 sqlite3 *db,
262 char **pzErrMsg,
263 const sqlite3_api_routines *pApi
265 int rc = SQLITE_OK;
266 SQLITE_EXTENSION_INIT2(pApi);
267 rc = sqlite3_create_module(db, "templatevtab", &templatevtabModule, 0);
268 return rc;