Jörgen Hägglund wrote:
> I'm trying to implement virtual tables, but I seem to be in over
> my head with this.
> I get an access violation in SQLite3.dll (reading of address 00000008)
>
> Does anyone have any ideas to what I'm doing wrong?
Not really. But one mistake I had made was to read this paragraph:
| The xCreate method need not initialize the pModule, nRef, and zErrMsg
| fields of the sqlite3_vtab object. The SQLite core will take care of
| that chore.
... and to believe it.
> Anyone having some source of how to implement a really simple virtual
> table (in any language)?
Below, in C.
Regards,
Clemens
--
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sqlite3.h>
static int test_CreateConnect(sqlite3 *db, void *pAux, int argc, const char
*const argv[], sqlite3_vtab **ppVTab, char **pzErr)
{
int err;
*ppVTab = sqlite3_malloc(sizeof(struct sqlite3_vtab));
if (!*ppVTab)
return SQLITE_NOMEM;
memset(*ppVTab, 0, sizeof(**ppVTab));
err = sqlite3_declare_vtab(db, "CREATE TABLE x(ID INTEGER, Name TEXT)");
if (err != SQLITE_OK) {
sqlite3_free(*ppVTab);
*ppVTab = NULL;
return err;
}
return SQLITE_OK;
}
static int test_BestIndex(sqlite3_vtab *pVTab, sqlite3_index_info *index_info)
{
index_info->idxNum = 0;
index_info->idxStr = "";
index_info->estimatedCost = 1000000;
return SQLITE_OK;
}
static int test_DisconnectDestroy(sqlite3_vtab *pVTab)
{
sqlite3_free(pVTab);
return SQLITE_OK;
}
struct test_cursor {
sqlite3_vtab_cursor base;
int row;
};
static int test_Open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor)
{
struct test_cursor *cursor;
cursor = sqlite3_malloc(sizeof(struct test_cursor));
if (!cursor)
return SQLITE_NOMEM;
memset(cursor, 0, sizeof(*cursor));
*ppCursor = &cursor->base;
return SQLITE_OK;
}
static int test_Close(sqlite3_vtab_cursor *pCursor)
{
sqlite3_free(pCursor);
return SQLITE_OK;
}
static int test_Eof(sqlite3_vtab_cursor *pCursor)
{
struct test_cursor *cursor = (void *)pCursor;
return cursor->row >= 5;
}
static int test_Filter(sqlite3_vtab_cursor *pCursor, int idxNum, const char
*idxStr, int argc, sqlite3_value **argv)
{
struct test_cursor *cursor = (void *)pCursor;
cursor->row = 0;
return SQLITE_OK;
}
static int test_Next(sqlite3_vtab_cursor *pCursor)
{
struct test_cursor *cursor = (void *)pCursor;
cursor->row++;
return SQLITE_OK;
}
static int test_Column(sqlite3_vtab_cursor *pCursor, sqlite3_context *context,
int N)
{
struct test_cursor *cursor = (void *)pCursor;
char str[16];
switch (N) {
case 0:
sqlite3_result_int(context, 42 + cursor->row);
break;
case 1:
sprintf(str, "row%d", cursor->row);
sqlite3_result_text(context, str, -1, SQLITE_TRANSIENT);
break;
}
return SQLITE_OK;
}
static int test_Rowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid)
{
struct test_cursor *cursor = (void *)pCursor;
*pRowid = cursor->row;
return SQLITE_OK;
}
static int test_Rename(sqlite3_vtab* pVTab, const char *zNew)
{
return SQLITE_OK;
}
static sqlite3_module module = {
.iVersion = 1,
.xCreate = test_CreateConnect,
.xConnect = test_CreateConnect,
.xBestIndex = test_BestIndex,
.xDisconnect = test_DisconnectDestroy,
.xDestroy = test_DisconnectDestroy,
.xOpen = test_Open,
.xClose = test_Close,
.xFilter = test_Filter,
.xNext = test_Next,
.xEof = test_Eof,
.xColumn = test_Column,
.xRowid = test_Rowid,
.xRename = test_Rename,
};
int main(int argc, char *argv[])
{
sqlite3 *db;
sqlite3_stmt *stmt;
int res, cols, i;
res = sqlite3_open(":memory:", &db);
assert(res == SQLITE_OK);
res = sqlite3_create_module(db, "test", &module, NULL);
assert(res == SQLITE_OK);
res = sqlite3_exec(db, "create virtual table t1 using test", NULL,
NULL, NULL);
assert(res == SQLITE_OK);
res = sqlite3_prepare_v2(db, "select * from t1", -1, &stmt, NULL);
assert(res == SQLITE_OK);
cols = sqlite3_column_count(stmt);
res = sqlite3_step(stmt);
while (res == SQLITE_ROW) {
for (i = 0; i < cols; i++)
printf(" %s", sqlite3_column_text(stmt, i));
putchar('\n');
res = sqlite3_step(stmt);
}
assert(res == SQLITE_DONE);
sqlite3_finalize(stmt);
sqlite3_close(db);
return 0;
}
_______________________________________________
sqlite-users mailing list
[email protected]
http://sqlite.org:8080/cgi-bin/mailman/listinfo/sqlite-users