public static void Compact(InMemoryRavenConfiguration ravenConfiguration, JET_PFNSTATUS statusCallback) { var src = Path.Combine(ravenConfiguration.DataDirectory, "Data"); var compactPath = Path.Combine(ravenConfiguration.DataDirectory, "Data.Compact"); if (File.Exists(compactPath)) { File.Delete(compactPath); } RecoverFromFailedCompact(src); JET_INSTANCE compactInstance; CreateInstance(out compactInstance, ravenConfiguration.DataDirectory + Guid.NewGuid()); try { new TransactionalStorageConfigurator(ravenConfiguration, null) .ConfigureInstance(compactInstance, ravenConfiguration.DataDirectory); DisableIndexChecking(compactInstance); Api.JetInit(ref compactInstance); using (var session = new Session(compactInstance)) { Api.JetAttachDatabase(session, src, AttachDatabaseGrbit.None); try { Api.JetCompact(session, src, compactPath, statusCallback, null, CompactGrbit.None); } finally { Api.JetDetachDatabase(session, src); } } } finally { Api.JetTerm2(compactInstance, TermGrbit.Complete); } File.Move(src, src + ".RenameOp"); File.Move(compactPath, src); File.Delete(src + ".RenameOp"); }
public static void Compact(InMemoryRavenConfiguration ravenConfiguration, JET_PFNSTATUS statusCallback) { bool lockTaken = false; try { Monitor.TryEnter(compactLocker, 30 * 1000, ref lockTaken); if (lockTaken == false) { throw new TimeoutException("Could not take Esent Compact Lock. Because of a probable bug in Esent, we only allow a single database to be compacted at a given time.\r\n" + "However, we waited for 30 seconds for the compact lock to be released, and gave up. The database wasn't compacted, please try again later, when the other compaction process is over."); } CompactInternal(ravenConfiguration, statusCallback); } finally { if (lockTaken) { Monitor.Exit(compactLocker); } } }
public void VerifyJetRstinfoEquality() { DateTime now = DateTime.Now; JET_PFNSTATUS status = (sesid, snp, snt, data) => JET_err.Success; var x = new JET_RSTINFO { crstmap = 1, lgposStop = new JET_LGPOS { ib = 1, isec = 2, lGeneration = 3 }, logtimeStop = new JET_LOGTIME(now), pfnStatus = status, rgrstmap = new[] { new JET_RSTMAP { szDatabaseName = "foo", szNewDatabaseName = "bar" } }, }; var y = new JET_RSTINFO { crstmap = 1, lgposStop = new JET_LGPOS { ib = 1, isec = 2, lGeneration = 3 }, logtimeStop = new JET_LOGTIME(now), pfnStatus = status, rgrstmap = new[] { new JET_RSTMAP { szDatabaseName = "foo", szNewDatabaseName = "bar" }, new JET_RSTMAP { szDatabaseName = "foo", szNewDatabaseName = "bar" } }, }; TestContentEquals(x, y); }
public void VerifyJetRstinfoInequality() { DateTime now = DateTime.Now; JET_PFNSTATUS status = (sesid, snp, snt, data) => JET_err.Success; var values = new JET_RSTINFO[7]; for (int i = 0; i < values.Length; ++i) { values[i] = new JET_RSTINFO { crstmap = 1, lgposStop = new JET_LGPOS { ib = 1, isec = 2, lGeneration = 3 }, logtimeStop = new JET_LOGTIME(now), pfnStatus = status, rgrstmap = new[] { new JET_RSTMAP { szDatabaseName = "foo", szNewDatabaseName = "bar" } }, }; } int j = 1; values[j++].crstmap--; values[j++].lgposStop = Any.Lgpos; values[j++].logtimeStop = Any.Logtime; values[j++].pfnStatus = (sesid, snp, snt, data) => JET_err.OutOfMemory; values[j++].rgrstmap = new[] { new JET_RSTMAP { szDatabaseName = "foo", szNewDatabaseName = "baz" } }; values[j++] = new JET_RSTINFO(); Debug.Assert(j == values.Length, "Didn't fill in all entries of values", values.Length.ToString()); VerifyAll(values); }
private static void CompactInternal(InMemoryRavenConfiguration ravenConfiguration, JET_PFNSTATUS statusCallback) { var src = Path.Combine(ravenConfiguration.DataDirectory, "Data"); var compactPath = Path.Combine(ravenConfiguration.DataDirectory, "Data.Compact"); if (File.Exists(compactPath)) File.Delete(compactPath); RecoverFromFailedCompact(src); JET_INSTANCE compactInstance; CreateInstance(out compactInstance, ravenConfiguration.DataDirectory + Guid.NewGuid()); try { new TransactionalStorageConfigurator(ravenConfiguration, null) .ConfigureInstance(compactInstance, ravenConfiguration.DataDirectory); DisableIndexChecking(compactInstance); Api.JetInit(ref compactInstance); using (var session = new Session(compactInstance)) { Api.JetAttachDatabase(session, src, AttachDatabaseGrbit.None); try { Api.JetCompact(session, src, compactPath, statusCallback, null, CompactGrbit.None); } finally { Api.JetDetachDatabase(session, src); } } } finally { Api.JetTerm2(compactInstance, TermGrbit.Complete); } File.Move(src, src + ".RenameOp"); File.Move(compactPath, src); File.Delete(src + ".RenameOp"); }
public static void Compact(InMemoryRavenConfiguration ravenConfiguration, JET_PFNSTATUS statusCallback) { bool lockTaken = false; try { Monitor.TryEnter(compactLocker, 30 * 1000, ref lockTaken); if (lockTaken == false) { throw new TimeoutException("Could not take Esent Compact Lock. Because of a probable bug in Esent, we only allow a single database to be compacted at a given time.\r\n" + "However, we waited for 30 seconds for the compact lock to be released, and gave up. The database wasn't compacted, please try again later, when the other compaction process is over."); } CompactInternal(ravenConfiguration, statusCallback); } finally { if (lockTaken) Monitor.Exit(compactLocker); } }
/// <summary> /// Initializes a new instance of the StatusCallbackWrapper class. /// </summary> /// <param name="wrappedCallback"> /// The managed callback to use. /// </param> public StatusCallbackWrapper(JET_PFNSTATUS wrappedCallback) { this.wrappedCallback = wrappedCallback; this.nativeCallback = wrappedCallback != null ? this.CallbackImpl : (NATIVE_PFNSTATUS)null; }
/// <summary> /// Initializes a new instance of the StatusCallbackWrapper class. /// </summary> /// <param name="wrappedCallback"> /// The managed callback to use. /// </param> public StatusCallbackWrapper(JET_PFNSTATUS wrappedCallback) { this.wrappedCallback = wrappedCallback; this.nativeCallback = this.CallbackImpl; }
/// <summary> /// Performs a streaming backup of an instance, including all the attached /// databases, to a directory. With multiple backup methods supported by /// the engine, this is the simplest and most encapsulated function. /// </summary> /// <param name="instance">The instance to backup.</param> /// <param name="destination"> /// The directory where the backup is to be stored. If the backup path is /// null to use the function will truncate the logs, if possible. /// </param> /// <param name="grbit">Backup options.</param> /// <param name="statusCallback"> /// Optional status notification callback. /// </param> public static void JetBackupInstance(JET_INSTANCE instance, string destination, BackupGrbit grbit, JET_PFNSTATUS statusCallback) { Api.Check(Impl.JetBackupInstance(instance, destination, grbit, statusCallback)); }
/// <summary> /// Restores and recovers a streaming backup of an instance including all /// the attached databases. It is designed to work with a backup created /// with the <see cref="Api.JetBackupInstance"/> function. This is the /// simplest and most encapsulated restore function. /// </summary> /// <param name="instance"> /// The instance to use. The instance should not be initialized. /// Restoring the files will initialize the instance. /// </param> /// <param name="source"> /// Location of the backup. The backup should have been created with /// <see cref="Api.JetBackupInstance"/>. /// </param> /// <param name="destination"> /// Name of the folder where the database files from the backup set will /// be copied and recovered. If this is set to null, the database files /// will be copied and recovered to their original location. /// </param> /// <param name="statusCallback"> /// Optional status notification callback. /// </param> public static void JetRestoreInstance(JET_INSTANCE instance, string source, string destination, JET_PFNSTATUS statusCallback) { Api.Check(Impl.JetRestoreInstance(instance, source, destination, statusCallback)); }
#pragma warning disable 618,612 // Disable warning that JET_CONVERT is obsolete /// <summary> /// Makes a copy of an existing database. The copy is compacted to a /// state optimal for usage. Data in the copied data will be packed /// according to the measures chosen for the indexes at index create. /// In this way, compacted data may be stored as densely as possible. /// Alternatively, compacted data may reserve space for subsequent /// record growth or index insertions. /// </summary> /// <param name="sesid">The session to use for the call.</param> /// <param name="sourceDatabase">The source database that will be compacted.</param> /// <param name="destinationDatabase">The name to use for the compacted database.</param> /// <param name="statusCallback"> /// A callback function that can be called periodically through the /// database compact operation to report progress. /// </param> /// <param name="ignored"> /// This parameter is ignored and should be null. /// </param> /// <param name="grbit">Compact options.</param> public static void JetCompact( JET_SESID sesid, string sourceDatabase, string destinationDatabase, JET_PFNSTATUS statusCallback, JET_CONVERT ignored, CompactGrbit grbit) { Api.Check( Impl.JetCompact(sesid, sourceDatabase, destinationDatabase, statusCallback, ignored, grbit)); }
/// <summary> /// Initializes a new instance of the StatusCallbackWrapper class. /// </summary> /// <param name="wrappedCallback"> /// The managed callback to use. /// </param> public StatusCallbackWrapper(JET_PFNSTATUS wrappedCallback) { this.wrappedCallback = wrappedCallback; }