Add support for on conflict clauses to fts3/fts4.

FossilOrigin-Name: 6d2633a6d0a9bb88fb1a6adac0827dc51df2d4d2
This commit is contained in:
dan
2011-04-25 18:49:57 +00:00
parent 713de341a7
commit b061d058cb
13 changed files with 297 additions and 67 deletions
+62 -8
View File
@@ -14,6 +14,18 @@
#ifndef SQLITE_OMIT_VIRTUALTABLE
#include "sqliteInt.h"
/*
** Before a virtual table xCreate() or xConnect() method is invoked, the
** sqlite3.pVtabCtx member variable is set to point to an instance of
** this struct allocated on the stack. It is used by the implementation of
** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which
** are invoked only from within xCreate and xConnect methods.
*/
struct VtabCtx {
Table *pTab;
VTable *pVTable;
};
/*
** The actual function that does the work of creating a new module.
** This function implements the sqlite3_create_module() and
@@ -434,6 +446,7 @@ static int vtabCallConstructor(
int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**),
char **pzErr
){
VtabCtx sCtx;
VTable *pVTable;
int rc;
const char *const*azArg = (const char *const*)pTab->azModuleArg;
@@ -453,12 +466,14 @@ static int vtabCallConstructor(
pVTable->db = db;
pVTable->pMod = pMod;
assert( !db->pVTab );
assert( xConstruct );
db->pVTab = pTab;
/* Invoke the virtual table constructor */
assert( &db->pVtabCtx );
assert( xConstruct );
sCtx.pTab = pTab;
sCtx.pVTable = pVTable;
db->pVtabCtx = &sCtx;
rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr);
db->pVtabCtx = 0;
if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
if( SQLITE_OK!=rc ){
@@ -474,7 +489,7 @@ static int vtabCallConstructor(
** the sqlite3_vtab object if successful. */
pVTable->pVtab->pModule = pMod->pModule;
pVTable->nRef = 1;
if( db->pVTab ){
if( sCtx.pTab ){
const char *zFormat = "vtable constructor did not declare schema: %s";
*pzErr = sqlite3MPrintf(db, zFormat, pTab->zName);
sqlite3VtabUnlock(pVTable);
@@ -522,7 +537,6 @@ static int vtabCallConstructor(
}
sqlite3DbFree(db, zModuleName);
db->pVTab = 0;
return rc;
}
@@ -642,7 +656,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
char *zErr = 0;
sqlite3_mutex_enter(db->mutex);
pTab = db->pVTab;
pTab = db->pVtabCtx->pTab;
if( !pTab ){
sqlite3Error(db, SQLITE_MISUSE, 0);
sqlite3_mutex_leave(db->mutex);
@@ -670,7 +684,7 @@ int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
pParse->pNewTable->nCol = 0;
pParse->pNewTable->aCol = 0;
}
db->pVTab = 0;
db->pVtabCtx->pTab = 0;
}else{
sqlite3Error(db, SQLITE_ERROR, (zErr ? "%s" : 0), zErr);
sqlite3DbFree(db, zErr);
@@ -937,4 +951,44 @@ void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){
}
}
int sqlite3_vtab_on_conflict(sqlite3 *db){
int aMap[] = {
SQLITE_ROLLBACK, SQLITE_IGNORE, SQLITE_ABORT, SQLITE_FAIL, SQLITE_REPLACE
};
assert( OE_Rollback==1 && OE_Abort==2 && OE_Fail==3 );
assert( OE_Ignore==4 && OE_Replace==5 );
assert( db->vtabOnConflict>=1 && db->vtabOnConflict<=5 );
return aMap[db->vtabOnConflict-1];
}
int sqlite3_vtab_config(sqlite3 *db, int op, ...){
va_list ap;
int rc = SQLITE_OK;
sqlite3_mutex_enter(db->mutex);
va_start(ap, op);
switch( op ){
case SQLITE_VTAB_CONSTRAINT_SUPPORT: {
VtabCtx *p = db->pVtabCtx;
if( !p ){
rc = SQLITE_MISUSE_BKPT;
}else{
assert( (p->pTab->tabFlags & TF_Virtual)!=0 );
p->pVTable->bConstraint = (u8)va_arg(ap, int);
}
break;
}
default:
rc = SQLITE_MISUSE_BKPT;
break;
}
va_end(ap);
if( rc!=SQLITE_OK ) sqlite3Error(db, rc, 0);
sqlite3_mutex_leave(db->mutex);
return rc;
}
#endif /* SQLITE_OMIT_VIRTUALTABLE */