Example #1
0
        public static RC Config(Context ctx, VTABLECONFIG op, object arg1)
        {
            RC rc = RC.OK;

            MutexEx.Enter(ctx.Mutex);
            switch (op)
            {
            case VTABLECONFIG.CONSTRAINT:
            {
                VTableContext p = ctx.VTableCtx;
                if (p == null)
                {
                    rc = SysEx.MISUSE_BKPT();
                }
                else
                {
                    Debug.Assert(p.Table == null || (p.Table.TabFlags & TF.Virtual) != 0);
                    p.VTable.Constraint = (bool)arg1;
                }
                break;
            }

            default:
                rc = SysEx.MISUSE_BKPT();
                break;
            }
            if (rc != RC.OK)
            {
                DataEx.Error(ctx, rc, null);
            }
            MutexEx.Leave(ctx.Mutex);
            return(rc);
        }
Example #2
0
        public Backup Next;             // Next backup associated with source pager

        static Btree FindBtree(Context errorCtx, Context ctx, string dbName)
        {
            int i = Parse.FindDbName(ctx, dbName);
            if (i == 1)
            {
                RC rc = 0;
                Parse parse = new Parse();
                if (parse == null)
                {
                    DataEx.Error(errorCtx, RC.NOMEM, "out of memory");
                    rc = RC.NOMEM;
                }
                else
                {
                    parse.Ctx = ctx;
                    if (parse.OpenTempDatabase() != 0)
                    {
                        DataEx.Error(errorCtx, parse.RC, "%s", parse.ErrMsg);
                        rc = RC.ERROR;
                    }
                    C._tagfree(errorCtx, ref parse.ErrMsg);
                }
                if (rc != 0)
                    return null;
            }

            if (i < 0)
            {
                DataEx.Error(errorCtx, RC.ERROR, "unknown database %s", dbName);
                return null;
            }
            return ctx.DBs[i].Bt;
        }
Example #3
0
        public static Backup Init(Context destCtx, string destDbName, Context srcCtx, string srcDbName)
        {
            // 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.
            MutexEx.Enter(srcCtx.Mutex);
            MutexEx.Enter(destCtx.Mutex);

            Backup p;
            if (srcCtx == destCtx)
            {
                DataEx.Error(destCtx, RC.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 Backup();
                if (p == null)
                    DataEx.Error(destCtx, RC.NOMEM, null);
            }

            // If the allocation succeeded, populate the new object.
            if (p != null)
            {
                p.Src = FindBtree(destCtx, srcCtx, srcDbName);
                p.Dest = FindBtree(destCtx, destCtx, destDbName);
                p.DestCtx = destCtx;
                p.SrcCtx = srcCtx;
                p.NextId = 1;
                p.IsAttached = false;

                if (p.Src == null || p.Dest == null || SetDestPgsz(p) == RC.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.
                    //C._free(ref p);
                    p = null;
                }
            }
            if (p != null)
                p.Src.Backups++;

            MutexEx.Leave(destCtx.Mutex);
            MutexEx.Leave(srcCtx.Mutex);
            return p;
        }
Example #4
0
        public static RC Finish(Backup p)
        {
            // Enter the mutexes 
            if (p == null) return RC.OK;
            Context srcCtx = p.SrcCtx; // Source database connection
            MutexEx.Enter(srcCtx.Mutex);
            p.Src.Enter();
            if (p.DestCtx != null)
                MutexEx.Enter(p.DestCtx.Mutex);

            // Detach this backup from the source pager.
            if (p.DestCtx != null)
                p.Src.Backups--;
            if (p.IsAttached)
            {
                Backup pp = (Backup)p.Src.get_Pager().Backup;
                while (pp != p)
                    pp = (pp).Next;
                p.Src.get_Pager().Backup = p.Next;
            }

            // If a transaction is still open on the Btree, roll it back.
            p.Dest.Rollback(RC.OK);

            // Set the error code of the destination database handle.
            RC rc = (p.RC_ == RC.DONE ? RC.OK : p.RC_);
            DataEx.Error(p.DestCtx, rc, null);

            // Exit the mutexes and free the backup context structure.
            if (p.DestCtx != null)
                DataEx.LeaveMutexAndCloseZombie(p.DestCtx.Mutex);
            p.Src.Leave();
            //// 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().
            //if (p.DestCtx != null)
            //    C._free(ref p);
            DataEx.LeaveMutexAndCloseZombie(mutex);
            return rc;
        }