#include "changes-vtab.h"
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "consts.h"
#include "crsqlite.h"
#include "ext-data.h"
#include "rust.h"
#include "util.h"
int crsql_changes_next(sqlite3_vtab_cursor *cur);
static int changesConnect(sqlite3 *db, void *pAux, int argc,
const char *const *argv, sqlite3_vtab **ppVtab,
char **pzErr) {
crsql_Changes_vtab *pNew;
int rc;
rc = sqlite3_declare_vtab(
db,
"CREATE TABLE x([table] TEXT NOT NULL, [pk] BLOB NOT NULL, [cid] TEXT "
"NOT NULL, [val] ANY, [col_version] INTEGER NOT NULL, [db_version] "
"INTEGER NOT NULL, [site_id] BLOB, [cl] INTEGER NOT NULL, [seq] "
"INTEGER NOT NULL)");
if (rc != SQLITE_OK) {
*pzErr = sqlite3_mprintf("Could not define the table");
return rc;
}
pNew = sqlite3_malloc(sizeof(*pNew));
*ppVtab = (sqlite3_vtab *)pNew;
if (pNew == 0) {
*pzErr = sqlite3_mprintf("Out of memory");
return SQLITE_NOMEM;
}
memset(pNew, 0, sizeof(*pNew));
pNew->db = db;
pNew->pExtData = (crsql_ExtData *)pAux;
rc = crsql_ensureTableInfosAreUpToDate(db, pNew->pExtData,
&(*ppVtab)->zErrMsg);
if (rc != SQLITE_OK) {
*pzErr = sqlite3_mprintf("Could not update table infos");
sqlite3_free(pNew);
return rc;
}
return rc;
}
static int changesDisconnect(sqlite3_vtab *pVtab) {
crsql_Changes_vtab *p = (crsql_Changes_vtab *)pVtab;
sqlite3_free(p);
return SQLITE_OK;
}
static int changesOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor) {
crsql_Changes_cursor *pCur;
pCur = sqlite3_malloc(sizeof(*pCur));
if (pCur == 0) {
return SQLITE_NOMEM;
}
memset(pCur, 0, sizeof(*pCur));
*ppCursor = &pCur->base;
pCur->pTab = (crsql_Changes_vtab *)p;
return SQLITE_OK;
}
static int changesCrsrFinalize(crsql_Changes_cursor *crsr) {
int rc = SQLITE_OK;
rc += sqlite3_finalize(crsr->pChangesStmt);
crsr->pChangesStmt = 0;
if (crsr->pRowStmt != 0) {
rc += sqlite3_clear_bindings(crsr->pRowStmt);
rc += sqlite3_reset(crsr->pRowStmt);
}
crsr->pRowStmt = 0;
crsr->dbVersion = MIN_POSSIBLE_DB_VERSION;
return rc;
}
static int changesClose(sqlite3_vtab_cursor *cur) {
crsql_Changes_cursor *pCur = (crsql_Changes_cursor *)cur;
changesCrsrFinalize(pCur);
sqlite3_free(pCur);
return SQLITE_OK;
}
int crsql_changes_filter(sqlite3_vtab_cursor *pVtabCursor, int idxNum,
const char *idxStr, int argc, sqlite3_value **argv);
int crsql_changes_best_index(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo);
int crsql_changes_update(sqlite3_vtab *pVTab, int argc, sqlite3_value **argv,
sqlite3_int64 *pRowid);
int crsql_changes_begin(sqlite3_vtab *pVTab);
int crsql_changes_commit(sqlite3_vtab *pVTab);
int crsql_changes_rowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid);
int crsql_changes_column(
sqlite3_vtab_cursor *cur,
sqlite3_context *ctx,
int i
);
int crsql_changes_eof(sqlite3_vtab_cursor *cur);
sqlite3_module crsql_changesModule = {
0,
0,
changesConnect,
crsql_changes_best_index,
changesDisconnect,
0,
changesOpen,
changesClose,
crsql_changes_filter,
crsql_changes_next,
crsql_changes_eof,
crsql_changes_column,
crsql_changes_rowid,
crsql_changes_update,
crsql_changes_begin,
0,
crsql_changes_commit,
0,
0,
0,
0,
0,
0,
0};