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); }
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; }
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; }
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; }