public IEphemeralDatabase RegisterDatabase(string name, IEphemeralDatabaseInitializer initializer = null)
        {
            if (_databases.IsReadOnly)
            {
                throw new InvalidOperationException("cannot add database after configuration has been frozen");
            }
            var db = new EphemeralDatabaseRegistration(name, initializer);

            _databases.Add(db);
            return(db.CompletionSource);
        }
Beispiel #2
0
        public void CreateDatabase(EphemeralDatabaseRegistration db)
        {
            using (var conn = new SqlConnection(Configuration.Server))
            {
                conn.Open();

                var privateDataDir = GetPrivateDataDir();

                var catalogName  = GetDatabaseCatalogName(db.Name);
                var fileName     = GetDatabaseFileName(catalogName);
                var dataFileName = Path.ChangeExtension(Path.Combine(privateDataDir, fileName), "mdf");
                var logFileName  = Path.ChangeExtension(Path.Combine(privateDataDir, fileName), "log");

                var cmd = new SqlCommand {
                    Connection = conn
                };
                cmd.CommandText = $@"create database [{SqlHelper.Escape(catalogName, ']')}]
on (
    name = [{SqlHelper.Escape(fileName, ']')}_data],
    filename = '{SqlHelper.Escape(dataFileName, '\'')}',
    size = 50,
    maxsize = 1000,
    filegrowth = 25
)
log on (
    name = [{SqlHelper.Escape(fileName, ']')}_log],
    filename = '{SqlHelper.Escape(logFileName, '\'')}',
    size = 25,
    maxsize = 500,
    filegrowth = 25
)
;
";
                cmd.ExecuteNonQuery();

                conn.ChangeDatabase(catalogName);

                // tag database as "ephemeral",
                // if an ephemeral database is left in a open state
                // we will atempt to delete it, assuming that we can decrypt
                // the "ephemeral" property, if we can't, well the database
                // must have been created some other way and we won't touch it.
                var cmd2 = new SqlCommand {
                    Connection = conn
                };
                cmd2.CommandType = System.Data.CommandType.StoredProcedure;
                cmd2.CommandText = "sp_addextendedproperty";
                cmd2.Parameters.AddWithValue("@name", _tag);
                cmd2.Parameters.AddWithValue("@value", Encrypt(privateDataDir));
                cmd2.ExecuteNonQuery();

                conn.Close(); // disconnect while initializer is running

                var cb = new SqlConnectionStringBuilder(Configuration.Server);
                cb.InitialCatalog = catalogName;
                var connStr = cb.ToString();
                db.CompletionSource.ConnectionString.SetResult(connStr);

                var initializer = db.Initializer;
                if (initializer != null)
                {
                    using (var context = new EphemeralDatabaseContext(db.CompletionSource))
                    {
                        initializer.Initialize(context);
                    }
                }
            }
        }