diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 14:07:11 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-13 14:07:11 +0000 |
commit | 63847496f14c813a5d80efd5b7de0f1294ffe1e3 (patch) | |
tree | 01c7571c7c762ceee70638549a99834fdd7c411b /ext/misc/templatevtab.c | |
parent | Initial commit. (diff) | |
download | sqlite3-63847496f14c813a5d80efd5b7de0f1294ffe1e3.tar.xz sqlite3-63847496f14c813a5d80efd5b7de0f1294ffe1e3.zip |
Adding upstream version 3.45.1.upstream/3.45.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ext/misc/templatevtab.c')
-rw-r--r-- | ext/misc/templatevtab.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/ext/misc/templatevtab.c b/ext/misc/templatevtab.c new file mode 100644 index 0000000..5865f52 --- /dev/null +++ b/ext/misc/templatevtab.c @@ -0,0 +1,269 @@ +/* +** 2018-04-19 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements a template virtual-table. +** Developers can make a copy of this file as a baseline for writing +** new virtual tables and/or table-valued functions. +** +** Steps for writing a new virtual table implementation: +** +** (1) Make a copy of this file. Perhaps call it "mynewvtab.c" +** +** (2) Replace this header comment with something appropriate for +** the new virtual table +** +** (3) Change every occurrence of "templatevtab" to some other string +** appropriate for the new virtual table. Ideally, the new string +** should be the basename of the source file: "mynewvtab". Also +** globally change "TEMPLATEVTAB" to "MYNEWVTAB". +** +** (4) Run a test compilation to make sure the unmodified virtual +** table works. +** +** (5) Begin making incremental changes, testing as you go, to evolve +** the new virtual table to do what you want it to do. +** +** This template is minimal, in the sense that it uses only the required +** methods on the sqlite3_module object. As a result, templatevtab is +** a read-only and eponymous-only table. Those limitation can be removed +** by adding new methods. +** +** This template implements an eponymous-only virtual table with a rowid and +** two columns named "a" and "b". The table as 10 rows with fixed integer +** values. Usage example: +** +** SELECT rowid, a, b FROM templatevtab; +*/ +#if !defined(SQLITEINT_H) +#include "sqlite3ext.h" +#endif +SQLITE_EXTENSION_INIT1 +#include <string.h> +#include <assert.h> + +/* templatevtab_vtab is a subclass of sqlite3_vtab which is +** underlying representation of the virtual table +*/ +typedef struct templatevtab_vtab templatevtab_vtab; +struct templatevtab_vtab { + sqlite3_vtab base; /* Base class - must be first */ + /* Add new fields here, as necessary */ +}; + +/* templatevtab_cursor is a subclass of sqlite3_vtab_cursor which will +** serve as the underlying representation of a cursor that scans +** over rows of the result +*/ +typedef struct templatevtab_cursor templatevtab_cursor; +struct templatevtab_cursor { + sqlite3_vtab_cursor base; /* Base class - must be first */ + /* Insert new fields here. For this templatevtab we only keep track + ** of the rowid */ + sqlite3_int64 iRowid; /* The rowid */ +}; + +/* +** The templatevtabConnect() method is invoked to create a new +** template virtual table. +** +** Think of this routine as the constructor for templatevtab_vtab objects. +** +** All this routine needs to do is: +** +** (1) Allocate the templatevtab_vtab object and initialize all fields. +** +** (2) Tell SQLite (via the sqlite3_declare_vtab() interface) what the +** result set of queries against the virtual table will look like. +*/ +static int templatevtabConnect( + sqlite3 *db, + void *pAux, + int argc, const char *const*argv, + sqlite3_vtab **ppVtab, + char **pzErr +){ + templatevtab_vtab *pNew; + int rc; + + rc = sqlite3_declare_vtab(db, + "CREATE TABLE x(a,b)" + ); + /* For convenience, define symbolic names for the index to each column. */ +#define TEMPLATEVTAB_A 0 +#define TEMPLATEVTAB_B 1 + if( rc==SQLITE_OK ){ + pNew = sqlite3_malloc( sizeof(*pNew) ); + *ppVtab = (sqlite3_vtab*)pNew; + if( pNew==0 ) return SQLITE_NOMEM; + memset(pNew, 0, sizeof(*pNew)); + } + return rc; +} + +/* +** This method is the destructor for templatevtab_vtab objects. +*/ +static int templatevtabDisconnect(sqlite3_vtab *pVtab){ + templatevtab_vtab *p = (templatevtab_vtab*)pVtab; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Constructor for a new templatevtab_cursor object. +*/ +static int templatevtabOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){ + templatevtab_cursor *pCur; + pCur = sqlite3_malloc( sizeof(*pCur) ); + if( pCur==0 ) return SQLITE_NOMEM; + memset(pCur, 0, sizeof(*pCur)); + *ppCursor = &pCur->base; + return SQLITE_OK; +} + +/* +** Destructor for a templatevtab_cursor. +*/ +static int templatevtabClose(sqlite3_vtab_cursor *cur){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + sqlite3_free(pCur); + return SQLITE_OK; +} + + +/* +** Advance a templatevtab_cursor to its next row of output. +*/ +static int templatevtabNext(sqlite3_vtab_cursor *cur){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + pCur->iRowid++; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the templatevtab_cursor +** is currently pointing. +*/ +static int templatevtabColumn( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + switch( i ){ + case TEMPLATEVTAB_A: + sqlite3_result_int(ctx, 1000 + pCur->iRowid); + break; + default: + assert( i==TEMPLATEVTAB_B ); + sqlite3_result_int(ctx, 2000 + pCur->iRowid); + break; + } + return SQLITE_OK; +} + +/* +** Return the rowid for the current row. In this implementation, the +** rowid is the same as the output value. +*/ +static int templatevtabRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + *pRowid = pCur->iRowid; + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int templatevtabEof(sqlite3_vtab_cursor *cur){ + templatevtab_cursor *pCur = (templatevtab_cursor*)cur; + return pCur->iRowid>=10; +} + +/* +** This method is called to "rewind" the templatevtab_cursor object back +** to the first row of output. This method is always called at least +** once prior to any call to templatevtabColumn() or templatevtabRowid() or +** templatevtabEof(). +*/ +static int templatevtabFilter( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + templatevtab_cursor *pCur = (templatevtab_cursor *)pVtabCursor; + pCur->iRowid = 1; + return SQLITE_OK; +} + +/* +** SQLite will invoke this method one or more times while planning a query +** that uses the virtual table. This routine needs to create +** a query plan for each invocation and compute an estimated cost for that +** plan. +*/ +static int templatevtabBestIndex( + sqlite3_vtab *tab, + sqlite3_index_info *pIdxInfo +){ + pIdxInfo->estimatedCost = (double)10; + pIdxInfo->estimatedRows = 10; + return SQLITE_OK; +} + +/* +** This following structure defines all the methods for the +** virtual table. +*/ +static sqlite3_module templatevtabModule = { + /* iVersion */ 0, + /* xCreate */ 0, + /* xConnect */ templatevtabConnect, + /* xBestIndex */ templatevtabBestIndex, + /* xDisconnect */ templatevtabDisconnect, + /* xDestroy */ 0, + /* xOpen */ templatevtabOpen, + /* xClose */ templatevtabClose, + /* xFilter */ templatevtabFilter, + /* xNext */ templatevtabNext, + /* xEof */ templatevtabEof, + /* xColumn */ templatevtabColumn, + /* xRowid */ templatevtabRowid, + /* xUpdate */ 0, + /* xBegin */ 0, + /* xSync */ 0, + /* xCommit */ 0, + /* xRollback */ 0, + /* xFindMethod */ 0, + /* xRename */ 0, + /* xSavepoint */ 0, + /* xRelease */ 0, + /* xRollbackTo */ 0, + /* xShadowName */ 0, + /* xIntegrity */ 0 +}; + + +#ifdef _WIN32 +__declspec(dllexport) +#endif +int sqlite3_templatevtab_init( + sqlite3 *db, + char **pzErrMsg, + const sqlite3_api_routines *pApi +){ + int rc = SQLITE_OK; + SQLITE_EXTENSION_INIT2(pApi); + rc = sqlite3_create_module(db, "templatevtab", &templatevtabModule, 0); + return rc; +} |