Add start of "zonefile" virtual table.

FossilOrigin-Name: 0b7bd1694bf50a5afed22ed3026cefe53c5e7ec334167244e2caa9c56185ff43
This commit is contained in:
dan
2018-02-10 21:04:12 +00:00
parent 087529aae4
commit b3f58b8b30
4 changed files with 703 additions and 17 deletions
+679 -4
View File
@@ -44,6 +44,25 @@ typedef unsigned long u32;
#define ZONEFILE_DEFAULT_COMPRESSION 0
#define ZONEFILE_SCHEMA \
"CREATE TABLE z1(" \
" k INTEGER PRIMARY KEY," \
" v BLOB," \
" fileid INTEGER," \
" frame INTEGER," \
" ofst INTEGER," \
" sz INTEGER" \
")"
#define ZONEFILE_FILES_SCHEMA \
"CREATE TABLE z2(" \
" filename TEXT," \
" priority INTEGER," \
" ekey BLOB," \
" header JSON HIDDEN" \
")"
#include <stdio.h>
#include <string.h>
#include <assert.h>
@@ -56,6 +75,21 @@ struct ZonefileWrite {
int maxAutoFrameSize;
};
typedef struct ZonefileHeader ZonefileHeader;
struct ZonefileHeader {
u32 magicNumber;
u8 compressionTypeIndexData;
u8 compressionTypeContent;
u32 byteOffsetDictionary;
u32 byteOffsetFrames;
u32 numFrames;
u32 numKeys;
u8 encryptionType;
u8 encryptionKeyIdx;
u8 extendedHeaderVersion;
u8 extendedHeaderSize;
};
typedef struct ZonefileBuffer ZonefileBuffer;
struct ZonefileBuffer {
u8 *a;
@@ -83,7 +117,33 @@ static void zonefileTransferError(sqlite3_context *pCtx){
sqlite3_result_error(pCtx, zErr, -1);
}
static sqlite3_stmt *zonefilePrepare(
static int zonefilePrepare(
sqlite3 *db,
sqlite3_stmt **ppStmt,
char **pzErr,
const char *zFmt,
...
){
int rc;
va_list ap;
char *zSql;
va_start(ap, zFmt);
zSql = sqlite3_vmprintf(zFmt, ap);
*ppStmt = 0;
if( zSql ){
rc = sqlite3_prepare(db, zSql, -1, ppStmt, 0);
if( rc!=SQLITE_OK ){
*pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
}
sqlite3_free(zSql);
}else{
rc = SQLITE_NOMEM;
}
return rc;
}
static sqlite3_stmt *zonefileCtxPrepare(
sqlite3_context *pCtx,
const char *zFmt,
...
@@ -99,6 +159,7 @@ static sqlite3_stmt *zonefilePrepare(
if( rc!=SQLITE_OK ){
zonefileTransferError(pCtx);
}
sqlite3_free(zSql);
}else{
sqlite3_result_error_nomem(pCtx);
}
@@ -118,9 +179,9 @@ static int zonefileCompareValue(sqlite3_value *p1, sqlite3_value *p2){
if( sqlite3_value_type(p2)!=eType ) return 1;
switch( eType ){
case SQLITE_INTEGER:
return sqlite3_value_int64(p1)==sqlite3_value_int64(p2);
return sqlite3_value_int64(p1)!=sqlite3_value_int64(p2);
case SQLITE_FLOAT:
return sqlite3_value_double(p1)==sqlite3_value_double(p2);
return sqlite3_value_double(p1)!=sqlite3_value_double(p2);
case SQLITE_TEXT:
case SQLITE_BLOB: {
int n1 = sqlite3_value_bytes(p1);
@@ -192,6 +253,13 @@ static void zonefilePut32(u8 *aBuf, u32 v){
aBuf[3] = v & 0xFF;
}
static u32 zonefileGet32(u8 *aBuf){
return (((u32)aBuf[0]) << 24)
+ (((u32)aBuf[1]) << 16)
+ (((u32)aBuf[2]) << 8)
+ (((u32)aBuf[3]) << 0);
}
static void zonefileAppend32(ZonefileBuffer *pBuf, u32 v){
zonefilePut32(&pBuf->a[pBuf->n], v);
pBuf->n += 4;
@@ -212,6 +280,15 @@ static int zonefileWrite(FILE *pFd, const u8 *aBuf, int nBuf){
return res!=nBuf ? SQLITE_ERROR : SQLITE_OK;
}
static int zonefileRead(FILE *pFd, u8 *aBuf, int nBuf, i64 iOff){
int rc = fseek(pFd, iOff, SEEK_SET);
if( rc==0 ){
rc = fread(aBuf, 1, nBuf, pFd);
rc = (rc==nBuf) ? SQLITE_OK : SQLITE_ERROR;
}
return rc;
}
/*
** Function: zonefile_write(F,T[,J])
*/
@@ -247,7 +324,7 @@ static void zonefileWriteFunc(
/* Prepare the SQL statement used to read data from the source table. This
** also serves to verify the suitability of the source table schema. */
pStmt = zonefilePrepare(pCtx,
pStmt = zonefileCtxPrepare(pCtx,
"SELECT k, frame, v FROM %Q ORDER BY frame, idx, k", zTbl
);
if( pStmt==0 ) return;
@@ -296,6 +373,8 @@ static void zonefileWriteFunc(
szFrame += nBlob;
nKey++;
}
sqlite3_value_free(pPrev);
pPrev = 0;
/* Create the zonefile header in the in-memory buffer */
zonefilePut32(&aHdr[0], ZONEFILE_MAGIC_NUMBER);
@@ -333,10 +412,598 @@ static void zonefileWriteFunc(
zonefileBufferFree(&sFrames);
}
typedef struct ZonefileFilesTab ZonefileFilesTab;
struct ZonefileFilesTab {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db;
char *zBase; /* Name of this table */
char *zDb; /* Database containing this table */
sqlite3_stmt *pInsert; /* Insert into the %_shadow_file table */
sqlite3_stmt *pDelete; /* Delete by rowid from %_shadow_file table */
};
typedef struct ZonefileFilesCsr ZonefileFilesCsr;
struct ZonefileFilesCsr {
sqlite3_vtab_cursor base; /* Base class - must be first */
sqlite3_stmt *pSelect;
};
/*
** This function does the work of xCreate (if bCreate!=0) or xConnect
** (if bCreate==0) for the zonefile_files module.
*/
static int zffCreateConnect(
int bCreate,
sqlite3 *db,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
ZonefileFilesTab *p;
const char *zName = argv[2];
const char *zDb = argv[1];
int nName = strlen(zName);
int nDb = strlen(zDb);
int rc = SQLITE_OK;
if( nName<6 || memcmp(&zName[nName-6], "_files", 6)!=0 ){
*pzErr = sqlite3_mprintf("do not create zonefile_files tables directly!");
*ppVtab = 0;
return SQLITE_ERROR;
}
p = (ZonefileFilesTab*)sqlite3_malloc(sizeof(ZonefileFilesTab)+nName+1+nDb+1);
if( !p ){
rc = SQLITE_NOMEM;
}else{
memset(p, 0, sizeof(ZonefileFilesTab));
p->zBase = (char*)&p[1];
memcpy(p->zBase, zName, nName-6);
p->zBase[nName-6] = '\0';
p->zDb = &p->zBase[nName+1];
memcpy(p->zDb, zDb, nDb+1);
p->db = db;
rc = sqlite3_declare_vtab(db, ZONEFILE_FILES_SCHEMA);
}
if( rc!=SQLITE_OK ){
sqlite3_free(p);
p = 0;
}
*ppVtab = (sqlite3_vtab*)p;
return rc;
}
/*
** zonefile_files virtual table module xCreate method.
*/
static int zffCreate(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
return zffCreateConnect(1, db, argc, argv, ppVtab, pzErr);
}
/*
** zonefile_files virtual table module xConnect method.
*/
static int zffConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
return zffCreateConnect(0, db, argc, argv, ppVtab, pzErr);
}
/*
** zonefile_files virtual table module xDisconnect method.
*/
static int zffDisconnect(sqlite3_vtab *pVtab){
ZonefileFilesTab *pTab = (ZonefileFilesTab*)pVtab;
sqlite3_finalize(pTab->pInsert);
sqlite3_finalize(pTab->pDelete);
sqlite3_free(pTab);
return SQLITE_OK;
}
/*
** zonefile_files virtual table module xBestIndex method.
*/
static int zffBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
return SQLITE_OK;
}
/*
** zonefile_files virtual table module xOpen method.
*/
static int zffOpen(sqlite3_vtab *pVtab, sqlite3_vtab_cursor **ppCursor){
ZonefileFilesCsr *pCsr;
pCsr = (ZonefileFilesCsr*)sqlite3_malloc(sizeof(ZonefileFilesCsr));
if( pCsr==0 ){
return SQLITE_NOMEM;
}
memset(pCsr, 0, sizeof(ZonefileFilesCsr));
*ppCursor = (sqlite3_vtab_cursor*)pCsr;
return SQLITE_OK;
}
static void zffCursorReset(ZonefileFilesCsr *pCsr){
sqlite3_finalize(pCsr->pSelect);
pCsr->pSelect = 0;
}
/*
** zonefile_files virtual table module xClose method.
*/
static int zffClose(sqlite3_vtab_cursor *cur){
ZonefileFilesCsr *pCsr = (ZonefileFilesCsr*)cur;
zffCursorReset(pCsr);
sqlite3_free(pCsr);
return SQLITE_OK;
}
/*
** zonefile_files virtual table module xNext method.
*/
static int zffNext(sqlite3_vtab_cursor *cur){
ZonefileFilesCsr *pCsr = (ZonefileFilesCsr*)cur;
int rc;
if( SQLITE_ROW==sqlite3_step(pCsr->pSelect) ){
rc = SQLITE_OK;
}else{
rc = sqlite3_finalize(pCsr->pSelect);
pCsr->pSelect = 0;
}
return rc;
}
/*
** zonefile_files virtual table module xFilter method.
*/
static int zffFilter(
sqlite3_vtab_cursor *cur,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
ZonefileFilesCsr *pCsr = (ZonefileFilesCsr*)cur;
ZonefileFilesTab *pTab = (ZonefileFilesTab*)(pCsr->base.pVtab);
int rc;
zffCursorReset(pCsr);
rc = zonefilePrepare(pTab->db, &pCsr->pSelect, &pTab->base.zErrMsg,
"SELECT filename, fileid FROM %Q.'%q_shadow_file'",
pTab->zDb, pTab->zBase
);
if( rc==SQLITE_OK ){
rc = zffNext(cur);
}
return rc;
}
/*
** zonefile_files virtual table module xEof method.
*/
static int zffEof(sqlite3_vtab_cursor *cur){
ZonefileFilesCsr *pCsr = (ZonefileFilesCsr*)cur;
return pCsr->pSelect==0;
}
static FILE *zonefileOpenFile(sqlite3_context *pCtx, const char *zFile){
FILE *pFd = fopen(zFile, "r");
if( pFd==0 ){
zonefileCtxError(pCtx, "failed to open file for reading: \"%s\"", zFile);
}
return pFd;
}
static void zonefileHeaderDeserialize(u8 *aBuf, ZonefileHeader *pHdr){
pHdr->magicNumber = zonefileGet32(&aBuf[0]);
pHdr->compressionTypeIndexData = aBuf[4];
pHdr->compressionTypeContent = aBuf[5];
pHdr->byteOffsetDictionary = zonefileGet32(&aBuf[6]);
pHdr->byteOffsetFrames = zonefileGet32(&aBuf[10]);
pHdr->numFrames = zonefileGet32(&aBuf[14]);
pHdr->numKeys = zonefileGet32(&aBuf[18]);
pHdr->encryptionType = aBuf[22];
pHdr->encryptionKeyIdx = aBuf[23];
pHdr->extendedHeaderVersion = aBuf[24];
pHdr->extendedHeaderSize = aBuf[25];
}
static void zonefileJsonHeader(sqlite3_context *pCtx, const char *zFile){
FILE *pFd = zonefileOpenFile(pCtx, zFile);
if( pFd ){
int rc;
ZonefileHeader hdr;
u8 aBuf[ZONEFILE_SZ_HEADER];
rc = zonefileRead(pFd, aBuf, ZONEFILE_SZ_HEADER, 0);
if( rc==SQLITE_OK ){
zonefileHeaderDeserialize(aBuf, &hdr);
}
if( rc!=SQLITE_OK ){
zonefileCtxError(pCtx, "failed to read header from file: \"%s\"", zFile);
}else{
char *zJson = sqlite3_mprintf("{"
"\"magicNumber\":%u,"
"\"compressionTypeIndexData\":%u,"
"\"compressionTypeContent\":%u,"
"\"byteOffsetDictionary\":%u,"
"\"byteOffsetFrames\":%u,"
"\"numFrames\":%u,"
"\"numKeys\":%u,"
"\"encryptionType\":%u,"
"\"encryptionKeyIdx\":%u,"
"\"extendedHeaderVersion\":%u,"
"\"extendedHeaderSize\":%u}",
(u32)hdr.magicNumber,
(u32)hdr.compressionTypeIndexData,
(u32)hdr.compressionTypeContent,
(u32)hdr.byteOffsetDictionary,
(u32)hdr.byteOffsetFrames,
(u32)hdr.numFrames,
(u32)hdr.numKeys,
(u32)hdr.encryptionType,
(u32)hdr.encryptionKeyIdx,
(u32)hdr.extendedHeaderVersion,
(u32)hdr.extendedHeaderSize
);
if( zJson ){
sqlite3_result_text(pCtx, zJson, -1, SQLITE_TRANSIENT);
sqlite3_free(zJson);
}else{
sqlite3_result_error_nomem(pCtx);
}
}
fclose(pFd);
}
}
/*
** zonefile_files virtual table module xColumn method.
*/
static int zffColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
ZonefileFilesCsr *pCsr = (ZonefileFilesCsr*)cur;
switch( i ){
case 0: /* filename */
sqlite3_result_value(ctx, sqlite3_column_value(pCsr->pSelect, 0));
break;
case 1: /* priority */
break;
case 2: /* ekey */
break;
case 3: { /* header */
const char *zFile = (const char*)sqlite3_column_text(pCsr->pSelect, 0);
zonefileJsonHeader(ctx, zFile);
break;
}
}
return SQLITE_OK;
}
/*
** zonefile_files virtual table module xRowid method.
*/
static int zffRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
ZonefileFilesCsr *pCsr = (ZonefileFilesCsr*)cur;
*pRowid = sqlite3_column_int64(pCsr->pSelect, 1);
return SQLITE_OK;
}
/*
** zonefile_files virtual table module xUpdate method.
**
** A delete specifies a single argument - the rowid of the row to remove.
**
** Update and insert operations pass:
**
** 1. The "old" rowid, or NULL.
** 2. The "new" rowid.
** 3. Values for each of the 4 columns: (filename,priority,ekey,header)
*/
static int zffUpdate(
sqlite3_vtab *pVtab,
int nVal,
sqlite3_value **apVal,
sqlite_int64 *pRowid
){
int rc = SQLITE_OK;
ZonefileFilesTab *pTab = (ZonefileFilesTab*)pVtab;
if( sqlite3_value_type(apVal[0])==SQLITE_INTEGER ){
if( pTab->pDelete==0 ){
rc = zonefilePrepare(pTab->db, &pTab->pInsert, &pVtab->zErrMsg,
"DELETE FROM %Q.'%q_shadow_file WHERE fileid=?",
pTab->zDb, pTab->zBase
);
}
if( rc==SQLITE_OK ){
sqlite3_bind_value(pTab->pDelete, 1, apVal[0]);
sqlite3_step(pTab->pDelete);
rc = sqlite3_reset(pTab->pDelete);
}
}
if( nVal>1 ){
if( pTab->pInsert==0 ){
rc = zonefilePrepare(pTab->db, &pTab->pInsert, &pVtab->zErrMsg,
"INSERT INTO %Q.'%q_shadow_file'(filename) VALUES(?)",
pTab->zDb, pTab->zBase
);
}
if( rc==SQLITE_OK ){
const char *zFile = (const char*)sqlite3_value_text(apVal[2]);
sqlite3_bind_text(pTab->pInsert, 1, zFile, -1, SQLITE_TRANSIENT);
sqlite3_step(pTab->pInsert);
rc = sqlite3_reset(pTab->pInsert);
}
}
return SQLITE_OK;
}
typedef struct ZonefileTab ZonefileTab;
struct ZonefileTab {
sqlite3_vtab base; /* Base class - must be first */
sqlite3 *db;
char *zName; /* Name of this table */
char *zDb; /* Name of db containing this table */
};
/*
** This function does the work of xCreate (if bCreate!=0) or xConnect
** (if bCreate==0) for the zonefile module.
**
** argv[0] -> module name ("zonefile")
** argv[1] -> database name
** argv[2] -> table name
*/
static int zonefileCreateConnect(
int bCreate,
sqlite3 *db,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
ZonefileTab *p;
const char *zName = argv[2];
const char *zDb = argv[1];
int nName = strlen(zName);
int nDb = strlen(zDb);
int rc = SQLITE_OK;
p = (ZonefileTab*)sqlite3_malloc(sizeof(ZonefileTab) + nName+1 + nDb+1);
if( !p ){
rc = SQLITE_NOMEM;
}else{
memset(p, 0, sizeof(ZonefileTab));
p->zName = (char*)&p[1];
memcpy(p->zName, zName, nName+1);
p->zDb = &p->zName[nName+1];
memcpy(p->zDb, zDb, nDb+1);
p->db = db;
if( bCreate ){
char *zSql = sqlite3_mprintf(
"CREATE TABLE %Q.'%q_shadow_idx'("
" k INTEGER PRIMARY KEY,"
" fileid INTEGER,"
" frame INTEGER,"
" ofst INTEGER,"
" sz INTEGER"
");"
"CREATE TABLE %Q.'%q_shadow_file'("
" filename TEXT,"
" priority INTEGER,"
" fileid INTEGER PRIMARY KEY"
");"
"CREATE VIRTUAL TABLE %Q.'%q_files' USING zonefile_files;",
zDb, zName, zDb, zName, zDb, zName
);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_exec(db, zSql, 0, 0, pzErr);
sqlite3_free(zSql);
}
}
if( rc==SQLITE_OK ){
rc = sqlite3_declare_vtab(db, ZONEFILE_SCHEMA);
}
}
if( rc!=SQLITE_OK ){
sqlite3_free(p);
p = 0;
}
*ppVtab = (sqlite3_vtab*)p;
return rc;
}
/*
** zonefile virtual table module xCreate method.
*/
static int zonefileCreate(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
return zonefileCreateConnect(1, db, argc, argv, ppVtab, pzErr);
}
/*
** zonefile virtual table module xConnect method.
*/
static int zonefileConnect(
sqlite3 *db,
void *pAux,
int argc, const char *const*argv,
sqlite3_vtab **ppVtab,
char **pzErr
){
return zonefileCreateConnect(0, db, argc, argv, ppVtab, pzErr);
}
/*
** zonefile virtual table module xDisconnect method.
*/
static int zonefileDisconnect(sqlite3_vtab *pVtab){
ZonefileTab *pTab = (ZonefileTab*)pVtab;
sqlite3_free(pTab);
return SQLITE_OK;
}
/*
** zonefile virtual table module xBestIndex method.
*/
static int zonefileBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
return SQLITE_OK;
}
/*
** zonefile virtual table module xDestroy method.
*/
static int zonefileDestroy(sqlite3_vtab *pVtab){
ZonefileTab *pTab = (ZonefileTab*)pVtab;
int rc = SQLITE_OK;
char *zSql = sqlite3_mprintf(
"DROP TABLE IF EXISTS %Q.'%q_shadow_idx';"
"DROP TABLE IF EXISTS %Q.'%q_shadow_file';"
"DROP TABLE IF EXISTS %Q.'%q_files';",
pTab->zDb, pTab->zName, pTab->zDb, pTab->zName, pTab->zDb, pTab->zName
);
if( zSql==0 ){
rc = SQLITE_NOMEM;
}else{
rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0);
}
if( rc==SQLITE_OK ){
zonefileDisconnect(pVtab);
}
return rc;
}
/*
** zonefile virtual table module xOpen method.
*/
static int zonefileOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
return SQLITE_OK;
}
/*
** zonefile virtual table module xClose method.
*/
static int zonefileClose(sqlite3_vtab_cursor *cur){
return SQLITE_OK;
}
/*
** zonefile virtual table module xFilter method.
*/
static int zonefileFilter(
sqlite3_vtab_cursor *pVtabCursor,
int idxNum, const char *idxStr,
int argc, sqlite3_value **argv
){
return SQLITE_OK;
}
/*
** zonefile virtual table module xNext method.
*/
static int zonefileNext(sqlite3_vtab_cursor *pVtabCursor){
return SQLITE_OK;
}
/*
** zonefile virtual table module xEof method.
*/
static int zonefileEof(sqlite3_vtab_cursor *cur){
return SQLITE_OK;
}
/*
** zonefile virtual table module xColumn method.
*/
static int zonefileColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
return SQLITE_OK;
}
/*
** zonefile virtual table module xRowid method.
*/
static int zonefileRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
return SQLITE_OK;
}
/*
** Register the "zonefile" extensions.
*/
static int zonefileRegister(sqlite3 *db){
static sqlite3_module filesModule = {
0, /* iVersion */
zffCreate, /* xCreate - create a table */
zffConnect, /* xConnect - connect to an existing table */
zffBestIndex, /* xBestIndex - Determine search strategy */
zffDisconnect, /* xDisconnect - Disconnect from a table */
zffDisconnect, /* xDestroy - Drop a table */
zffOpen, /* xOpen - open a cursor */
zffClose, /* xClose - close a cursor */
zffFilter, /* xFilter - configure scan constraints */
zffNext, /* xNext - advance a cursor */
zffEof, /* xEof */
zffColumn, /* xColumn - read data */
zffRowid, /* xRowid - read data */
zffUpdate, /* xUpdate - write data */
0, /* xBegin - begin transaction */
0, /* xSync - sync transaction */
0, /* xCommit - commit transaction */
0, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
0, /* xRename - rename the table */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
};
static sqlite3_module zonefileModule = {
0, /* iVersion */
zonefileCreate, /* xCreate - create a table */
zonefileConnect, /* xConnect - connect to an existing table */
zonefileBestIndex, /* xBestIndex - Determine search strategy */
zonefileDisconnect, /* xDisconnect - Disconnect from a table */
zonefileDestroy, /* xDestroy - Drop a table */
zonefileOpen, /* xOpen - open a cursor */
zonefileClose, /* xClose - close a cursor */
zonefileFilter, /* xFilter - configure scan constraints */
zonefileNext, /* xNext - advance a cursor */
zonefileEof, /* xEof */
zonefileColumn, /* xColumn - read data */
zonefileRowid, /* xRowid - read data */
0, /* xUpdate - write data */
0, /* xBegin - begin transaction */
0, /* xSync - sync transaction */
0, /* xCommit - commit transaction */
0, /* xRollback - rollback transaction */
0, /* xFindFunction - function overloading */
0, /* xRename - rename the table */
0, /* xSavepoint */
0, /* xRelease */
0 /* xRollbackTo */
};
struct Func {
const char *z;
int n;
@@ -345,6 +1012,7 @@ static int zonefileRegister(sqlite3 *db){
{ "zonefile_write", 2, zonefileWriteFunc },
{ "zonefile_write", 3, zonefileWriteFunc },
};
int rc = SQLITE_OK;
int i;
@@ -353,6 +1021,13 @@ static int zonefileRegister(sqlite3 *db){
rc = sqlite3_create_function(db, p->z, p->n, SQLITE_ANY, 0, p->x, 0, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "zonefile_files", &filesModule, 0);
}
if( rc==SQLITE_OK ){
rc = sqlite3_create_module(db, "zonefile", &zonefileModule, 0);
}
return rc;
}
+16 -2
View File
@@ -19,7 +19,6 @@ source [file join $testdir tester.tcl]
set testprefix zonefile1
load_static_extension db zonefile
do_execsql_test 1.0 {
CREATE TABLE zz(k INTEGER PRIMARY KEY, frame INTEGER, idx INTEGER, v BLOB);
INSERT INTO zz VALUES(1, -1, -1, randomblob(100));
@@ -27,8 +26,23 @@ do_execsql_test 1.0 {
INSERT INTO zz VALUES(3, -1, -1, randomblob(100));
}
do_execsql_test 1.1 {
SELECT zonefile_write('test.zonefile', 'zz');
}
} {{}}
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE z1 USING zonefile;
SELECT name FROM sqlite_master WHERE name LIKE 'z1%' ORDER BY 1;
} {z1 z1_files z1_shadow_file z1_shadow_idx}
do_execsql_test 2.1 {
INSERT INTO z1_files(filename) VALUES('test.zonefile');
SELECT filename,
json_extract(header, '$.magicNumber'),
json_extract(header, '$.numFrames'),
json_extract(header, '$.numKeys')
FROM z1_files;
} {test.zonefile 1179332920 1 3}
finish_test
+7 -10
View File
@@ -1,5 +1,5 @@
C Add\sthe\sstart\sof\sthe\s"zonefile"\sextension.
D 2018-02-10T17:41:01.882
C Add\sstart\sof\s"zonefile"\svirtual\stable.
D 2018-02-10T21:04:12.610
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 7a3f714b4fcf793108042b7b0a5c720b0b310ec84314d61ba7f3f49f27e550ea
@@ -409,8 +409,8 @@ F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3
F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04
F ext/userauth/userauth.c 3410be31283abba70255d71fd24734e017a4497f
F ext/zonefile/README.md d675dbdffe2cd6d54681b958a13c88433a5022d39ab9ef3d4f487a272603f902
F ext/zonefile/zonefile.c da7c63bfc0332e61cff28712ff75b08164c3a5eceef6273cac82f1fe2703b1ce
F ext/zonefile/zonefile1.test ba4ca1166bb39a4121e6e7b3ef40a57cdff47a7432c816ab90ca61c02d9648d3
F ext/zonefile/zonefile.c 835a05e6c633aa65f986971ccdc90dff8e14e5f31562907907934f32c745489e
F ext/zonefile/zonefile1.test b13e8c46b2e48fd262c47ad9dcc648763cc1bf0ab4269d9c2d55e9543e0fd97e
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60
@@ -1708,10 +1708,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 3aed949a18a251c5795f21f0385c205a127502b7e9cf06bc7f4c763951cd7984
R 49b6c60b83f70d70fd5fce453b29eb31
T *branch * zonefile
T *sym-zonefile *
T -sym-trunk *
P c125b4c380d1a20c7d71b413e96183eca9987aed3d0ba28395aa79c7c31bb6fd
R de1cffc2d7f24bccc433152f51d0cae7
U dan
Z c26dc1aef1bc29dda740f0f5df0c6eab
Z 7e0b32a62a935b3702f0204df537dbab
+1 -1
View File
@@ -1 +1 @@
c125b4c380d1a20c7d71b413e96183eca9987aed3d0ba28395aa79c7c31bb6fd
0b7bd1694bf50a5afed22ed3026cefe53c5e7ec334167244e2caa9c56185ff43