/// <summary>
        /// Initializes the database by creating the umbraco db schema.
        /// </summary>
        /// <remarks>This needs to execute as part of a transaction.</remarks>
        public void InitializeDatabaseSchema()
        {
            if (!_database.InTransaction)
            {
                throw new InvalidOperationException("Database is not in a transaction.");
            }

            var e = new DatabaseCreationEventArgs();

            FireBeforeCreation(e);

            if (e.Cancel == false)
            {
                var dataCreation = new DatabaseDataCreator(_database, _logger);
                foreach (var table in OrderedTables)
                {
                    CreateTable(false, table, dataCreation);
                }
            }

            FireAfterCreation(e);
        }
        /// <summary>
        /// Creates a new table in the database for the specified <paramref name="modelType"/>.
        /// </summary>
        /// <param name="overwrite">Whether the table should be overwritten if it already exists.</param>
        /// <param name="modelType">The representing the table.</param>
        /// <param name="dataCreation"></param>
        /// <remarks>
        /// If <paramref name="modelType"/> has been decorated with an <see cref="TableNameAttribute"/>, the name from
        /// that  attribute will be used for the table name. If the attribute is not present, the name
        /// <paramref name="modelType"/> will be used instead.
        ///
        /// If a table with the same name already exists, the <paramref name="overwrite"/> parameter will determine
        /// whether the table is overwritten. If <c>true</c>, the table will be overwritten, whereas this method will
        /// not do anything if the parameter is <c>false</c>.
        ///
        /// This need to execute as part of a transaction.
        /// </remarks>
        internal void CreateTable(bool overwrite, Type modelType, DatabaseDataCreator dataCreation)
        {
            if (!_database.InTransaction)
            {
                throw new InvalidOperationException("Database is not in a transaction.");
            }

            var tableDefinition = DefinitionFactory.GetTableDefinition(modelType, SqlSyntax);
            var tableName       = tableDefinition.Name;

            var createSql           = SqlSyntax.Format(tableDefinition);
            var createPrimaryKeySql = SqlSyntax.FormatPrimaryKey(tableDefinition);
            var foreignSql          = SqlSyntax.Format(tableDefinition.ForeignKeys);
            var indexSql            = SqlSyntax.Format(tableDefinition.Indexes);

            var tableExist = TableExists(tableName);

            if (overwrite && tableExist)
            {
                _logger.Info <DatabaseSchemaCreator>("Table {TableName} already exists, but will be recreated", tableName);

                DropTable(tableName);
                tableExist = false;
            }

            if (tableExist)
            {
                // The table exists and was not recreated/overwritten.
                _logger.Info <Database>("Table {TableName} already exists - no changes were made", tableName);
                return;
            }

            //Execute the Create Table sql
            _database.Execute(new Sql(createSql));
            _logger.Info <DatabaseSchemaCreator>("Create Table {TableName}: \n {Sql}", tableName, createSql);

            //If any statements exists for the primary key execute them here
            if (string.IsNullOrEmpty(createPrimaryKeySql) == false)
            {
                _database.Execute(new Sql(createPrimaryKeySql));
                _logger.Info <DatabaseSchemaCreator>("Create Primary Key:\n {Sql}", createPrimaryKeySql);
            }

            if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
            {
                _database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} ON "));
            }

            //Call the NewTable-event to trigger the insert of base/default data
            //OnNewTable(tableName, _db, e, _logger);

            dataCreation.InitializeBaseData(tableName);

            if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
            {
                _database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} OFF;"));
            }

            //Loop through index statements and execute sql
            foreach (var sql in indexSql)
            {
                _database.Execute(new Sql(sql));
                _logger.Info <DatabaseSchemaCreator>("Create Index:\n {Sql}", sql);
            }

            //Loop through foreignkey statements and execute sql
            foreach (var sql in foreignSql)
            {
                _database.Execute(new Sql(sql));
                _logger.Info <DatabaseSchemaCreator>("Create Foreign Key:\n {Sql}", sql);
            }

            if (overwrite)
            {
                _logger.Info <Database>("Table {TableName} was recreated", tableName);
            }
            else
            {
                _logger.Info <Database>("New table {TableName} was created", tableName);
            }
        }
示例#3
0
        /// <summary>
        /// Creates a new table in the database for the specified <paramref name="modelType"/>.
        /// </summary>
        /// <param name="overwrite">Whether the table should be overwritten if it already exists.</param>
        /// <param name="modelType">The the representing the table.</param>
        /// <param name="dataCreation"></param>
        /// <remarks>
        /// If <paramref name="modelType"/> has been decorated with an <see cref="TableNameAttribute"/>, the name from
        /// that  attribute will be used for the table name. If the attribute is not present, the name
        /// <paramref name="modelType"/> will be used instead.
        ///
        /// If a table with the same name already exists, the <paramref name="overwrite"/> parameter will determine
        /// whether the table is overwritten. If <c>true</c>, the table will be overwritten, whereas this method will
        /// not do anything if the parameter is <c>false</c>.
        ///
        /// This need to execute as part of a transaction.
        /// </remarks>
        public void CreateTable(bool overwrite, Type modelType, DatabaseDataCreator dataCreation)
        {
            if (!_database.InTransaction)
            {
                throw new InvalidOperationException("Database is not in a transaction.");
            }

            var tableDefinition = DefinitionFactory.GetTableDefinition(modelType, SqlSyntax);
            var tableName       = tableDefinition.Name;

            var createSql           = SqlSyntax.Format(tableDefinition);
            var createPrimaryKeySql = SqlSyntax.FormatPrimaryKey(tableDefinition);
            var foreignSql          = SqlSyntax.Format(tableDefinition.ForeignKeys);
            var indexSql            = SqlSyntax.Format(tableDefinition.Indexes);

            var tableExist = TableExists(tableName);

            if (overwrite && tableExist)
            {
                _logger.Info <DatabaseSchemaCreator>("Table '{TableName}' already exists, but will be recreated", tableName);

                DropTable(tableName);
                tableExist = false;
            }

            if (tableExist)
            {
                // The table exists and was not recreated/overwritten.
                _logger.Info <Database>("Table '{TableName}' already exists - no changes were made", tableName);
                return;
            }

            //Execute the Create Table sql
            var created = _database.Execute(new Sql(createSql));

            _logger.Info <DatabaseSchemaCreator>("Create Table '{TableName}' ({Created}): \n {Sql}", tableName, created, createSql);

            //If any statements exists for the primary key execute them here
            if (string.IsNullOrEmpty(createPrimaryKeySql) == false)
            {
                var createdPk = _database.Execute(new Sql(createPrimaryKeySql));
                _logger.Info <DatabaseSchemaCreator>("Create Primary Key ({CreatedPk}):\n {Sql}", createdPk, createPrimaryKeySql);
            }

            //Turn on identity insert if db provider is not mysql
            if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
            {
                _database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} ON "));
            }

            //Call the NewTable-event to trigger the insert of base/default data
            //OnNewTable(tableName, _db, e, _logger);

            dataCreation.InitializeBaseData(tableName);

            //Turn off identity insert if db provider is not mysql
            if (SqlSyntax.SupportsIdentityInsert() && tableDefinition.Columns.Any(x => x.IsIdentity))
            {
                _database.Execute(new Sql($"SET IDENTITY_INSERT {SqlSyntax.GetQuotedTableName(tableName)} OFF;"));
            }

            //Special case for MySql
            if (SqlSyntax is MySqlSyntaxProvider && tableName.Equals("umbracoUser"))
            {
                _database.Update <UserDto>("SET id = @IdAfter WHERE id = @IdBefore AND userLogin = @Login", new { IdAfter = 0, IdBefore = 1, Login = "******" });
            }

            //Loop through index statements and execute sql
            foreach (var sql in indexSql)
            {
                var createdIndex = _database.Execute(new Sql(sql));
                _logger.Info <DatabaseSchemaCreator>("Create Index ({CreatedIndex}):\n {Sql}", createdIndex, sql);
            }

            //Loop through foreignkey statements and execute sql
            foreach (var sql in foreignSql)
            {
                var createdFk = _database.Execute(new Sql(sql));
                _logger.Info <DatabaseSchemaCreator>("Create Foreign Key ({CreatedFk}):\n {Sql}", createdFk, sql);
            }

            if (overwrite)
            {
                _logger.Info <Database>("Table '{TableName}' was recreated", tableName);
            }
            else
            {
                _logger.Info <Database>("New table '{TableName}' was created", tableName);
            }
        }