summaryrefslogtreecommitdiffstats
path: root/ext/misc/templatevtab.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 14:07:11 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 14:07:11 +0000
commit63847496f14c813a5d80efd5b7de0f1294ffe1e3 (patch)
tree01c7571c7c762ceee70638549a99834fdd7c411b /ext/misc/templatevtab.c
parentInitial commit. (diff)
downloadsqlite3-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.c269
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;
+}