private void InitializeDatabase() { string connectionString = ConnectionString; Debug.AssertStringNotEmpty(connectionString); string dbFilePath = ConnectionStringHelper.GetDataSourceFilePath(connectionString); if (File.Exists(dbFilePath)) { return; } using (SqlCeEngine engine = new SqlCeEngine(ConnectionString)) { engine.CreateDatabase(); } using (SqlCeConnection conn = new SqlCeConnection(ConnectionString)) { using (SqlCeCommand cmd = new SqlCeCommand()) { conn.Open(); SqlCeTransaction transaction = conn.BeginTransaction(); try { cmd.Connection = conn; cmd.Transaction = transaction; cmd.CommandText = @" SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = N'ELMAH_Error'"; object obj = cmd.ExecuteScalar(); if (obj == null) { cmd.CommandText = @" CREATE TABLE ELMAH_Error ( [ErrorId] UNIQUEIDENTIFIER NOT NULL PRIMARY KEY DEFAULT newid(), [Application] NVARCHAR(60) NOT NULL, [Host] NVARCHAR(50) NOT NULL, [Type] NVARCHAR(100) NOT NULL, [Source] NVARCHAR(60) NOT NULL, [Message] NVARCHAR(500) NOT NULL, [User] NVARCHAR(50) NOT NULL, [StatusCode] INT NOT NULL, [TimeUtc] DATETIME NOT NULL, [Sequence] INT IDENTITY (1, 1) NOT NULL, [AllXml] NTEXT NOT NULL )"; cmd.ExecuteNonQuery(); cmd.CommandText = @" CREATE NONCLUSTERED INDEX [IX_Error_App_Time_Seq] ON [ELMAH_Error] ( [Application] ASC, [TimeUtc] DESC, [Sequence] DESC )"; cmd.ExecuteNonQuery(); } transaction.Commit(CommitMode.Immediate); } catch (SqlCeException) { transaction.Rollback(); throw; } } } }
private void InitializeDatabase() { string connectionString = ConnectionString; Debug.AssertStringNotEmpty(connectionString); string dbFilePath = ConnectionStringHelper.GetDataSourceFilePath(connectionString); if (File.Exists(dbFilePath)) { return; } // // Make sure that we don't have multiple instances trying to create the database. // lock (_mdbInitializationLock) { // // Just double-check that no other thread has created the database while // we were waiting for the lock. // if (File.Exists(dbFilePath)) { return; } // // Create a temporary copy of the mkmdb.vbs script. // We do this in the same directory as the resulting database for security permission purposes. // string scriptPath = Path.Combine(Path.GetDirectoryName(dbFilePath), _scriptResourceName); using (FileStream scriptStream = new FileStream(scriptPath, FileMode.Create, FileAccess.Write, FileShare.None)) { ManifestResourceHelper.WriteResourceToStream(scriptStream, _scriptResourceName); } // // Run the script file to create the database using batch // mode (//B), which suppresses script errors and prompts // from displaying. // ProcessStartInfo psi = new ProcessStartInfo( "cscript", scriptPath + " \"" + dbFilePath + "\" //B //NoLogo"); psi.UseShellExecute = false; // i.e. CreateProcess psi.CreateNoWindow = true; // Stay lean, stay mean try { using (Process process = Process.Start(psi)) { // // A few seconds should be plenty of time to create the database. // TimeSpan tolerance = TimeSpan.FromSeconds(2); if (!process.WaitForExit((int)tolerance.TotalMilliseconds)) { // // but it wasn't, so clean up and throw an exception! // Realistically, I don't expect to ever get here! // process.Kill(); throw new Exception(string.Format( "The Microsoft Access database creation script took longer than the allocated time of {0} seconds to execute. " + "The script was terminated prematurely.", tolerance.TotalSeconds)); } if (process.ExitCode != 0) { throw new Exception(string.Format( "The Microsoft Access database creation script failed with exit code {0}.", process.ExitCode)); } } } finally { // // Clean up after ourselves!! // File.Delete(scriptPath); } } }