/* ** Add a new module argument to pTable.azModuleArg[]. ** The string is not copied - the pointer is stored. The ** string will be freed automatically when the table is ** deleted. */ static void addModuleArgument(sqlite3 db, Table pTable, string zArg) { int i = pTable.nModuleArg++; //int nBytes = sizeof(char )*(1+pTable.nModuleArg); //string[] azModuleArg; //sqlite3DbRealloc( db, pTable.azModuleArg, nBytes ); if (pTable.azModuleArg == null || pTable.azModuleArg.Length < pTable.nModuleArg) Array.Resize(ref pTable.azModuleArg, 3 + pTable.nModuleArg); //if ( azModuleArg == null ) //{ // int j; // for ( j = 0; j < i; j++ ) // { // sqlite3DbFree( db, ref pTable.azModuleArg[j] ); // } // sqlite3DbFree( db, ref zArg ); // sqlite3DbFree( db, ref pTable.azModuleArg ); // pTable.nModuleArg = 0; //} //else { pTable.azModuleArg[i] = zArg; //pTable.azModuleArg[i + 1] = null; //azModuleArg[i+1] = 0; } //pTable.azModuleArg = azModuleArg; }
/* ** pTab is a pointer to a Table structure representing a virtual-table. ** Return a pointer to the VTable object used by connection db to access ** this virtual-table, if one has been created, or NULL otherwise. */ VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab) { VTable *pVtab; assert( IsVirtual(pTab) ); for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); return pVtab; }
internal static extern int sqlite3_prepare_v2( sqlite3* db, /* Database handle */ string zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ out sqlite3_stmt* ppStmt, /* OUT: Statement handle */ out char* pzTail /* OUT: Pointer to unused portion of zSql */ );
// The token *pName contains the name of a database (either "main" or "temp" or the name of an attached db). This routine returns the // index of the named database in db->aDb[], or -1 if the named db does not exist. internal static int sqlite3FindDb(sqlite3 db, Token pName) { var zName = sqlite3NameFromToken(db, pName); var i = sqlite3FindDbName(db, zName); sqlite3DbFree(db, ref zName); return i; }
private static bool CreateTable(sqlite3* db, string sql) { sqlite3_stmt* createTableStmt; char* tail; int error = NativeMethods.sqlite3_prepare_v2(db, sql, sql.Length, out createTableStmt, out tail); if (error != 0) { LogErrorWithTimeStamp("sqlite3_prepare_v2 -> " + sql + " failed to execute with SQLite error code: " + error); NativeMethods.sqlite3_finalize(createTableStmt); return false; } error = NativeMethods.sqlite3_step(createTableStmt); if (error != 101) { LogErrorWithTimeStamp("sqlite3_step -> " + sql + " failed to execute with SQLite error code: " + error); NativeMethods.sqlite3_finalize(createTableStmt); return false; } NativeMethods.sqlite3_finalize(createTableStmt); return true; }
internal static extern int sqlite3_exec( sqlite3* db, /* An open database */ string sql, /* SQL to be evaluated */ IntPtr callback, /* Callback function */ IntPtr firstArg, /* 1st argument to callback */ IntPtr errmsg /* Error msg written here */ );
public StringBuilder zText; // The string collected so far #endregion Fields #region Constructors public StrAccum(int n) { db = null; zText = new StringBuilder(n); mxAlloc = 0; Context = null; }
/* ** This function invokes either the xRollback or xCommit method ** of each of the virtual tables in the sqlite3.aVTrans array. The method ** called is identified by the second argument, "offset", which is ** the offset of the method to call in the sqlite3_module structure. ** ** The array is cleared after invoking the callbacks. */ static void callFinaliser(sqlite3 db, int offset) { int i; if (db.aVTrans != null) { for (i = 0; i < db.nVTrans; i++) { VTable pVTab = db.aVTrans[i]; sqlite3_vtab p = pVTab.pVtab; if (p != null) { //int (*x)(sqlite3_vtab ); //x = *(int (*)(sqlite3_vtab ))((char )p.pModule + offset); //if( x ) x(p); if (offset == 0) { if (p.pModule.xCommit != null) p.pModule.xCommit(p); } else { if (p.pModule.xRollback != null) p.pModule.xRollback(p); } } pVTab.iSavepoint = 0; sqlite3VtabUnlock(pVTab); } sqlite3DbFree(db, ref db.aVTrans); db.nVTrans = 0; db.aVTrans = null; } }
/* ** Execute zSql on database db. Return an error code. */ static int execSql( sqlite3 db, string pzErrMsg, string zSql ) { sqlite3_stmt pStmt = null; #if !NDEBUG int rc; //VVA_ONLY( int rc; ) #endif if ( zSql == null ) { return SQLITE_NOMEM; } if ( SQLITE_OK != sqlite3_prepare( db, zSql, -1, ref pStmt, 0 ) ) { sqlite3SetString( ref pzErrMsg, db, sqlite3_errmsg( db ) ); return sqlite3_errcode( db ); } #if !NDEBUG rc = sqlite3_step( pStmt ); //VVA_ONLY( rc = ) sqlite3_step(pStmt); Debug.Assert( rc != SQLITE_ROW ); #else sqlite3_step(pStmt); #endif return vacuumFinalize( db, pStmt, pzErrMsg ); }
/* ** The first parameter (pDef) is a function implementation. The ** second parameter (pExpr) is the first argument to this function. ** If pExpr is a column in a virtual table, then let the virtual ** table implementation have an opportunity to overload the function. ** ** This routine is used to allow virtual table implementations to ** overload MATCH, LIKE, GLOB, and REGEXP operators. ** ** Return either the pDef argument (indicating no change) or a ** new FuncDef structure that is marked as ephemeral using the ** SQLITE_FUNC_EPHEM flag. */ FuncDef *sqlite3VtabOverloadFunction( sqlite3 *db, /* Database connection for reporting malloc problems */ FuncDef *pDef, /* Function to possibly overload */ int nArg, /* Number of arguments to the function */ Expr *pExpr /* First argument to the function */ ) { Table *pTab; sqlite3_vtab *pVtab; sqlite3_module *pMod; void (*xFunc)(sqlite3_context*,int,sqlite3_value**) = 0; void *pArg = 0; FuncDef *pNew; int rc = 0; char *zLowerName; unsigned char *z; /* Check to see the left operand is a column in a virtual table */ if( NEVER(pExpr==0) ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef; pTab = pExpr->pTab; if( NEVER(pTab==0) ) return pDef; if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef; pVtab = sqlite3GetVTable(db, pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; /* Call the xFindFunction method on the virtual table implementation ** to see if the implementation wants to overload this function */ zLowerName = sqlite3DbStrDup(db, pDef->zName); if( zLowerName ){ for(z=(unsigned char*)zLowerName; *z; z++){ *z = sqlite3UpperToLower[*z]; } rc = pMod->xFindFunction(pVtab, nArg, zLowerName, &xFunc, &pArg); sqlite3DbFree(db, zLowerName); } if( rc==0 ){ return pDef; } /* Create a new ephemeral function definition for the overloaded ** function */ pNew = sqlite3DbMallocZero(db, sizeof(*pNew) + sqlite3Strlen30(pDef->zName) + 1); if( pNew==0 ){ return pDef; } *pNew = *pDef; pNew->zName = (char *)&pNew[1]; memcpy(pNew->zName, pDef->zName, sqlite3Strlen30(pDef->zName)+1); pNew->xFunc = xFunc; pNew->pUserData = pArg; pNew->flags |= SQLITE_FUNC_EPHEM; return pNew; }
internal static void CheckOk(sqlite3 db, int rc) { int extended = raw.sqlite3_extended_errcode(db); if (raw.SQLITE_OK != rc) { throw SQLiteException.Create(rc, extended, raw.sqlite3_errmsg(db)); } }
// Reclaim the memory used by an index internal static void freeIndex(sqlite3 db, ref Index p) { #if !SQLITE_OMIT_ANALYZE sqlite3DeleteIndexSamples(db, p); #endif sqlite3DbFree(db, ref p.zColAff); sqlite3DbFree(db, ref p); }
//OVERLOADS static public int sqlite3_exec( sqlite3 db, /* The database on which the SQL executes */ string zSql, /* The SQL to be executed */ int NoCallback, int NoArgs, int NoErrors ) { string Errors = ""; return sqlite3_exec( db, zSql, null, null, ref Errors ); }
/* ** 2003 April 6 ** ** 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 contains code used to implement the VACUUM command. ** ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2011-05-19 13:26:54 ed1da510a239ea767a01dc332b667119fa3c908e ** ************************************************************************* */ //#include "sqliteInt.h" //#include "vdbeInt.h" #if !SQLITE_OMIT_VACUUM && !SQLITE_OMIT_ATTACH /* ** Finalize a prepared statement. If there was an error, store the ** text of the error message in *pzErrMsg. Return the result code. */ static int vacuumFinalize( sqlite3 db, sqlite3_stmt pStmt, string pzErrMsg ) { int rc; rc = sqlite3VdbeFinalize( ref pStmt ); if ( rc != 0 ) { sqlite3SetString( ref pzErrMsg, db, sqlite3_errmsg( db ) ); } return rc; }
/* ** This is the entry point to register the extension for the cube() function. */ static int cube_init( sqlite3 db, ref string pzErrMsg, sqlite3_api_routines pApi ) { sqlite3_api = pApi; //SQLITE_EXTENSION_INIT2( pApi ); sqlite3_create_function( db, "cube", 1, SQLITE_ANY, 0, cubeFunc, null, null ); return 0; }
/* ** Open a blob handle. */ int sqlite3_blob_open( sqlite3* db, /* The database connection */ string zDb, /* The attached database containing the blob */ string zTable, /* The table containing the blob */ string zColumn, /* The column containing the blob */ sqlite_int64 iRow, /* The row containing the glob */ int flags, /* True -> read/write access, false -> read-only */ sqlite3_blob **ppBlob /* Handle for accessing the blob returned here */ ){ int nAttempt = 0; int iCol; /* Index of zColumn in row-record */
static public int sqlite3_exec( sqlite3 db, /* The database on which the SQL executes */ string zSql, /* The SQL to be executed */ sqlite3_callback xCallback, /* Invoke this callback routine */ object pArg, /* First argument to xCallback() */ int NoErrors ) { string Errors = ""; return sqlite3_exec( db, zSql, xCallback, pArg, ref Errors ); }
/* ** 2001 September 15 ** ** 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 contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2011-06-23 19:49:22 4374b7e83ea0a3fbc3691f9c0c936272862f32f2 ** ************************************************************************* */ //#include "sqliteInt.h" /* ** Delete all the content of a Select structure but do not deallocate ** the select structure itself. */ static void clearSelect( sqlite3 db, Select p ) { sqlite3ExprListDelete( db, ref p.pEList ); sqlite3SrcListDelete( db, ref p.pSrc ); sqlite3ExprDelete( db, ref p.pWhere ); sqlite3ExprListDelete( db, ref p.pGroupBy ); sqlite3ExprDelete( db, ref p.pHaving ); sqlite3ExprListDelete( db, ref p.pOrderBy ); sqlite3SelectDelete( db, ref p.pPrior ); sqlite3ExprDelete( db, ref p.pLimit ); sqlite3ExprDelete( db, ref p.pOffset ); }
public static int sqlite3_prepare_v2( sqlite3 db, /* Database handle. */ string zSql, /* UTF-8 encoded SQL statement. */ int nBytes, /* Length of zSql in bytes. */ ref sqlite3_stmt ppStmt, /* OUT: A pointer to the prepared statement */ ref string pzTail /* OUT: End of parsed string */ ) { int rc; rc = sqlite3LockAndPrepare( db, zSql, nBytes, 1, null, ref ppStmt, ref pzTail ); Debug.Assert( rc == SQLITE_OK || ppStmt == null ); /* VERIFY: F13021 */ return rc; }
/* ** ** 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 contains the implementation for TRIGGERs ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2010-03-09 19:31:43 4ae453ea7be69018d8c16eb8dabe05617397dc4d ** ** $Header: Community.CsharpSqlite/src/trigger_c.cs,v 6604176a7dbe 2010/03/12 23:35:36 Noah $ ************************************************************************* */ //#include "sqliteInt.h" #if !SQLITE_OMIT_TRIGGER /* ** Delete a linked list of TriggerStep structures. */ static void sqlite3DeleteTriggerStep( sqlite3 db, ref TriggerStep pTriggerStep ) { while ( pTriggerStep != null ) { TriggerStep pTmp = pTriggerStep; pTriggerStep = pTriggerStep.pNext; sqlite3ExprDelete( db, ref pTmp.pWhere ); sqlite3ExprListDelete( db, ref pTmp.pExprList ); sqlite3SelectDelete( db, ref pTmp.pSelect ); sqlite3IdListDelete( db, ref pTmp.pIdList ); pTriggerStep = null;sqlite3DbFree( db, ref pTmp ); } }
// Parameter zName points to a nul-terminated buffer containing the name of a database ("main", "temp" or the name of an attached db). This // function returns the index of the named database in db->aDb[], or -1 if the named db cannot be found. internal static int sqlite3FindDbName(sqlite3 db, string zName) { var i = -1; /* Database number */ if (zName != null) { int n = sqlite3Strlen30(zName); for (i = (db.nDb - 1); i >= 0; i--) { var pDb = db.aDb[i]; if ((OMIT_TEMPDB == 0 || i != 1) && n == sqlite3Strlen30(pDb.zName) && pDb.zName.Equals(zName, StringComparison.InvariantCultureIgnoreCase)) break; } } return i; }
/* ** Create a new virtual database engine. */ static Vdbe sqlite3VdbeCreate( sqlite3 db ) { Vdbe p; p = new Vdbe();// sqlite3DbMallocZero(db, Vdbe).Length; if ( p == null ) return null; p.db = db; if ( db.pVdbe != null ) { db.pVdbe.pPrev = p; } p.pNext = db.pVdbe; p.pPrev = null; db.pVdbe = p; p.magic = VDBE_MAGIC_INIT; return p; }
/* Methods for the wholenumber module */ static int wholenumberConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ) { sqlite3_vtab pNew; pNew = ppVtab = new sqlite3_vtab();//sqlite3_malloc( sizeof(*pNew) ); //if ( pNew == null ) // return SQLITE_NOMEM; sqlite3_declare_vtab( db, "CREATE TABLE x(value)" ); //memset(pNew, 0, sizeof(*pNew)); pzErr = ""; return SQLITE_OK; }
/* ** Locate and return an entry from the db.aCollSeq hash table. If the entry ** specified by zName and nName is not found and parameter 'create' is ** true, then create a new entry. Otherwise return NULL. ** ** Each pointer stored in the sqlite3.aCollSeq hash table contains an ** array of three CollSeq structures. The first is the collation sequence ** prefferred for UTF-8, the second UTF-16le, and the third UTF-16be. ** ** Stored immediately after the three collation sequences is a copy of ** the collation sequence name. A pointer to this string is stored in ** each collation sequence structure. */ static CollSeq[] findCollSeqEntry( sqlite3 db, /* Database connection */ string zName, /* Name of the collating sequence */ int create /* Create a new entry if true */ ) { CollSeq[] pColl; int nName = sqlite3Strlen30( zName ); pColl = sqlite3HashFind( db.aCollSeq, zName, nName, (CollSeq[])null ); if ( ( null == pColl ) && create != 0 ) { pColl = new CollSeq[3]; //sqlite3DbMallocZero(db, 3*sizeof(*pColl) + nName + 1 ); if ( pColl != null ) { CollSeq pDel = null; pColl[0] = new CollSeq(); pColl[0].zName = zName; pColl[0].enc = SQLITE_UTF8; pColl[1] = new CollSeq(); pColl[1].zName = zName; pColl[1].enc = SQLITE_UTF16LE; pColl[2] = new CollSeq(); pColl[2].zName = zName; pColl[2].enc = SQLITE_UTF16BE; //memcpy(pColl[0].zName, zName, nName); //pColl[0].zName[nName] = 0; CollSeq[] pDelArray = sqlite3HashInsert( ref db.aCollSeq, pColl[0].zName, nName, pColl ); if ( pDelArray != null ) pDel = pDelArray[0]; /* If a malloc() failure occurred in sqlite3HashInsert(), it will ** return the pColl pointer to be deleted (because it wasn't added ** to the hash table). */ Debug.Assert( pDel == null || pDel == pColl[0] ); if ( pDel != null ) { //// db.mallocFailed = 1; pDel = null; //was sqlite3DbFree(db,ref pDel); pColl = null; } } } return pColl; }
/* ** This function is a complex assert() that verifies the following ** properties of the blocked connections list: ** ** 1) Each entry in the list has a non-NULL value for either ** pUnlockConnection or pBlockingConnection, or both. ** ** 2) All entries in the list that share a common value for ** xUnlockNotify are grouped together. ** ** 3) If the argument db is not NULL, then none of the entries in the ** blocked connections list have pUnlockConnection or pBlockingConnection ** set to db. This is used when closing connection db. */ static void checkListProperties(sqlite3 *db){ sqlite3 *p; for(p=sqlite3BlockedList; p; p=p->pNextBlocked){ int seen = 0; sqlite3 *p2; /* Verify property (1) */ assert( p->pUnlockConnection || p->pBlockingConnection ); /* Verify property (2) */ for(p2=sqlite3BlockedList; p2!=p; p2=p2->pNextBlocked){ if( p2->xUnlockNotify==p->xUnlockNotify ) seen = 1; assert( p2->xUnlockNotify==p->xUnlockNotify || !seen ); assert( db==0 || p->pUnlockConnection!=db ); assert( db==0 || p->pBlockingConnection!=db ); } } }
/* ** This routine is called if the collation factory fails to deliver a ** collation function in the best encoding but there may be other versions ** of this collation function (for other text encodings) available. Use one ** of these instead if they exist. Avoid a UTF-8 <. UTF-16 conversion if ** possible. */ static int synthCollSeq( sqlite3 db, CollSeq pColl ) { CollSeq pColl2; string z = pColl.zName; int i; byte[] aEnc = { SQLITE_UTF16BE, SQLITE_UTF16LE, SQLITE_UTF8 }; for ( i = 0; i < 3; i++ ) { pColl2 = sqlite3FindCollSeq( db, aEnc[i], z, 0 ); if ( pColl2.xCmp != null ) { pColl = pColl2.Copy(); //memcpy(pColl, pColl2, sizeof(CollSeq)); pColl.xDel = null; /* Do not copy the destructor */ return SQLITE_OK; } } return SQLITE_ERROR; }
// Locate the in-memory structure that describes a particular database table given the name of that table and (optionally) the name of the // database containing the table. Return NULL if not found. // // If zDatabase is 0, all databases are searched for the table and the first matching table is returned. (No checking for duplicate table // names is done.) The search order is TEMP first, then MAIN, then any auxiliary databases added using the ATTACH command. // // See also sqlite3LocateTable(). internal static Table sqlite3FindTable(sqlite3 db, string zName, string zDatabase) { Table p = null; Debug.Assert(zName != null); var nName = sqlite3Strlen30(zName); // All mutexes are required for schema access. Make sure we hold them. Debug.Assert(zDatabase != null || sqlite3BtreeHoldsAllMutexes(db)); for (var i = OMIT_TEMPDB; i < db.nDb; i++) { var j = (i < 2 ? i ^ 1 : i); // Search TEMP before MAIN if (zDatabase != null && !zDatabase.Equals(db.aDb[j].zName, StringComparison.InvariantCultureIgnoreCase)) continue; Debug.Assert(sqlite3SchemaMutexHeld(db, j, null)); p = sqlite3HashFind(db.aDb[j].pSchema.tblHash, zName, nName, (Table)null); if (p != null) break; } return p; }
/* Methods for the tclvar module */ static int tclvarConnect( sqlite3 db, object pAux, int argc, string[] argv, out sqlite3_vtab ppVtab, out string pzErr ){ tclvar_vtab pVtab; string zSchema = "CREATE TABLE whatever(name TEXT, arrayname TEXT, value TEXT)"; pVtab = new tclvar_vtab();//sqlite3MallocZero( sizeof(*pVtab) ); //if( pVtab==0 ) return SQLITE_NOMEM; ppVtab = pVtab;//*ppVtab = pVtab.base; pVtab.interp = (Tcl_Interp)pAux; sqlite3_declare_vtab(db, zSchema); pzErr = ""; return SQLITE_OK; }
/* ** The actual function that does the work of creating a new module. ** This function implements the sqlite3_create_module() and ** sqlite3_create_module_v2() interfaces. */ static int createModule( sqlite3 db, /* Database in which module is registered */ string zName, /* Name assigned to this module */ sqlite3_module pModule, /* The definition of the module */ object pAux, /* Context pointer for xCreate/xConnect */ smdxDestroy xDestroy /* Module destructor function */ ) { int rc, nName; Module pMod; sqlite3_mutex_enter( db.mutex ); nName = sqlite3Strlen30( zName ); pMod = new Module();// (Module)sqlite3DbMallocRaw( db, sizeof( Module ) + nName + 1 ); if ( pMod != null ) { Module pDel; string zCopy;// = (char )(&pMod[1]); zCopy = zName;//memcpy(zCopy, zName, nName+1); pMod.zName = zCopy; pMod.pModule = pModule; pMod.pAux = pAux; pMod.xDestroy = xDestroy; pDel = (Module)sqlite3HashInsert( ref db.aModule, zCopy, nName, pMod ); if ( pDel != null && pDel.xDestroy != null ) { sqlite3ResetInternalSchema( db, -1 ); pDel.xDestroy( ref pDel.pAux ); } sqlite3DbFree( db, ref pDel ); //if( pDel==pMod ){ // db.mallocFailed = 1; //} } else if ( xDestroy != null ) { xDestroy( ref pAux ); } rc = sqlite3ApiExit( db, SQLITE_OK ); sqlite3_mutex_leave( db.mutex ); return rc; }
// Locate the in-memory structure that describes a particular index given the name of that index // and the name of the database that contains the index. Return NULL if not found. // // If zDatabase is 0, all databases are searched for the table and the first matching index is returned. (No checking // for duplicate index names is done.) The search order is TEMP first, then MAIN, then any auxiliary databases added // using the ATTACH command. internal static Index sqlite3FindIndex(sqlite3 db, string zName, string zDb) { Index p = null; int nName = sqlite3Strlen30(zName); // All mutexes are required for schema access. Make sure we hold them. Debug.Assert(zDb != null || sqlite3BtreeHoldsAllMutexes(db)); for (var i = OMIT_TEMPDB; i < db.nDb; i++) { var j = (i < 2 ? i ^ 1 : i); // Search TEMP before MAIN var pSchema = db.aDb[j].pSchema; Debug.Assert(pSchema != null); if (zDb != null && !zDb.Equals(db.aDb[j].zName, StringComparison.InvariantCultureIgnoreCase)) continue; Debug.Assert(sqlite3SchemaMutexHeld(db, j, null)); p = sqlite3HashFind(pSchema.idxHash, zName, nName, (Index)null); if (p != null) break; } return p; }
/* ** 2003 January 11 ** ** 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 contains code used to implement the sqlite3_set_authorizer() ** API. This facility is an optional feature of the library. Embedded ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ************************************************************************* ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart ** C#-SQLite is an independent reimplementation of the SQLite software library ** ** SQLITE_SOURCE_ID: 2010-08-23 18:52:01 42537b60566f288167f1b5864a5435986838e3a3 ** ************************************************************************* */ //#include "sqliteInt.h" /* ** All of the code in this file may be omitted by defining a single ** macro. */ #if !SQLITE_OMIT_AUTHORIZATION /* ** Set or clear the access authorization function. ** ** The access authorization function is be called during the compilation ** phase to verify that the user has read and/or write access permission on ** various fields of the database. The first argument to the auth function ** is a copy of the 3rd argument to this routine. The second argument ** to the auth function is one of these constants: ** ** SQLITE_CREATE_INDEX ** SQLITE_CREATE_TABLE ** SQLITE_CREATE_TEMP_INDEX ** SQLITE_CREATE_TEMP_TABLE ** SQLITE_CREATE_TEMP_TRIGGER ** SQLITE_CREATE_TEMP_VIEW ** SQLITE_CREATE_TRIGGER ** SQLITE_CREATE_VIEW ** SQLITE_DELETE ** SQLITE_DROP_INDEX ** SQLITE_DROP_TABLE ** SQLITE_DROP_TEMP_INDEX ** SQLITE_DROP_TEMP_TABLE ** SQLITE_DROP_TEMP_TRIGGER ** SQLITE_DROP_TEMP_VIEW ** SQLITE_DROP_TRIGGER ** SQLITE_DROP_VIEW ** SQLITE_INSERT ** SQLITE_PRAGMA ** SQLITE_READ ** SQLITE_SELECT ** SQLITE_TRANSACTION ** SQLITE_UPDATE ** ** The third and fourth arguments to the auth function are the name of ** the table and the column that are being accessed. The auth function ** should return either SQLITE_OK, SQLITE_DENY, or SQLITE_IGNORE. If ** SQLITE_OK is returned, it means that access is allowed. SQLITE_DENY ** means that the SQL statement will never-run - the sqlite3_exec() call ** will return with an error. SQLITE_IGNORE means that the SQL statement ** should run but attempts to read the specified column will return NULL ** and attempts to write the column will be ignored. ** ** Setting the auth function to NULL disables this hook. The default ** setting of the auth function is NULL. */ int sqlite3_set_authorizer( sqlite3 db, int (*xAuth)(void *, int, const char *, const char *, const char *, const char),
//# define sqlite3BtreeLeaveAll(X) static void sqlite3BtreeLeaveAll(sqlite3 X) { }
/* ** tclcmd: abuse_create_function ** ** Make various calls to sqlite3_create_function that do not have valid ** parameters. Verify that the error condition is detected and reported. */ static int abuse_create_function( object clientdata, Tcl_Interp interp, int objc, Tcl_Obj[] objv ) { //extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**); sqlite3 db = null; int rc; int mxArg; if (getDbPointer(interp, TCL.Tcl_GetString(objv[1]), ref db) != 0) { return(TCL.TCL_ERROR); } rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep, tStep, tFinal); if (rc != SQLITE_MISUSE) { goto abuse_err; } rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep, tStep, null); if (rc != SQLITE_MISUSE) { goto abuse_err; } rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, tStep, null, tFinal); if (rc != SQLITE_MISUSE) { goto abuse_err; } rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, null, null, tFinal); if (rc != SQLITE_MISUSE) { goto abuse_err; } rc = sqlite3_create_function(db, "tx", 1, SQLITE_UTF8, 0, null, tStep, null); if (rc != SQLITE_MISUSE) { goto abuse_err; } rc = sqlite3_create_function(db, "tx", -2, SQLITE_UTF8, 0, tStep, null, null); if (rc != SQLITE_MISUSE) { goto abuse_err; } rc = sqlite3_create_function(db, "tx", 128, SQLITE_UTF8, 0, tStep, null, null); if (rc != SQLITE_MISUSE) { goto abuse_err; } rc = sqlite3_create_function(db, "funcxx" + "_123456789_123456789_123456789_123456789_123456789" + "_123456789_123456789_123456789_123456789_123456789" + "_123456789_123456789_123456789_123456789_123456789" + "_123456789_123456789_123456789_123456789_123456789" + "_123456789_123456789_123456789_123456789_123456789", 1, SQLITE_UTF8, 0, tStep, null, null); if (rc != SQLITE_MISUSE) { goto abuse_err; } /* This last function registration should actually work. Generate ** a no-op function (that always returns NULL) and which has the ** maximum-length function name and the maximum number of parameters. */ sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, 10000); mxArg = sqlite3_limit(db, SQLITE_LIMIT_FUNCTION_ARG, -1); rc = sqlite3_create_function(db, "nullx" + "_123456789_123456789_123456789_123456789_123456789" + "_123456789_123456789_123456789_123456789_123456789" + "_123456789_123456789_123456789_123456789_123456789" + "_123456789_123456789_123456789_123456789_123456789" + "_123456789_123456789_123456789_123456789_123456789", mxArg, SQLITE_UTF8, 0, tStep, null, null); if (rc != SQLITE_OK) { goto abuse_err; } return(TCL.TCL_OK); abuse_err: TCL.Tcl_AppendResult(interp, "sqlite3_create_function abused test failed" ); return(TCL.TCL_ERROR); }
private SqlConnection(IPersistentStorageFaultInjector faultInjector, sqlite3 handle) { _faultInjector = faultInjector; _handle = handle; }
/// <summary> /// This function is used by SQL generated to implement the /// ALTER TABLE command. The first argument is the text of a CREATE TRIGGER /// statement. The second is a table name. The table name in the CREATE /// TRIGGER statement is replaced with the third argument and the result /// returned. This is analagous to renameTableFunc() above, except for CREATE /// TRIGGER, not CREATE INDEX and CREATE TABLE. /// </summary> static void renameTriggerFunc( sqlite3_context context, int NotUsed, sqlite3_value[] argv ) { string zSql = sqlite3_value_text(argv[0]); string zTableName = sqlite3_value_text(argv[1]); int token = 0; Token tname = new Token(); int dist = 3; int zCsr = 0; int zLoc = 0; int len = 1; string zRet; sqlite3 db = sqlite3_context_db_handle(context); UNUSED_PARAMETER(NotUsed); /* The principle used to locate the table name in the CREATE TRIGGER ** statement is that the table name is the first token that is immediatedly ** preceded by either TK_ON or TK_DOT and immediatedly followed by one ** of TK_WHEN, TK_BEGIN or TK_FOR. */ if (zSql != null) { do { if (zCsr == zSql.Length) { /* Ran out of input before finding the table name. Return NULL. */ return; } /* Store the token that zCsr points to in tname. */ zLoc = zCsr; tname.z = zSql.Substring(zCsr, len); //(char*)zCsr; tname.n = len; /* Advance zCsr to the next token. Store that token type in 'token', ** and its length in 'len' (to be used next iteration of this loop). */ do { zCsr += len; len = (zCsr == zSql.Length) ? 1 : sqlite3GetToken(zSql, zCsr, ref token); } while (token == TK_SPACE); Debug.Assert(len > 0); /* Variable 'dist' stores the number of tokens read since the most ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN ** token is read and 'dist' equals 2, the condition stated above ** to be met. ** ** Note that ON cannot be a database, table or column name, so ** there is no need to worry about syntax like ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc. */ dist++; if (token == TK_DOT || token == TK_ON) { dist = 0; } } while (dist != 2 || (token != TK_WHEN && token != TK_FOR && token != TK_BEGIN)); /* Variable tname now contains the token that is the old table-name ** in the CREATE TRIGGER statement. */ zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", zLoc, zSql.Substring(0, zLoc), zTableName, zSql.Substring(zLoc + tname.n)); sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); } }
//# define sqlite3BtreeEnterAll(X) static void sqlite3BtreeEnterAll(sqlite3 p) { }
/// <summary> /// This function is called by the parser after the table-name in /// an "ALTER TABLE <table-name> ADD" statement is parsed. Argument /// pSrc is the full-name of the table being altered. /// /// This routine makes a (partial) copy of the Table structure /// for the table being altered and sets Parse.pNewTable to point /// to it. Routines called by the parser as the column definition /// is parsed (i.e. sqlite3AddColumn()) add the new Column data to /// the copy. The copy of the Table structure is deleted by tokenize.c /// after parsing is finished. /// /// Routine sqlite3AlterFinishAddColumn() will be called to complete /// coding the "ALTER TABLE ... ADD" statement. /// </summary> static void sqlite3AlterBeginAddColumn(Parse pParse, SrcList pSrc) { Table pNew; Table pTab; Vdbe v; int iDb; int i; int nAlloc; sqlite3 db = pParse.db; /* Look up the table being altered. */ Debug.Assert(pParse.pNewTable == null); Debug.Assert(sqlite3BtreeHoldsAllMutexes(db)); // if ( db.mallocFailed != 0 ) goto exit_begin_add_column; pTab = sqlite3LocateTable(pParse, 0, pSrc.a[0].zName, pSrc.a[0].zDatabase); if (pTab == null) { goto exit_begin_add_column; } if (IsVirtual(pTab)) { sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); goto exit_begin_add_column; } /* Make sure this is not an attempt to ALTER a view. */ if (pTab.pSelect != null) { sqlite3ErrorMsg(pParse, "Cannot add a column to a view"); goto exit_begin_add_column; } if (SQLITE_OK != isSystemTable(pParse, pTab.zName)) { goto exit_begin_add_column; } Debug.Assert(pTab.addColOffset > 0); iDb = sqlite3SchemaToIndex(db, pTab.pSchema); /* Put a copy of the Table struct in Parse.pNewTable for the ** sqlite3AddColumn() function and friends to modify. But modify ** the name by adding an "sqlite_altertab_" prefix. By adding this ** prefix, we insure that the name will not collide with an existing ** table because user table are not allowed to have the "sqlite_" ** prefix on their name. */ pNew = new Table(); // (Table*)sqlite3DbMallocZero( db, sizeof(Table)) if (pNew == null) { goto exit_begin_add_column; } pParse.pNewTable = pNew; pNew.nRef = 1; pNew.nCol = pTab.nCol; Debug.Assert(pNew.nCol > 0); nAlloc = (((pNew.nCol - 1) / 8) * 8) + 8; Debug.Assert(nAlloc >= pNew.nCol && nAlloc % 8 == 0 && nAlloc - pNew.nCol < 8); pNew.aCol = new Column[nAlloc]; // (Column*)sqlite3DbMallocZero( db, sizeof(Column) * nAlloc ); pNew.zName = sqlite3MPrintf(db, "sqlite_altertab_%s", pTab.zName); if (pNew.aCol == null || pNew.zName == null) { // db.mallocFailed = 1; goto exit_begin_add_column; } // memcpy( pNew.aCol, pTab.aCol, sizeof(Column) * pNew.nCol ); for (i = 0; i < pNew.nCol; i++) { Column pCol = pTab.aCol[i].Copy(); // sqlite3DbStrDup( db, pCol.zName ); pCol.zColl = null; pCol.zType = null; pCol.pDflt = null; pCol.zDflt = null; pNew.aCol[i] = pCol; } pNew.pSchema = db.aDb[iDb].pSchema; pNew.addColOffset = pTab.addColOffset; pNew.nRef = 1; /* Begin a transaction and increment the schema cookie. */ sqlite3BeginWriteOperation(pParse, 0, iDb); v = sqlite3GetVdbe(pParse); if (v == null) { goto exit_begin_add_column; } sqlite3ChangeCookie(pParse, iDb); exit_begin_add_column: sqlite3SrcListDelete(db, ref pSrc); return; }
public static void rekey(this sqlite3 db, ReadOnlySpan <byte> k) { int rc = raw.sqlite3_rekey(db, k); check_ok(rc); }
public static void wal_checkpoint(this sqlite3 db, string dbName, int eMode, out int logSize, out int framesCheckPointed) { int rc = raw.sqlite3_wal_checkpoint_v2(db, dbName, eMode, out logSize, out framesCheckPointed); check_ok(rc); }
//# define sqlite3_result_text16be 0 //# define sqlite3_result_text16le 0 //# define sqlite3_value_text16 0 //# define sqlite3_value_text16be 0 //# define sqlite3_value_text16le 0 //# define sqlite3_column_database_name16 0 //# define sqlite3_column_table_name16 0 //# define sqlite3_column_origin_name16 0 #endif #if SQLITE_OMIT_COMPLETE //# define sqlite3_complete 0 //# define sqlite3_complete16 0 #endif #if SQLITE_OMIT_PROGRESS_CALLBACK //# define sqlite3_progress_handler 0 static void sqlite3_progress_handler(sqlite3 db, int nOps, dxProgress xProgress, object pArg) { }
//# define sqlite3SchemaMutexHeld(X,Y,Z) 1 static bool sqlite3SchemaMutexHeld(sqlite3 X, int y, Schema z) { return(true); }
/* ** An SQL user-function registered to do the work of an DETACH statement. The ** three arguments to the function come directly from a detach statement: ** ** DETACH DATABASE x ** ** SELECT sqlite_detach(x) */ static void detachFunc( sqlite3_context context, int NotUsed, sqlite3_value[] argv ) { string zName = zName = argv[0].z != null && (argv[0].z.Length > 0) ? sqlite3_value_text(argv[0]) : "";//(sqlite3_value_text(argv[0]); sqlite3 db = sqlite3_context_db_handle(context); int i; Db pDb = null; StringBuilder zErr = new StringBuilder(200); UNUSED_PARAMETER(NotUsed); if (zName == null) { zName = ""; } for (i = 0; i < db.nDb; i++) { pDb = db.aDb[i]; if (pDb.pBt == null) { continue; } if (pDb.zName.Equals(zName, StringComparison.InvariantCultureIgnoreCase)) { break; } } if (i >= db.nDb) { sqlite3_snprintf(200, zErr, "no such database: %s", zName); goto detach_error; } if (i < 2) { sqlite3_snprintf(200, zErr, "cannot detach database %s", zName); goto detach_error; } if (0 == db.autoCommit) { sqlite3_snprintf(200, zErr, "cannot DETACH database within transaction"); goto detach_error; } if (sqlite3BtreeIsInReadTrans(pDb.pBt) || sqlite3BtreeIsInBackup(pDb.pBt)) { sqlite3_snprintf(200, zErr, "database %s is locked", zName); goto detach_error; } sqlite3BtreeClose(ref pDb.pBt); pDb.pBt = null; pDb.pSchema = null; sqlite3ResetInternalSchema(db, -1); return; detach_error: sqlite3_result_error(context, zErr.ToString(), -1); }
/* ** Run the parser on the given SQL string. The parser structure is ** passed in. An SQLITE_ status code is returned. If an error occurs ** then an and attempt is made to write an error message into ** memory obtained from sqlite3_malloc() and to make pzErrMsg point to that ** error message. */ static int sqlite3RunParser(Parse pParse, string zSql, ref string pzErrMsg) { int nErr = 0; /* Number of errors encountered */ int i; /* Loop counter */ yyParser pEngine; /* The LEMON-generated LALR(1) parser */ int tokenType = 0; /* type of the next token */ int lastTokenParsed = -1; /* type of the previous token */ byte enableLookaside; /* Saved value of db->lookaside.bEnabled */ sqlite3 db = pParse.db; /* The database connection */ int mxSqlLen; /* Max length of an SQL string */ mxSqlLen = db.aLimit[SQLITE_LIMIT_SQL_LENGTH]; if (db.activeVdbeCnt == 0) { db.u1.isInterrupted = false; } pParse.rc = SQLITE_OK; pParse.zTail = new StringBuilder(zSql); i = 0; Debug.Assert(pzErrMsg != null); pEngine = sqlite3ParserAlloc();//sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc); //if ( pEngine == null ) //{ // db.mallocFailed = 1; // return SQLITE_NOMEM; //} Debug.Assert(pParse.pNewTable == null); Debug.Assert(pParse.pNewTrigger == null); Debug.Assert(pParse.nVar == 0); Debug.Assert(pParse.nzVar == 0); Debug.Assert(pParse.azVar == null); enableLookaside = db.lookaside.bEnabled; if (db.lookaside.pStart != 0) { db.lookaside.bEnabled = 1; } while (/* 0 == db.mallocFailed && */ i < zSql.Length) { Debug.Assert(i >= 0); //pParse->sLastToken.z = &zSql[i]; pParse.sLastToken.n = sqlite3GetToken(zSql, i, ref tokenType); pParse.sLastToken.z = zSql.Substring(i); i += pParse.sLastToken.n; if (i > mxSqlLen) { pParse.rc = SQLITE_TOOBIG; break; } switch (tokenType) { case TK_SPACE: { if (db.u1.isInterrupted) { sqlite3ErrorMsg(pParse, "interrupt"); pParse.rc = SQLITE_INTERRUPT; goto abort_parse; } break; } case TK_ILLEGAL: { sqlite3DbFree(db, ref pzErrMsg); pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"", (object)pParse.sLastToken); nErr++; goto abort_parse; } case TK_SEMI: { //pParse.zTail = new StringBuilder(zSql.Substring( i,zSql.Length-i )); /* Fall thru into the default case */ goto default; } default: { sqlite3Parser(pEngine, tokenType, pParse.sLastToken, pParse); lastTokenParsed = tokenType; if (pParse.rc != SQLITE_OK) { goto abort_parse; } break; } } } abort_parse: pParse.zTail = new StringBuilder(zSql.Length <= i ? "" : zSql.Substring(i, zSql.Length - i)); if (zSql.Length >= i && nErr == 0 && pParse.rc == SQLITE_OK) { if (lastTokenParsed != TK_SEMI) { sqlite3Parser(pEngine, TK_SEMI, pParse.sLastToken, pParse); } sqlite3Parser(pEngine, 0, pParse.sLastToken, pParse); } #if YYTRACKMAXSTACKDEPTH sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK, sqlite3ParserStackPeak(pEngine) ); #endif //* YYDEBUG */ sqlite3ParserFree(pEngine, null);//sqlite3_free ); db.lookaside.bEnabled = enableLookaside; //if ( db.mallocFailed != 0 ) //{ // pParse.rc = SQLITE_NOMEM; //} if (pParse.rc != SQLITE_OK && pParse.rc != SQLITE_DONE && pParse.zErrMsg == "") { sqlite3SetString(ref pParse.zErrMsg, db, sqlite3ErrStr(pParse.rc)); } //assert( pzErrMsg!=0 ); if (pParse.zErrMsg != null) { pzErrMsg = pParse.zErrMsg; sqlite3_log(pParse.rc, "%s", pzErrMsg); pParse.zErrMsg = ""; nErr++; } if (pParse.pVdbe != null && pParse.nErr > 0 && pParse.nested == 0) { sqlite3VdbeDelete(ref pParse.pVdbe); pParse.pVdbe = null; } #if !SQLITE_OMIT_SHARED_CACHE if (pParse.nested == 0) { sqlite3DbFree(db, ref pParse.aTableLock); pParse.aTableLock = null; pParse.nTableLock = 0; } #endif #if !SQLITE_OMIT_VIRTUALTABLE pParse.apVtabLock = null;//sqlite3_free( pParse.apVtabLock ); #endif if (!IN_DECLARE_VTAB(pParse)) { /* If the pParse.declareVtab flag is set, do not delete any table ** structure built up in pParse.pNewTable. The calling code (see vtab.c) ** will take responsibility for freeing the Table structure. */ sqlite3DeleteTable(db, ref pParse.pNewTable); } #if !SQLITE_OMIT_TRIGGER sqlite3DeleteTrigger(db, ref pParse.pNewTrigger); #endif //for ( i = pParse.nzVar - 1; i >= 0; i-- ) // sqlite3DbFree( db, pParse.azVar[i] ); sqlite3DbFree(db, ref pParse.azVar); sqlite3DbFree(db, ref pParse.aAlias); while (pParse.pAinc != null) { AutoincInfo p = pParse.pAinc; pParse.pAinc = p.pNext; sqlite3DbFree(db, ref p); } while (pParse.pZombieTab != null) { Table p = pParse.pZombieTab; pParse.pZombieTab = p.pNextZombie; sqlite3DeleteTable(db, ref p); } if (nErr > 0 && pParse.rc == SQLITE_OK) { pParse.rc = SQLITE_ERROR; } return(nErr); }
static sqlite3 va_arg(object[] ap, sqlite3 sysType) { return((sqlite3)ap[vaNEXT++]); }
/* ** An SQL user-function registered to do the work of an ATTACH statement. The ** three arguments to the function come directly from an attach statement: ** ** ATTACH DATABASE x AS y KEY z ** ** SELECT sqlite_attach(x, y, z) ** ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the ** third argument. */ static void attachFunc( sqlite3_context context, int NotUsed, sqlite3_value[] argv ) { int i; int rc = 0; sqlite3 db = sqlite3_context_db_handle(context); string zName; string zFile; Db aNew = null; string zErrDyn = ""; UNUSED_PARAMETER(NotUsed); zFile = argv[0].z != null && (argv[0].z.Length > 0) ? sqlite3_value_text(argv[0]) : ""; zName = argv[1].z != null && (argv[1].z.Length > 0) ? sqlite3_value_text(argv[1]) : ""; //if( zFile==null ) zFile = ""; //if ( zName == null ) zName = ""; /* Check for the following errors: ** ** * Too many attached databases, ** * Transaction currently open ** * Specified database name already being used. */ if (db.nDb >= db.aLimit[SQLITE_LIMIT_ATTACHED] + 2) { zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", db.aLimit[SQLITE_LIMIT_ATTACHED] ); goto attach_error; } if (0 == db.autoCommit) { zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); goto attach_error; } for (i = 0; i < db.nDb; i++) { string z = db.aDb[i].zName; Debug.Assert(z != null && zName != null); if (sqlite3StrICmp(z, zName) == 0) { zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); goto attach_error; } } /* Allocate the new entry in the db.aDb[] array and initialise the schema ** hash tables. */ /* Allocate the new entry in the db.aDb[] array and initialise the schema ** hash tables. */ //if( db.aDb==db.aDbStatic ){ // aNew = sqlite3DbMallocRaw(db, sizeof(db.aDb[0])*3 ); // if( aNew==0 ) return; // memcpy(aNew, db.aDb, sizeof(db.aDb[0])*2); //}else { if (db.aDb.Length <= db.nDb) { Array.Resize(ref db.aDb, db.nDb + 1); //aNew = sqlite3DbRealloc(db, db.aDb, sizeof(db.aDb[0])*(db.nDb+1) ); } if (db.aDb == null) { return; // if( aNew==0 ) return; } //} db.aDb[db.nDb] = new Db(); //db.aDb = aNew; aNew = db.aDb[db.nDb]; //memset(aNew, 0, sizeof(*aNew)); // memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use ** it to obtain the database schema. At this point the schema may ** or may not be initialised. */ rc = sqlite3BtreeFactory(db, zFile, false, SQLITE_DEFAULT_CACHE_SIZE, db.openFlags | SQLITE_OPEN_MAIN_DB, ref aNew.pBt); db.nDb++; if (rc == SQLITE_CONSTRAINT) { rc = SQLITE_ERROR; zErrDyn = sqlite3MPrintf(db, "database is already attached"); } else if (rc == SQLITE_OK) { Pager pPager; aNew.pSchema = sqlite3SchemaGet(db, aNew.pBt); if (aNew.pSchema == null) { rc = SQLITE_NOMEM; } else if (aNew.pSchema.file_format != 0 && aNew.pSchema.enc != ENC(db)) { zErrDyn = sqlite3MPrintf(db, "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } pPager = sqlite3BtreePager(aNew.pBt); sqlite3PagerLockingMode(pPager, db.dfltLockMode); sqlite3PagerJournalMode(pPager, db.dfltJournalMode); sqlite3BtreeSecureDelete(aNew.pBt, sqlite3BtreeSecureDelete(db.aDb[0].pBt, -1)); } aNew.safety_level = 3; aNew.zName = zName;//sqlite3DbStrDup(db, zName); //if( rc==SQLITE_OK && aNew.zName==0 ){ // rc = SQLITE_NOMEM; //} #if SQLITE_HAS_CODEC if (rc == SQLITE_OK) {
public static void wal_autocheckpoint(this sqlite3 db, int n) { int rc = raw.sqlite3_wal_autocheckpoint(db, n); check_ok(rc); }
/* Make sure "isView" and other macros defined above are undefined. Otherwise ** thely may interfere with compilation of other functions in this file ** (or in another file, if this file becomes part of the amalgamation). */ //#ifdef isView // #undef isView //#endif //#ifdef pTrigger // #undef pTrigger //#endif #if !SQLITE_OMIT_VIRTUALTABLE /* ** Generate code for an UPDATE of a virtual table. ** ** The strategy is that we create an ephemerial table that contains ** for each row to be changed: ** ** (A) The original rowid of that row. ** (B) The revised rowid for the row. (note1) ** (C) The content of every column in the row. ** ** Then we loop over this ephemeral table and for each row in ** the ephermeral table call VUpdate. ** ** When finished, drop the ephemeral table. ** ** (note1) Actually, if we know in advance that (A) is always the same ** as (B) we only store (A), then duplicate (A) when pulling ** it out of the ephemeral table before calling VUpdate. */ static void updateVirtualTable( Parse pParse, /* The parsing context */ SrcList pSrc, /* The virtual table to be modified */ Table pTab, /* The virtual table */ ExprList pChanges, /* The columns to change in the UPDATE statement */ Expr pRowid, /* Expression used to recompute the rowid */ int aXRef, /* Mapping from columns of pTab to entries in pChanges */ Expr pWhere /* WHERE clause of the UPDATE statement */ ) { Vdbe v = pParse.pVdbe; /* Virtual machine under construction */ ExprList pEList = 0; /* The result set of the SELECT statement */ Select pSelect = 0; /* The SELECT statement */ Expr pExpr; /* Temporary expression */ int ephemTab; /* Table holding the result of the SELECT */ int i; /* Loop counter */ int addr; /* Address of top of loop */ int iReg; /* First register in set passed to OP_VUpdate */ sqlite3 db = pParse.db; /* Database connection */ const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); SelectDest dest; /* Construct the SELECT statement that will find the new values for ** all updated rows. */ pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, "_rowid_")); if (pRowid) { pEList = sqlite3ExprListAppend(pParse, pEList, sqlite3ExprDup(db, pRowid, 0), 0); } Debug.Assert(pTab.iPKey < 0); for (i = 0; i < pTab.nCol; i++) { if (aXRef[i] >= 0) { pExpr = sqlite3ExprDup(db, pChanges.a[aXRef[i]].pExpr, 0); } else { pExpr = sqlite3Expr(db, TK_ID, pTab.aCol[i].zName); } pEList = sqlite3ExprListAppend(pParse, pEList, pExpr); } pSelect = sqlite3SelectNew(pParse, pEList, pSrc, pWhere, 0, 0, 0, 0, 0, 0); /* Create the ephemeral table into which the update results will ** be stored. */ Debug.Assert(v); ephemTab = pParse.nTab++; sqlite3VdbeAddOp2(v, OP_OpenEphemeral, ephemTab, pTab.nCol + 1 + (pRowid != 0)); sqlite3VdbeChangeP5(v, BTREE_UNORDERED); /* fill the ephemeral table */ sqlite3SelectDestInit(dest, SRT_Table, ephemTab); sqlite3Select(pParse, pSelect, ref dest); /* Generate code to scan the ephemeral table and call VUpdate. */ iReg = ++pParse.nMem; pParse.nMem += pTab.nCol + 1; addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid 1 : 0), iReg + 1); for (i = 0; i < pTab.nCol; i++) { sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i + 1 + (pRowid != 0), iReg + 2 + i); } sqlite3VtabMakeWritable(pParse, pTab); sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab.nCol + 2, iReg, pVTab, P4_VTAB); sqlite3MayAbort(pParse); sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr + 1); sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); /* Cleanup */ sqlite3SelectDelete(pSelect); }
public static int sqlite3_exec( sqlite3 db, /* The database on which the SQL executes */ string zSql, /* The SQL to be executed */ sqlite3_callback xCallback, /* Invoke this callback routine */ object pArg, /* First argument to xCallback() */ ref string pzErrMsg /* Write error messages here */ ) { int rc = SQLITE_OK; /* Return code */ string zLeftover = ""; /* Tail of unprocessed SQL */ sqlite3_stmt pStmt = null; /* The current SQL statement */ string[] azCols = null; /* Names of result columns */ int nRetry = 0; /* Number of retry attempts */ int callbackIsInit; /* True if callback data is initialized */ if (zSql == null) { zSql = ""; } sqlite3_mutex_enter(db.mutex); sqlite3Error(db, SQLITE_OK, 0); while ((rc == SQLITE_OK || (rc == SQLITE_SCHEMA && (++nRetry) < 2)) && zSql != "") { int nCol; string[] azVals = null; pStmt = null; rc = sqlite3_prepare(db, zSql, -1, ref pStmt, ref zLeftover); Debug.Assert(rc == SQLITE_OK || pStmt == null); if (rc != SQLITE_OK) { continue; } if (pStmt == null) { /* this happens for a comment or white-space */ zSql = zLeftover; continue; } callbackIsInit = 0; nCol = sqlite3_column_count(pStmt); while (true) { int i; rc = sqlite3_step(pStmt); /* Invoke the callback function if required */ if (xCallback != null && (SQLITE_ROW == rc || (SQLITE_DONE == rc && callbackIsInit == 0 && (db.flags & SQLITE_NullCallback) != 0))) { if (0 == callbackIsInit) { azCols = new string[nCol];//sqlite3DbMallocZero(db, 2*nCol*sizeof(const char*) + 1); if (azCols == null) { goto exec_out; } for (i = 0; i < nCol; i++) { azCols[i] = sqlite3_column_name(pStmt, i); /* sqlite3VdbeSetColName() installs column names as UTF8 ** strings so there is no way for sqlite3_column_name() to fail. */ Debug.Assert(azCols[i] != null); } callbackIsInit = 1; } if (rc == SQLITE_ROW) { azVals = new string[nCol];// azCols[nCol]; for (i = 0; i < nCol; i++) { azVals[i] = sqlite3_column_text(pStmt, i); if (azVals[i] == null && sqlite3_column_type(pStmt, i) != SQLITE_NULL) { //// db.mallocFailed = 1; goto exec_out; } } } if (xCallback(pArg, nCol, azVals, azCols) != 0) { rc = SQLITE_ABORT; sqlite3VdbeFinalize(pStmt); pStmt = null; sqlite3Error(db, SQLITE_ABORT, 0); goto exec_out; } } if (rc != SQLITE_ROW) { rc = sqlite3VdbeFinalize(pStmt); pStmt = null; if (rc != SQLITE_SCHEMA) { nRetry = 0; if ((zSql = zLeftover) != "") { int zindex = 0; while (zindex < zSql.Length && sqlite3Isspace(zSql[zindex])) { zindex++; } if (zindex != 0) { zSql = zindex < zSql.Length ? zSql.Substring(zindex) : ""; } } } break; } } //sqlite3DbFree( db, ref azCols ); azCols = null; } exec_out: if (pStmt != null) { sqlite3VdbeFinalize(pStmt); } //sqlite3DbFree( db, ref azCols ); rc = sqlite3ApiExit(db, rc); if (rc != SQLITE_OK && ALWAYS(rc == sqlite3_errcode(db)) && pzErrMsg != null) { //int nErrMsg = 1 + sqlite3Strlen30(sqlite3_errmsg(db)); //pzErrMsg = sqlite3Malloc(nErrMsg); //if (pzErrMsg) //{ // memcpy(pzErrMsg, sqlite3_errmsg(db), nErrMsg); //}else{ //rc = SQLITE_NOMEM; //sqlite3Error(db, SQLITE_NOMEM, 0); //} pzErrMsg = sqlite3_errmsg(db); } else if (pzErrMsg != "") { pzErrMsg = ""; } Debug.Assert((rc & db.errMask) == rc); sqlite3_mutex_leave(db.mutex); return(rc); }
/* ** Query status information for a single database connection */ static public int sqlite3_db_status( sqlite3 db, /* The database connection whose status is desired */ int op, /* Status verb */ ref int pCurrent, /* Write current value here */ ref int pHighwater, /* Write high-water mark here */ int resetFlag /* Reset high-water mark if true */ ) { int rc = SQLITE_OK; /* Return code */ sqlite3_mutex_enter(db.mutex); switch (op) { case SQLITE_DBSTATUS_LOOKASIDE_USED: { pCurrent = db.lookaside.nOut; pHighwater = db.lookaside.mxOut; if (resetFlag != 0) { db.lookaside.mxOut = db.lookaside.nOut; } break; } case SQLITE_DBSTATUS_LOOKASIDE_HIT: case SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE: case SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL: { testcase(op == SQLITE_DBSTATUS_LOOKASIDE_HIT); testcase(op == SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE); testcase(op == SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL); Debug.Assert((op - SQLITE_DBSTATUS_LOOKASIDE_HIT) >= 0); Debug.Assert((op - SQLITE_DBSTATUS_LOOKASIDE_HIT) < 3); pCurrent = 0; pHighwater = db.lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT]; if (resetFlag != 0) { db.lookaside.anStat[op - SQLITE_DBSTATUS_LOOKASIDE_HIT] = 0; } break; } /* ** Return an approximation for the amount of memory currently used ** by all pagers associated with the given database connection. The ** highwater mark is meaningless and is returned as zero. */ case SQLITE_DBSTATUS_CACHE_USED: { int totalUsed = 0; int i; sqlite3BtreeEnterAll(db); for (i = 0; i < db.nDb; i++) { Btree pBt = db.aDb[i].pBt; if (pBt != null) { Pager pPager = sqlite3BtreePager(pBt); totalUsed += sqlite3PagerMemUsed(pPager); } } sqlite3BtreeLeaveAll(db); pCurrent = totalUsed; pHighwater = 0; break; } /* ** *pCurrent gets an accurate estimate of the amount of memory used ** to store the schema for all databases (main, temp, and any ATTACHed ** databases. *pHighwater is set to zero. */ case SQLITE_DBSTATUS_SCHEMA_USED: { int i; /* Used to iterate through schemas */ int nByte = 0; /* Used to accumulate return value */ sqlite3BtreeEnterAll(db); //db.pnBytesFreed = nByte; for (i = 0; i < db.nDb; i++) { Schema pSchema = db.aDb[i].pSchema; if (ALWAYS(pSchema != null)) { HashElem p; //nByte += (int)(sqlite3GlobalConfig.m.xRoundup(sizeof(HashElem)) * ( // pSchema.tblHash.count // + pSchema.trigHash.count // + pSchema.idxHash.count // + pSchema.fkeyHash.count //)); //nByte += (int)sqlite3MallocSize( pSchema.tblHash.ht ); //nByte += (int)sqlite3MallocSize( pSchema.trigHash.ht ); //nByte += (int)sqlite3MallocSize( pSchema.idxHash.ht ); //nByte += (int)sqlite3MallocSize( pSchema.fkeyHash.ht ); for (p = sqliteHashFirst(pSchema.trigHash); p != null; p = sqliteHashNext(p)) { Trigger t = (Trigger)sqliteHashData(p); sqlite3DeleteTrigger(db, ref t); } for (p = sqliteHashFirst(pSchema.tblHash); p != null; p = sqliteHashNext(p)) { Table t = (Table)sqliteHashData(p); sqlite3DeleteTable(db, ref t); } } } db.pnBytesFreed = 0; sqlite3BtreeLeaveAll(db); pHighwater = 0; pCurrent = nByte; break; } /* ** *pCurrent gets an accurate estimate of the amount of memory used ** to store all prepared statements. ** *pHighwater is set to zero. */ case SQLITE_DBSTATUS_STMT_USED: { Vdbe pVdbe; /* Used to iterate through VMs */ int nByte = 0; /* Used to accumulate return value */ //db.pnBytesFreed = nByte; for (pVdbe = db.pVdbe; pVdbe != null; pVdbe = pVdbe.pNext) { sqlite3VdbeDeleteObject(db, ref pVdbe); } db.pnBytesFreed = 0; pHighwater = 0; pCurrent = nByte; break; } default: { rc = SQLITE_ERROR; break; } } sqlite3_mutex_leave(db.mutex); return(rc); }
//#include "sqlite3ext.h" //#include "sqliteInt.h" //#include <string.h> #if !SQLITE_OMIT_LOAD_EXTENSION /* ** Some API routines are omitted when various features are ** excluded from a build of SQLite. Substitute a NULL pointer ** for any missing APIs. */ #if !SQLITE_ENABLE_COLUMN_METADATA //# define sqlite3_column_database_name 0 //# define sqlite3_column_database_name16 0 //# define sqlite3_column_table_name 0 //# define sqlite3_column_table_name16 0 //# define sqlite3_column_origin_name 0 //# define sqlite3_column_origin_name16 0 //# define sqlite3_table_column_metadata 0 #endif #if SQLITE_OMIT_AUTHORIZATION //# define sqlite3_set_authorizer 0 #endif #if SQLITE_OMIT_UTF16 //# define sqlite3_bind_text16 0 //# define sqlite3_collation_needed16 0 //# define sqlite3_column_decltype16 0 //# define sqlite3_column_name16 0 //# define sqlite3_column_text16 0 //# define sqlite3_complete16 0 //# define sqlite3_create_collation16 0 //# define sqlite3_create_function16 0 //# define sqlite3_errmsg16 0 static string sqlite3_errmsg16(sqlite3 db) { return(""); }
public static void wal_checkpoint(this sqlite3 db, string dbName) { int rc = raw.sqlite3_wal_checkpoint(db, dbName); check_ok(rc); }
/* ** An SQL user-function registered to do the work of an ATTACH statement. The ** three arguments to the function come directly from an attach statement: ** ** ATTACH DATABASE x AS y KEY z ** ** SELECT sqlite_attach(x, y, z) ** ** If the optional "KEY z" syntax is omitted, an SQL NULL is passed as the ** third argument. */ static void attachFunc( sqlite3_context context, int NotUsed, sqlite3_value[] argv ) { int i; int rc = 0; sqlite3 db = sqlite3_context_db_handle(context); string zName; string zFile; string zPath = ""; string zErr = ""; int flags; Db aNew = null; string zErrDyn = ""; sqlite3_vfs pVfs = null; UNUSED_PARAMETER(NotUsed); zFile = argv[0].z != null && (argv[0].z.Length > 0) && argv[0].flags != MEM_Null?sqlite3_value_text(argv[0]) : ""; zName = argv[1].z != null && (argv[1].z.Length > 0) && argv[1].flags != MEM_Null?sqlite3_value_text(argv[1]) : ""; //if( zFile==null ) zFile = ""; //if ( zName == null ) zName = ""; /* Check for the following errors: ** ** * Too many attached databases, ** * Transaction currently open ** * Specified database name already being used. */ if (db.nDb >= db.aLimit[SQLITE_LIMIT_ATTACHED] + 2) { zErrDyn = sqlite3MPrintf(db, "too many attached databases - max %d", db.aLimit[SQLITE_LIMIT_ATTACHED] ); goto attach_error; } if (0 == db.autoCommit) { zErrDyn = sqlite3MPrintf(db, "cannot ATTACH database within transaction"); goto attach_error; } for (i = 0; i < db.nDb; i++) { string z = db.aDb[i].zName; Debug.Assert(z != null && zName != null); if (z.Equals(zName, StringComparison.InvariantCultureIgnoreCase)) { zErrDyn = sqlite3MPrintf(db, "database %s is already in use", zName); goto attach_error; } } /* Allocate the new entry in the db.aDb[] array and initialise the schema ** hash tables. */ /* Allocate the new entry in the db.aDb[] array and initialise the schema ** hash tables. */ //if( db.aDb==db.aDbStatic ){ // aNew = sqlite3DbMallocRaw(db, sizeof(db.aDb[0])*3 ); // if( aNew==0 ) return; // memcpy(aNew, db.aDb, sizeof(db.aDb[0])*2); //}else { if (db.aDb.Length <= db.nDb) { Array.Resize(ref db.aDb, db.nDb + 1);//aNew = sqlite3DbRealloc(db, db.aDb, sizeof(db.aDb[0])*(db.nDb+1) ); } if (db.aDb == null) { return; // if( aNew==0 ) return; } //} db.aDb[db.nDb] = new Db(); //db.aDb = aNew; aNew = db.aDb[db.nDb]; //memset(aNew, 0, sizeof(*aNew)); // memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use ** it to obtain the database schema. At this point the schema may ** or may not be initialised. */ flags = (int)db.openFlags; rc = sqlite3ParseUri(db.pVfs.zName, zFile, ref flags, ref pVfs, ref zPath, ref zErr); if (rc != SQLITE_OK) { //if ( rc == SQLITE_NOMEM ) //db.mallocFailed = 1; sqlite3_result_error(context, zErr, -1); //sqlite3_free( zErr ); return; } Debug.Assert(pVfs != null); flags |= SQLITE_OPEN_MAIN_DB; rc = sqlite3BtreeOpen(pVfs, zPath, db, ref aNew.pBt, 0, (int)flags); //sqlite3_free( zPath ); db.nDb++; if (rc == SQLITE_CONSTRAINT) { rc = SQLITE_ERROR; zErrDyn = sqlite3MPrintf(db, "database is already attached"); } else if (rc == SQLITE_OK) { Pager pPager; aNew.pSchema = sqlite3SchemaGet(db, aNew.pBt); //if ( aNew.pSchema == null ) //{ // rc = SQLITE_NOMEM; //} //else if (aNew.pSchema.file_format != 0 && aNew.pSchema.enc != ENC(db)) { zErrDyn = sqlite3MPrintf(db, "attached databases must use the same text encoding as main database"); rc = SQLITE_ERROR; } pPager = sqlite3BtreePager(aNew.pBt); sqlite3PagerLockingMode(pPager, db.dfltLockMode); sqlite3BtreeSecureDelete(aNew.pBt, sqlite3BtreeSecureDelete(db.aDb[0].pBt, -1)); } aNew.safety_level = 3; aNew.zName = zName;//sqlite3DbStrDup(db, zName); //if( rc==SQLITE_OK && aNew.zName==0 ){ // rc = SQLITE_NOMEM; //} #if SQLITE_HAS_CODEC if (rc == SQLITE_OK) { //extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); //extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); int nKey; string zKey; int t = sqlite3_value_type(argv[2]); switch (t) { case SQLITE_INTEGER: case SQLITE_FLOAT: zErrDyn = "Invalid key value"; //sqlite3DbStrDup( db, "Invalid key value" ); rc = SQLITE_ERROR; break; case SQLITE_TEXT: case SQLITE_BLOB: nKey = sqlite3_value_bytes(argv[2]); zKey = sqlite3_value_blob(argv[2]).ToString(); // (char *)sqlite3_value_blob(argv[2]); rc = sqlite3CodecAttach(db, db.nDb - 1, zKey, nKey); break; case SQLITE_NULL: /* No key specified. Use the key from the main database */ sqlite3CodecGetKey(db, 0, out zKey, out nKey); //sqlite3CodecGetKey(db, 0, (void**)&zKey, nKey); if (nKey > 0 || sqlite3BtreeGetReserve(db.aDb[0].pBt) > 0) { rc = sqlite3CodecAttach(db, db.nDb - 1, zKey, nKey); } break; } } #endif /* If the file was opened successfully, read the schema for the new database. ** If this fails, or if opening the file failed, then close the file and ** remove the entry from the db.aDb[] array. i.e. put everything back the way ** we found it. */ if (rc == SQLITE_OK) { sqlite3BtreeEnterAll(db); rc = sqlite3Init(db, ref zErrDyn); sqlite3BtreeLeaveAll(db); } if (rc != 0) { int iDb = db.nDb - 1; Debug.Assert(iDb >= 2); if (db.aDb[iDb].pBt != null) { sqlite3BtreeClose(ref db.aDb[iDb].pBt); db.aDb[iDb].pBt = null; db.aDb[iDb].pSchema = null; } sqlite3ResetInternalSchema(db, -1); db.nDb = iDb; if (rc == SQLITE_NOMEM || rc == SQLITE_IOERR_NOMEM) { //// db.mallocFailed = 1; sqlite3DbFree(db, ref zErrDyn); zErrDyn = sqlite3MPrintf(db, "out of memory"); } else if (zErrDyn == "") { zErrDyn = sqlite3MPrintf(db, "unable to open database: %s", zFile); } goto attach_error; } return; attach_error: /* Return an error if we get here */ if (zErrDyn != "") { sqlite3_result_error(context, zErrDyn, -1); sqlite3DbFree(db, ref zErrDyn); } if (rc != 0) { sqlite3_result_error_code(context, rc); } }
//# define sqlite3BtreeHoldsAllMutexes(X) 1 static bool sqlite3BtreeHoldsAllMutexes(sqlite3 X) { return(true); }
/* ** Locate a user function given a name, a number of arguments and a flag ** indicating whether the function prefers UTF-16 over UTF-8. Return a ** pointer to the FuncDef structure that defines that function, or return ** NULL if the function does not exist. ** ** If the createFlag argument is true, then a new (blank) FuncDef ** structure is created and liked into the "db" structure if a ** no matching function previously existed. When createFlag is true ** and the nArg parameter is -1, then only a function that accepts ** any number of arguments will be returned. ** ** If createFlag is false and nArg is -1, then the first valid ** function found is returned. A function is valid if either xFunc ** or xStep is non-zero. ** ** If createFlag is false, then a function with the required name and ** number of arguments may be returned even if the eTextRep flag does not ** match that requested. */ static FuncDef sqlite3FindFunction( sqlite3 db, /* An open database */ string zName, /* Name of the function. Not null-terminated */ int nName, /* Number of characters in the name */ int nArg, /* Number of arguments. -1 means any number */ u8 enc, /* Preferred text encoding */ u8 createFlag /* Create new entry if true and does not otherwise exist */ ) { FuncDef p; /* Iterator variable */ FuncDef pBest = null; /* Best match found so far */ int bestScore = 0; int h; /* Hash value */ Debug.Assert(enc == SQLITE_UTF8 || enc == SQLITE_UTF16LE || enc == SQLITE_UTF16BE); h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db.aFunc.a); /* First search for a match amongst the application-defined functions. */ p = functionSearch(db.aFunc, h, zName, nName); while (p != null) { int score = matchQuality(p, nArg, enc); if (score > bestScore) { pBest = p; bestScore = score; } p = p.pNext; } /* If no match is found, search the built-in functions. ** ** If the SQLITE_PreferBuiltin flag is set, then search the built-in ** functions even if a prior app-defined function was found. And give ** priority to built-in functions. ** ** Except, if createFlag is true, that means that we are trying to ** install a new function. Whatever FuncDef structure is returned it will ** have fields overwritten with new information appropriate for the ** new function. But the FuncDefs for built-in functions are read-only. ** So we must not search for built-ins when creating a new function. */ if (0 == createFlag && (pBest == null || (db.flags & SQLITE_PreferBuiltin) != 0)) { #if SQLITE_OMIT_WSD FuncDefHash pHash = GLOBAL(FuncDefHash, sqlite3GlobalFunctions); #else FuncDefHash pHash = sqlite3GlobalFunctions; #endif bestScore = 0; p = functionSearch(pHash, h, zName, nName); while (p != null) { int score = matchQuality(p, nArg, enc); if (score > bestScore) { pBest = p; bestScore = score; } p = p.pNext; } } /* If the createFlag parameter is true and the search did not reveal an ** exact match for the name, number of arguments and encoding, then add a ** new entry to the hash table and return it. */ if (createFlag != 0 && (bestScore < 6 || pBest.nArg != nArg) && (pBest = new FuncDef()) != null) { //sqlite3DbMallocZero(db, sizeof(*pBest)+nName+1))!=0 ){ //pBest.zName = (char *)&pBest[1]; pBest.nArg = (i16)nArg; pBest.iPrefEnc = enc; pBest.zName = zName; //memcpy(pBest.zName, zName, nName); //pBest.zName[nName] = 0; sqlite3FuncDefInsert(db.aFunc, pBest); } if (pBest != null && (pBest.xStep != null || pBest.xFunc != null || createFlag != 0)) { return(pBest); } return(null); }
// /* // ** c_realloc_test // */ // static int c_realloc_test( // object clientdata, /* Pointer to sqlite3_enable_XXX function */ // Tcl_Interp interp, /* The TCL interpreter that invoked this command */ // int objc, /* Number of arguments */ // Tcl_Obj[] objv /* Command arguments */ // ) // { // object p; // string zErrFunction = "N/A"; // if ( objc != 1 ) // { // TCL.Tcl_WrongNumArgs( interp, 1, objv, "" ); // return TCL.TCL_ERROR; // } // p = sqlite3Malloc( 5 ); // if ( p == null ) // { // zErrFunction = "sqlite3Malloc"; // goto error_out; // } // /* Test that realloc()ing a block of memory to a negative size is // ** the same as free()ing that memory. // */ // //TODO -- ignore realloc // //p = sqlite3_realloc(p, -1); // //if( p!=null ){ // // zErrFunction = "sqlite3_realloc"; // // goto error_out; // //} // return TCL.TCL_OK; //error_out: // TCL.Tcl_ResetResult( interp ); // TCL.Tcl_AppendResult( interp, "Error testing function: ", zErrFunction ); // return TCL.TCL_ERROR; // } /* ** c_misuse_test */ static int c_misuse_test( object clientdata, /* Pointer to sqlite3_enable_XXX function */ Tcl_Interp interp, /* The TCL interpreter that invoked this command */ int objc, /* Number of arguments */ Tcl_Obj[] objv /* Command arguments */ ) { string zErrFunction = "N/A"; sqlite3 db = null; sqlite3_stmt pStmt; string dummyS = ""; int rc; if (objc != 1) { TCL.Tcl_WrongNumArgs(interp, 1, objv, ""); return(TCL.TCL_ERROR); } /* Open a database. Then close it again. We need to do this so that ** we have a "closed database handle" to pass to various API functions. */ rc = sqlite3_open(":memory:", ref db); if (rc != SQLITE_OK) { zErrFunction = "sqlite3_open"; goto error_out; } sqlite3_close(db); rc = sqlite3_errcode(db); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_errcode"; goto error_out; } pStmt = new sqlite3_stmt(); pStmt.pc = 1234; rc = sqlite3_prepare(db, null, 0, ref pStmt, ref dummyS); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_prepare"; goto error_out; } Debug.Assert(pStmt == null); /* Verify that pStmt is zeroed even on a MISUSE error */ pStmt = new sqlite3_stmt(); pStmt.pc = 1234; rc = sqlite3_prepare_v2(db, null, 0, ref pStmt, ref dummyS); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_prepare_v2"; goto error_out; } Debug.Assert(pStmt == null); #if !SQLITE_OMIT_UTF16 pStmt = (sqlite3_stmt)1234; rc = sqlite3_prepare16(db, null, 0, ref pStmt, ref dummyS); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_prepare16"; goto error_out; } assert(pStmt == 0); pStmt = (sqlite3_stmt)1234; rc = sqlite3_prepare16_v2(db, null, 0, ref pStmt, ref dummyS); if (rc != SQLITE_MISUSE) { zErrFunction = "sqlite3_prepare16_v2"; goto error_out; } assert(pStmt == 0); #endif return(TCL.TCL_OK); error_out: TCL.Tcl_ResetResult(interp); TCL.Tcl_AppendResult(interp, "Error testing function: ", zErrFunction); return(TCL.TCL_ERROR); }
public static void Throw(sqlite3 handle, Result result) => throw new SqlException(result, raw.sqlite3_errmsg(handle) + "\r\n" + raw.sqlite3_errstr(raw.sqlite3_extended_errcode(handle)));
/// <summary> /// This procedure generates VDBE code for a single invocation of either the /// sqlite_detach() or sqlite_attach() SQL user functions. /// </summary> /// <param name='pParse'> /// The parser context /// </param> /// <param name='type'> /// Either SQLITE_ATTACH or SQLITE_DETACH /// </param> /// <param name='pFunc'> /// FuncDef wrapper for detachFunc() or attachFunc() /// </param> /// <param name='pAuthArg'> /// Expression to pass to authorization callback /// </param> /// <param name='pFilename'> /// Name of database file /// </param> /// <param name='pDbname'> /// Name of the database to use internally /// </param> /// <param name='pKey'> /// Database key for encryption extension /// </param> static void codeAttach( Parse pParse, int type, FuncDef pFunc, Expr pAuthArg, Expr pFilename, Expr pDbname, Expr pKey ) { NameContext sName; Vdbe v; sqlite3 db = pParse.db; int regArgs; sName = new NameContext(); // memset( &sName, 0, sizeof(NameContext)); sName.pParse = pParse; if ( SQLITE_OK != (resolveAttachExpr(sName, pFilename)) || SQLITE_OK != (resolveAttachExpr(sName, pDbname)) || SQLITE_OK != (resolveAttachExpr(sName, pKey)) ) { pParse.nErr++; goto attach_end; } #if !SQLITE_OMIT_AUTHORIZATION if (pAuthArg) { char *zAuthArg; if (pAuthArg->op == TK_STRING) { zAuthArg = pAuthArg->u.zToken; } else { zAuthArg = 0; } rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); if (rc != SQLITE_OK) { goto attach_end; } } #endif //* SQLITE_OMIT_AUTHORIZATION */ v = sqlite3GetVdbe(pParse); regArgs = sqlite3GetTempRange(pParse, 4); sqlite3ExprCode(pParse, pFilename, regArgs); sqlite3ExprCode(pParse, pDbname, regArgs + 1); sqlite3ExprCode(pParse, pKey, regArgs + 2); Debug.Assert(v != null /*|| db.mallocFailed != 0 */); if (v != null) { sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs + 3 - pFunc.nArg, regArgs + 3); Debug.Assert(pFunc.nArg == -1 || (pFunc.nArg & 0xff) == pFunc.nArg); sqlite3VdbeChangeP5(v, (u8)(pFunc.nArg)); sqlite3VdbeChangeP4(v, -1, pFunc, P4_FUNCDEF); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). */ sqlite3VdbeAddOp1(v, OP_Expire, (type == SQLITE_ATTACH) ? 1 : 0); } attach_end: sqlite3ExprDelete(db, ref pFilename); sqlite3ExprDelete(db, ref pDbname); sqlite3ExprDelete(db, ref pKey); }
/* ** Create an sqlite3_backup process to copy the contents of zSrcDb from ** connection handle pSrcDb to zDestDb in pDestDb. If successful, return ** a pointer to the new sqlite3_backup object. ** ** If an error occurs, NULL is returned and an error code and error message ** stored in database handle pDestDb. */ static public sqlite3_backup sqlite3_backup_init( sqlite3 pDestDb, /* Database to write to */ string zDestDb, /* Name of database within pDestDb */ sqlite3 pSrcDb, /* Database connection to read from */ string zSrcDb /* Name of database within pSrcDb */ ) { sqlite3_backup p; /* Value to return */ /* Lock the source database handle. The destination database ** handle is not locked in this routine, but it is locked in ** sqlite3_backup_step(). The user is required to ensure that no ** other thread accesses the destination handle for the duration ** of the backup operation. Any attempt to use the destination ** database connection while a backup is in progress may cause ** a malfunction or a deadlock. */ sqlite3_mutex_enter(pSrcDb.mutex); sqlite3_mutex_enter(pDestDb.mutex); if (pSrcDb == pDestDb) { sqlite3Error( pDestDb, SQLITE_ERROR, "source and destination must be distinct" ); p = null; } else { /* Allocate space for a new sqlite3_backup object... ** EVIDENCE-OF: R-64852-21591 The sqlite3_backup object is created by a ** call to sqlite3_backup_init() and is destroyed by a call to ** sqlite3_backup_finish(). */ p = new sqlite3_backup();// (sqlite3_backup)sqlite3_malloc( sizeof( sqlite3_backup ) ); //if ( null == p ) //{ // sqlite3Error( pDestDb, SQLITE_NOMEM, 0 ); //} } /* If the allocation succeeded, populate the new object. */ if (p != null) { // memset( p, 0, sizeof( sqlite3_backup ) ); p.pSrc = findBtree(pDestDb, pSrcDb, zSrcDb); p.pDest = findBtree(pDestDb, pDestDb, zDestDb); p.pDestDb = pDestDb; p.pSrcDb = pSrcDb; p.iNext = 1; p.isAttached = 0; if (null == p.pSrc || null == p.pDest || setDestPgsz(p) == SQLITE_NOMEM) { /* One (or both) of the named databases did not exist or an OOM ** error was hit. The error has already been written into the ** pDestDb handle. All that is left to do here is free the ** sqlite3_backup structure. */ //sqlite3_free( ref p ); p = null; } } if (p != null) { p.pSrc.nBackup++; } sqlite3_mutex_leave(pDestDb.mutex); sqlite3_mutex_leave(pSrcDb.mutex); return(p); }
/// <summary> /// Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" /// command. /// </summary> /// <param name='pParse'> /// Parser context. /// </param> /// <param name='pSrc'> /// The table to rename. /// </param> /// <param name='pName'> /// The new table name. /// </param> static void sqlite3AlterRenameTable( Parse pParse, SrcList pSrc, Token pName ) { int iDb; /* Database that contains the table */ string zDb; /* Name of database iDb */ Table pTab; /* Table being renamed */ string zName = null; /* NULL-terminated version of pName */ sqlite3 db = pParse.db; /* Database connection */ int nTabName; /* Number of UTF-8 characters in zTabName */ string zTabName; /* Original name of the table */ Vdbe v; #if !SQLITE_OMIT_TRIGGER string zWhere = ""; /* Where clause to locate temp triggers */ #endif VTable pVTab = null; /* Non-zero if this is a v-tab with an xRename() */ int savedDbFlags; /* Saved value of db->flags */ savedDbFlags = db.flags; //if ( NEVER( db.mallocFailed != 0 ) ) goto exit_rename_table; Debug.Assert(pSrc.nSrc == 1); Debug.Assert(sqlite3BtreeHoldsAllMutexes(pParse.db)); pTab = sqlite3LocateTable(pParse, 0, pSrc.a[0].zName, pSrc.a[0].zDatabase); if (pTab == null) { goto exit_rename_table; } iDb = sqlite3SchemaToIndex(pParse.db, pTab.pSchema); zDb = db.aDb[iDb].zName; db.flags |= SQLITE_PreferBuiltin; /* Get a NULL terminated version of the new table name. */ zName = sqlite3NameFromToken(db, pName); if (zName == null) { goto exit_rename_table; } /* Check that a table or index named 'zName' does not already exist ** in database iDb. If so, this is an error. */ if (sqlite3FindTable(db, zName, zDb) != null || sqlite3FindIndex(db, zName, zDb) != null) { sqlite3ErrorMsg(pParse, "there is already another table or index with this name: %s", zName); goto exit_rename_table; } /* Make sure it is not a system table being altered, or a reserved name ** that the table is being renamed to. */ if (SQLITE_OK != isSystemTable(pParse, pTab.zName)) { goto exit_rename_table; } if (SQLITE_OK != sqlite3CheckObjectName(pParse, zName)) { goto exit_rename_table; } #if !SQLITE_OMIT_VIEW if (pTab.pSelect != null) { sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab.zName); goto exit_rename_table; } #endif #if !SQLITE_OMIT_AUTHORIZATION /* Invoke the authorization callback. */ if (sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab.zName, 0)) { goto exit_rename_table; } #endif if (sqlite3ViewGetColumnNames(pParse, pTab) != 0) { goto exit_rename_table; } #if !SQLITE_OMIT_VIRTUALTABLE if (IsVirtual(pTab)) { pVTab = sqlite3GetVTable(db, pTab); if (pVTab.pVtab.pModule.xRename == null) { pVTab = null; } } #endif /* Begin a transaction and code the VerifyCookie for database iDb. ** Then modify the schema cookie (since the ALTER TABLE modifies the ** schema). Open a statement transaction if the table is a virtual ** table. */ v = sqlite3GetVdbe(pParse); if (v == null) { goto exit_rename_table; } sqlite3BeginWriteOperation(pParse, pVTab != null ? 1 : 0, iDb); sqlite3ChangeCookie(pParse, iDb); /* If this is a virtual table, invoke the xRename() function if ** one is defined. The xRename() callback will modify the names ** of any resources used by the v-table implementation (including other ** SQLite tables) that are identified by the name of the virtual table. */ #if !SQLITE_OMIT_VIRTUALTABLE if (pVTab != null) { int i = ++pParse.nMem; sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0); sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0, pVTab, P4_VTAB); sqlite3MayAbort(pParse); } #endif /* figure out how many UTF-8 characters are in zName */ zTabName = pTab.zName; nTabName = sqlite3Utf8CharLen(zTabName, -1); #if !(SQLITE_OMIT_FOREIGN_KEY) && !(SQLITE_OMIT_TRIGGER) if ((db.flags & SQLITE_ForeignKeys) != 0) { /* If foreign-key support is enabled, rewrite the CREATE TABLE ** statements corresponding to all child tables of foreign key constraints ** for which the renamed table is the parent table. */ if ((zWhere = whereForeignKeys(pParse, pTab)) != null) { sqlite3NestedParse(pParse, "UPDATE \"%w\".%s SET " + "sql = sqlite_rename_parent(sql, %Q, %Q) " + "WHERE %s;", zDb, SCHEMA_TABLE(iDb), zTabName, zName, zWhere); sqlite3DbFree(db, ref zWhere); } } #endif /* Modify the sqlite_master table to use the new table name. */ sqlite3NestedParse(pParse, "UPDATE %Q.%s SET " + #if SQLITE_OMIT_TRIGGER "sql = sqlite_rename_table(sql, %Q), " + #else "sql = CASE " + "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" + "ELSE sqlite_rename_table(sql, %Q) END, " + #endif "tbl_name = %Q, " + "name = CASE " + "WHEN type='table' THEN %Q " + "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " + "'sqlite_autoindex_' || %Q || substr(name,%d+18) " + "ELSE name END " + "WHERE tbl_name=%Q AND " + "(type='table' OR type='index' OR type='trigger');", zDb, SCHEMA_TABLE(iDb), zName, zName, zName, #if !SQLITE_OMIT_TRIGGER zName, #endif zName, nTabName, zTabName ); #if !SQLITE_OMIT_AUTOINCREMENT /* If the sqlite_sequence table exists in this database, then update ** it with the new table name. */ if (sqlite3FindTable(db, "sqlite_sequence", zDb) != null) { sqlite3NestedParse(pParse, "UPDATE \"%w\".sqlite_sequence set name = %Q WHERE name = %Q", zDb, zName, pTab.zName ); } #endif #if !SQLITE_OMIT_TRIGGER /* If there are TEMP triggers on this table, modify the sqlite_temp_master ** table. Don't do this if the table being ALTERed is itself located in ** the temp database. */ if ((zWhere = whereTempTriggers(pParse, pTab)) != "") { sqlite3NestedParse(pParse, "UPDATE sqlite_temp_master SET " + "sql = sqlite_rename_trigger(sql, %Q), " + "tbl_name = %Q " + "WHERE %s;", zName, zName, zWhere); sqlite3DbFree(db, ref zWhere); } #endif #if !(SQLITE_OMIT_FOREIGN_KEY) && !(SQLITE_OMIT_TRIGGER) if ((db.flags & SQLITE_ForeignKeys) != 0) { FKey p; for (p = sqlite3FkReferences(pTab); p != null; p = p.pNextTo) { Table pFrom = p.pFrom; if (pFrom != pTab) { reloadTableSchema(pParse, p.pFrom, pFrom.zName); } } } #endif /* Drop and reload the internal table schema. */ reloadTableSchema(pParse, pTab, zName); exit_rename_table: sqlite3SrcListDelete(db, ref pSrc); sqlite3DbFree(db, ref zName); db.flags = savedDbFlags; }
/* ** This procedure generates VDBE code for a single invocation of either the ** sqlite_detach() or sqlite_attach() SQL user functions. */ static void codeAttach( Parse pParse, /* The parser context */ int type, /* Either SQLITE_ATTACH or SQLITE_DETACH */ FuncDef pFunc, /* FuncDef wrapper for detachFunc() or attachFunc() */ Expr pAuthArg, /* Expression to pass to authorization callback */ Expr pFilename, /* Name of database file */ Expr pDbname, /* Name of the database to use internally */ Expr pKey /* Database key for encryption extension */ ) { int rc; NameContext sName; Vdbe v; sqlite3 db = pParse.db; int regArgs; sName = new NameContext();// memset( &sName, 0, sizeof(NameContext)); sName.pParse = pParse; if ( SQLITE_OK != (rc = resolveAttachExpr(sName, pFilename)) || SQLITE_OK != (rc = resolveAttachExpr(sName, pDbname)) || SQLITE_OK != (rc = resolveAttachExpr(sName, pKey)) ) { pParse.nErr++; goto attach_end; } #if !SQLITE_OMIT_AUTHORIZATION if (pAuthArg) { char *zAuthArg; if (pAuthArg->op == TK_STRING) { zAuthArg = pAuthArg->u.zToken; } else { zAuthArg = 0; } rc = sqlite3AuthCheck(pParse, type, zAuthArg, 0, 0); if (rc != SQLITE_OK) { goto attach_end; } } #endif //* SQLITE_OMIT_AUTHORIZATION */ v = sqlite3GetVdbe(pParse); regArgs = sqlite3GetTempRange(pParse, 4); sqlite3ExprCode(pParse, pFilename, regArgs); sqlite3ExprCode(pParse, pDbname, regArgs + 1); sqlite3ExprCode(pParse, pKey, regArgs + 2); Debug.Assert(v != null /*|| db.mallocFailed != 0 */); if (v != null) { sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs + 3 - pFunc.nArg, regArgs + 3); Debug.Assert(pFunc.nArg == -1 || (pFunc.nArg & 0xff) == pFunc.nArg); sqlite3VdbeChangeP5(v, (u8)(pFunc.nArg)); sqlite3VdbeChangeP4(v, -1, pFunc, P4_FUNCDEF); /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this ** statement only). For DETACH, set it to false (expire all existing ** statements). */ sqlite3VdbeAddOp1(v, OP_Expire, (type == SQLITE_ATTACH) ? 1 : 0); } attach_end: sqlite3ExprDelete(db, ref pFilename); sqlite3ExprDelete(db, ref pDbname); sqlite3ExprDelete(db, ref pKey); }