mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-04 13:54:25 +08:00
first steps with sqlite
This commit is contained in:
@@ -65,6 +65,9 @@ set(BUILD_DOCUMENTATION OFF CACHE BOOL "Build the documentation")
|
||||
# Optionally build a version to be installed inside CCP4
|
||||
set(BUILD_FOR_CCP4 OFF CACHE BOOL "Build a version to be installed in CCP4")
|
||||
|
||||
# Create the cql/sqlite interface
|
||||
set(BUILD_SQLITE_INTERFACE ON CACHE BOOL "Build the sqlite interface")
|
||||
|
||||
# Building shared libraries?
|
||||
if(NOT(BUILD_FOR_CCP4 AND WIN32))
|
||||
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build a shared library instead of a static one")
|
||||
@@ -189,6 +192,10 @@ if(NOT ZLIB_FOUND)
|
||||
message(FATAL_ERROR "cifpp: The zlib development files were not found you this system, please install them and try again (hint: on debian/ubuntu use apt-get install zlib1g-dev)")
|
||||
endif()
|
||||
|
||||
if(BUILD_SQLITE_INTERFACE)
|
||||
find_package(SQLite3 REQUIRED)
|
||||
endif()
|
||||
|
||||
include(FindPkgConfig)
|
||||
|
||||
if(PKG_CONFIG_FOUND)
|
||||
@@ -352,6 +359,10 @@ if(NOT STD_CHARCONV_COMPILING)
|
||||
target_link_libraries(cifpp PUBLIC FastFloat::fast_float)
|
||||
endif()
|
||||
|
||||
if(BUILD_SQLITE_INTERFACE)
|
||||
target_link_libraries(cifpp PRIVATE SQLite::SQLite3)
|
||||
endif()
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
target_link_options(cifpp PRIVATE -undefined dynamic_lookup)
|
||||
endif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
||||
|
||||
@@ -437,15 +437,24 @@ class result
|
||||
class transaction
|
||||
{
|
||||
public:
|
||||
transaction(const datablock &db)
|
||||
: m_db(const_cast<datablock &>(db))
|
||||
{
|
||||
}
|
||||
transaction(const datablock &db);
|
||||
~transaction();
|
||||
|
||||
transaction(const transaction &) = delete;
|
||||
transaction &operator=(const transaction &) = delete;
|
||||
|
||||
result exec(std::string_view query);
|
||||
|
||||
private:
|
||||
datablock &m_db;
|
||||
struct transaction_impl *m_impl;
|
||||
};
|
||||
|
||||
// // --------------------------------------------------------------------
|
||||
|
||||
// class connection
|
||||
// {
|
||||
|
||||
// };
|
||||
|
||||
|
||||
} // namespace cif::cql
|
||||
33
sqlite-backend/CMakeLists.txt
Normal file
33
sqlite-backend/CMakeLists.txt
Normal file
@@ -0,0 +1,33 @@
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
# Copyright (c) 2025 NKI/AVL, Netherlands Cancer Institute
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this
|
||||
# list of conditions and the following disclaimer
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation
|
||||
# and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
cmake_minimum_required(VERSION 3.23)
|
||||
|
||||
project(cifpp-sqlite VERSION 1.0.0 LANGUAGES C)
|
||||
|
||||
find_package(SQLite3 REQUIRED)
|
||||
|
||||
add_library(cifpp-sqlite SHARED
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/cifpp2sqlite.c
|
||||
)
|
||||
1137
sqlite-backend/cifpp2sqlite.c
Normal file
1137
sqlite-backend/cifpp2sqlite.c
Normal file
File diff suppressed because it is too large
Load Diff
1137
sqlite-backend/cifpp2sqlite.cpp
Normal file
1137
sqlite-backend/cifpp2sqlite.cpp
Normal file
File diff suppressed because it is too large
Load Diff
269
sqlite-backend/template.c
Normal file
269
sqlite-backend/template.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -27,13 +27,18 @@
|
||||
#include "cif++/cql/transaction.hpp"
|
||||
|
||||
#include "cif++/category.hpp"
|
||||
#include "cif++/condition.hpp"
|
||||
#include "cif++/datablock.hpp"
|
||||
#include "cif++/row.hpp"
|
||||
#include "cif++/text.hpp"
|
||||
#include "cif++/validate.hpp"
|
||||
|
||||
#include <mcfp/mcfp.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <sqlite3.h>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace cif::cql
|
||||
@@ -349,7 +354,6 @@ class SimpleColumnValueExpression : public ValueExpression
|
||||
std::string mColumn;
|
||||
};
|
||||
|
||||
|
||||
// // -----------------------------------------------------------------------
|
||||
|
||||
// class StatementList : public Statement
|
||||
@@ -1253,8 +1257,6 @@ std::vector<std::pair<std::string, std::string>> Parser::ParseItemList()
|
||||
{
|
||||
Match(Token::BRACE_OPEN);
|
||||
|
||||
|
||||
|
||||
Match(Token::BRACE_CLOSE);
|
||||
}
|
||||
else
|
||||
@@ -1518,6 +1520,245 @@ cif::condition Parser::ParseWhereClause(cif::category &cat, const column_list &c
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
struct virtual_table
|
||||
{
|
||||
static int Connect(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, char **pzErr);
|
||||
static int Disconnect(sqlite3_vtab *pVtab);
|
||||
static int Open(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor);
|
||||
static int Close(sqlite3_vtab_cursor *cur);
|
||||
static int Next(sqlite3_vtab_cursor *cur);
|
||||
static int Column(
|
||||
sqlite3_vtab_cursor *cur, /* The cursor */
|
||||
sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
|
||||
int i); /* Which column to return */
|
||||
static int Rowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid);
|
||||
static int Eof(sqlite3_vtab_cursor *cur);
|
||||
static int Filter(sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv);
|
||||
static int BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo);
|
||||
|
||||
static sqlite3_module s_module;
|
||||
};
|
||||
|
||||
struct transaction_impl
|
||||
{
|
||||
const datablock &m_db;
|
||||
sqlite3 *m_sqlite_db = nullptr;
|
||||
|
||||
transaction_impl(const datablock &db);
|
||||
|
||||
~transaction_impl()
|
||||
{
|
||||
sqlite3_close(m_sqlite_db);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
sqlite3_module virtual_table::s_module{
|
||||
/* iVersion */ 0,
|
||||
/* xCreate */ 0,
|
||||
/* xConnect */ Connect,
|
||||
/* xBestIndex */ BestIndex,
|
||||
/* xDisconnect */ Disconnect,
|
||||
/* xDestroy */ 0,
|
||||
/* xOpen */ Open,
|
||||
/* xClose */ Close,
|
||||
/* xFilter */ Filter,
|
||||
/* xNext */ Next,
|
||||
/* xEof */ Eof,
|
||||
/* xColumn */ Column,
|
||||
/* xRowid */ Rowid,
|
||||
/* xUpdate */ 0,
|
||||
/* xBegin */ 0,
|
||||
/* xSync */ 0,
|
||||
/* xCommit */ 0,
|
||||
/* xRollback */ 0,
|
||||
/* xFindFunction */ 0,
|
||||
/* xRename */ 0,
|
||||
/* xSavepoint */ 0,
|
||||
/* xRelease */ 0,
|
||||
/* xRollbackTo */ 0,
|
||||
/* xShadowName */ 0,
|
||||
/* xIntegrity */ 0
|
||||
};
|
||||
|
||||
/*
|
||||
** The templatevtabConnect() method is invoked to create a new
|
||||
** template virtual table.
|
||||
**
|
||||
** Think of this routine as the constructor for virtual_table objects.
|
||||
**
|
||||
** All this routine needs to do is:
|
||||
**
|
||||
** (1) Allocate the virtual_table 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.
|
||||
*/
|
||||
int virtual_table::Connect(sqlite3 *db, void *pAux, int argc, const char *const *argv, sqlite3_vtab **ppVtab, char **pzErr)
|
||||
{
|
||||
virtual_table *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 virtual_table objects.
|
||||
*/
|
||||
int virtual_table::Disconnect(sqlite3_vtab *pVtab)
|
||||
{
|
||||
virtual_table *p = (virtual_table *)pVtab;
|
||||
sqlite3_free(p);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
** Constructor for a new templatevtab_cursor object.
|
||||
*/
|
||||
int virtual_table::Open(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.
|
||||
*/
|
||||
int virtual_table::Close(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.
|
||||
*/
|
||||
int virtual_table::Next(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.
|
||||
*/
|
||||
int virtual_table::Column(
|
||||
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.
|
||||
*/
|
||||
int virtual_table::Rowid(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.
|
||||
*/
|
||||
int virtual_table::Eof(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().
|
||||
*/
|
||||
int virtual_table::Filter(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.
|
||||
*/
|
||||
int virtual_table::BestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo)
|
||||
{
|
||||
pIdxInfo->estimatedCost = (double)10;
|
||||
pIdxInfo->estimatedRows = 10;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
transaction_impl::transaction_impl(const datablock &db)
|
||||
: m_db(db)
|
||||
{
|
||||
auto rc = sqlite3_open(":memory:", &m_sqlite_db);
|
||||
|
||||
if (rc)
|
||||
throw std::runtime_error(std::format("Cannot open databank: {}", sqlite3_errmsg(m_sqlite_db)));
|
||||
|
||||
rc = sqlite3_create_module(m_sqlite_db, "cifpp", &virtual_table::s_module, &m_db);
|
||||
|
||||
if (rc)
|
||||
throw std::runtime_error(std::format("Cannot open databank: {}", sqlite3_errmsg(m_sqlite_db)));
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
transaction::transaction(const datablock &db)
|
||||
: m_impl(new transaction_impl(db))
|
||||
{
|
||||
}
|
||||
|
||||
transaction::~transaction()
|
||||
{
|
||||
delete m_impl;
|
||||
}
|
||||
|
||||
result transaction::exec(std::string_view query)
|
||||
{
|
||||
struct membuf : public std::streambuf
|
||||
@@ -1528,9 +1769,9 @@ result transaction::exec(std::string_view query)
|
||||
}
|
||||
} buffer(const_cast<char *>(query.data()), query.size());
|
||||
|
||||
Parser p(m_db);
|
||||
auto stmt = p.Parse(&buffer);
|
||||
return { *stmt->Execute() };
|
||||
// Parser p(m_db);
|
||||
// auto stmt = p.Parse(&buffer);
|
||||
// return { *stmt->Execute() };
|
||||
}
|
||||
|
||||
} // namespace cif::cql
|
||||
Reference in New Issue
Block a user