示例#1
0
 /*
 ** 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;
 }
示例#2
0
 /*
 ** 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;
 }
示例#3
0
 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 */
     );
示例#4
0
 // 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;
 }
示例#5
0
        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;
        }
示例#6
0
 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 */
     );
示例#7
0
        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;
        }
示例#8
0
 /*
 ** 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;
     }
 }
示例#9
0
    /*
** 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 );
    }
示例#10
0
        /*
        ** 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));
     }
 }
示例#12
0
 // 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);
 }
示例#13
0
 //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 );
 }
示例#14
0
    /*
    ** 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;
 }
示例#16
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 */
示例#17
0
 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 );
 }
示例#18
0
    /*
    ** 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 );
    }
示例#19
0
 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;
 }
示例#20
0
    /*
    **
    ** 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 );
      }
    }
示例#21
0
 // 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;
 }
示例#22
0
    /*
** 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;
 }
示例#24
0
        /*
        ** 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;
        }
示例#25
0
/*
** 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 );
}
}
}
示例#26
0
 /*
 ** 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;
 }
示例#27
0
 // 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;
}
示例#29
0
    /*
    ** 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;
    }
示例#30
0
 // 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;
 }
示例#31
0
        /*
        ** 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),
示例#32
0
 //# define sqlite3BtreeLeaveAll(X)
 static void sqlite3BtreeLeaveAll(sqlite3 X)
 {
 }
示例#33
0
        /*
        ** 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);
        }
示例#34
0
 private SqlConnection(IPersistentStorageFaultInjector faultInjector, sqlite3 handle)
 {
     _faultInjector = faultInjector;
     _handle        = handle;
 }
示例#35
0
        /// <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);
            }
        }
示例#36
0
 //# define sqlite3BtreeEnterAll(X)
 static void sqlite3BtreeEnterAll(sqlite3 p)
 {
 }
示例#37
0
        /// <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;
        }
示例#38
0
        public static void rekey(this sqlite3 db, ReadOnlySpan <byte> k)
        {
            int rc = raw.sqlite3_rekey(db, k);

            check_ok(rc);
        }
示例#39
0
        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);
        }
示例#40
0
        //# 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)
        {
        }
示例#41
0
 //# 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);
        }
示例#43
0
        /*
        ** 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);
        }
示例#44
0
文件: _Custom.cs 项目: da-ka/Vocaluxe
 static sqlite3 va_arg(object[] ap, sqlite3 sysType)
 {
     return((sqlite3)ap[vaNEXT++]);
 }
示例#45
0
        /*
        ** 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)
            {
示例#46
0
        public static void wal_autocheckpoint(this sqlite3 db, int n)
        {
            int rc = raw.sqlite3_wal_autocheckpoint(db, n);

            check_ok(rc);
        }
示例#47
0
        /* 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);
        }
示例#48
0
        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);
        }
示例#49
0
        /*
        ** 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);
        }
示例#50
0
        //#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("");
        }
示例#51
0
        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);
            }
        }
示例#53
0
 //# define sqlite3BtreeHoldsAllMutexes(X) 1
 static bool sqlite3BtreeHoldsAllMutexes(sqlite3 X)
 {
     return(true);
 }
示例#54
0
        /*
        ** 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);
        }
示例#55
0
//    /*
//    ** 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);
        }
示例#56
0
 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)));
示例#57
0
        /// <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);
        }
示例#58
0
        /*
        ** 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);
        }
示例#59
0
        /// <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);
        }