Beispiel #1
0
        public async Task CreateDatabaseAsync()
        {
            // Check if our database exists yet
            if (!await _dbProvider.CheckIfDatabaseExistsAsync().ConfigureAwait(false))
            {
                await _dbProvider.CreateDatabaseAsync().ConfigureAwait(false);
            }

            // Check if DatabaseVersion table is setup, if not, create it.
            if (!await _dbProvider.CheckIfTableExistsAsync("DatabaseVersions").ConfigureAwait(false))
            {
                var database = new Database(_dbProvider.DatabaseName, _dbProvider.Dialect);

                var dbVersionTable = database.AddTable("DatabaseVersions");
                dbVersionTable.AddColumn("VersionNumber", typeof(int)).PrimaryKey().Clustered().NotNullable();
                dbVersionTable.AddColumn("MigrationDate", typeof(DateTime)).NotNullable();
                dbVersionTable.AddColumn("IsBeforeMigrationComplete", typeof(bool)).NotNullable(true);
                dbVersionTable.AddColumn("IsMigrationComplete", typeof(bool)).NotNullable(true);
                dbVersionTable.AddColumn("IsAfterMigrationComplete", typeof(bool)).NotNullable(true);

                await _dbProvider.ExecuteNonQueryAsync(database.ToString()).ConfigureAwait(false);
            }
            else
            {
                // Check if the new fields have bee added to the DatabaseVersion table yet, if not add them.
                if (!await _dbProvider.CheckIfTableColumnExistsAsync("DatabaseVersions", "IsBeforeMigrationComplete").ConfigureAwait(false))
                {
                    var database = new Database(_dbProvider.DatabaseName, _dbProvider.Dialect);

                    var dbVersionTable = database.UpdateTable("DatabaseVersions");
                    dbVersionTable.AddColumn("IsBeforeMigrationComplete", typeof(bool)).NotNullable(true);
                    dbVersionTable.AddColumn("IsMigrationComplete", typeof(bool)).NotNullable(true);
                    dbVersionTable.AddColumn("IsAfterMigrationComplete", typeof(bool)).NotNullable(true);

                    await _dbProvider.ExecuteNonQueryAsync(database.ToString()).ConfigureAwait(false);
                }
            }
        }
        /// <inheritdoc />
        public async Task MigrateAsync(CancellationToken token = default)
        {
            try
            {
                if (_migrationMap.Count == 0)
                {
                    _logger?.LogWarning("No migrations were added to migrator. Skip migration");
                    return;
                }

                // check if database exists and create if not
                _logger?.LogInformation($"Check Database \"{_dbProvider.DbName}\" existence...");
                var isDatabaseExist = await _dbProvider.CheckIfDatabaseExistsAsync(_dbProvider.DbName, token);

                if (isDatabaseExist)
                {
                    _logger?.LogInformation($"Database \"{_dbProvider.DbName}\" exists. Starting migration...");
                }
                else
                {
                    _logger?.LogInformation($"Database \"{_dbProvider.DbName}\" doesn't exist. Creating database...");
                    await _dbProvider.CreateDatabaseIfNotExistsAsync(token);

                    _logger?.LogInformation("Creating database completed.");
                }

                await _dbProvider.OpenConnectionAsync(token);

                // check if applied migrations table exists and create if not
                _logger?.LogInformation($"Check \"{_dbProvider.AppliedMigrationsTableName}\" table existence...");
                var isMigrationTableExists = await _dbProvider.CheckIfTableExistsAsync(_dbProvider.AppliedMigrationsTableName, token);

                if (isMigrationTableExists)
                {
                    _logger?.LogInformation($"Table \"{_dbProvider.AppliedMigrationsTableName}\" exists. ");
                }
                else
                {
                    _logger?.LogInformation($"Creating \"{_dbProvider.AppliedMigrationsTableName}\" table...");
                    await _dbProvider.CreateAppliedMigrationsTableIfNotExistsAsync(token);

                    _logger?.LogInformation($"Creating \"{_dbProvider.AppliedMigrationsTableName}\" table completed.");
                }

                // get applied migrations versions
                var(isUpgrade, migrationsToApply) = await GetMigrationsAsync(false, token);

                if (migrationsToApply.Count == 0)
                {
                    _logger?.LogInformation($"Database \"{_dbProvider.DbName}\" is actual. Skip migration.");
                    return;
                }

                _logger?.LogInformation($"Executing pre-migration scripts for database \"{_dbProvider.DbName}\"...");
                var wasPreMigrationExecuted = await ExecutePreMigrationScriptsAsync(token);

                if (wasPreMigrationExecuted)
                {
                    _logger?.LogInformation($"Executing pre-migration scripts for database \"{_dbProvider.DbName}\" completed.");

                    // applied migration versions might be changed after pre-migration
                    (isUpgrade, migrationsToApply) = await GetMigrationsAsync(true, token);
                }
                else
                {
                    _logger?.LogInformation("No pre-migration scripts were found.");
                }

                if (migrationsToApply.Count == 0)
                {
                    _logger?.LogInformation($"Database \"{_dbProvider.DbName}\" is actual. Skip migration.");
                    return;
                }

                _logger?.LogInformation($"Migrating database \"{_dbProvider.DbName}\"...");
                var policy = isUpgrade
                    ? _upgradePolicy
                    : _downgradePolicy;
                await MigrateAsync(migrationsToApply, isUpgrade, policy, token);

                await _dbProvider.CloseConnectionAsync();

                _logger?.LogInformation($"Migrating database {_dbProvider.DbName} completed.");
            }
            catch (MigrationException)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new MigrationException(
                          MigrationError.MigratingError,
                          $"Error while migrating database {_dbProvider.DbName}. Reason: {e.Message}",
                          e);
            }
        }