protected virtual void GenerateEnumStatements( [NotNull] AlterDatabaseOperation operation, [NotNull] IModel model, [NotNull] MigrationCommandListBuilder builder) { foreach (var enumTypeToCreate in operation.Npgsql().PostgresEnums .Where(ne => operation.Npgsql().OldPostgresEnums.All(oe => oe.Name != ne.Name))) { GenerateCreateEnum(enumTypeToCreate, model, builder); } foreach (var enumTypeToDrop in operation.Npgsql().OldPostgresEnums .Where(oe => operation.Npgsql().PostgresEnums.All(ne => ne.Name != oe.Name))) { GenerateDropEnum(enumTypeToDrop, model, builder); } // TODO: Some forms of enum alterations are actually supported... if (operation.Npgsql().PostgresEnums.FirstOrDefault(nr => operation.Npgsql().OldPostgresEnums.Any(or => or.Name == nr.Name) ) is PostgresEnum enumTypeToAlter) { throw new NotSupportedException($"Altering enum type ${enumTypeToAlter} isn't supported."); } }
protected virtual AlterDatabaseOperation PostFilterOperation(AlterDatabaseOperation operation) { HandleCharSetDelegation(operation, DelegationModes.ApplyToDatabases); ApplyCollationAnnotation(operation, (operation, collation) => operation.Collation ??= collation); ApplyCollationAnnotation(operation.OldDatabase, (operation, collation) => operation.Collation ??= collation); HandleCollationDelegation(operation, DelegationModes.ApplyToDatabases, o => o.Collation = null); // Ensure, that no properties have been added by the EF Core team in the meantime. // If they have, they need to be checked below. AssertMigrationOperationProperties( operation, new[] { nameof(AlterDatabaseOperation.OldDatabase), nameof(AlterDatabaseOperation.Collation), }); // Ensure, that this hasn't become an empty operation. return(operation.Collation != operation.OldDatabase.Collation || operation.IsReadOnly != operation.OldDatabase.IsReadOnly || HasDifferences(operation.GetAnnotations(), operation.OldDatabase.GetAnnotations()) ? operation : null); }
protected override void Generate( AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); foreach (var extension in PostgresExtension.GetPostgresExtensions(operation)) { GenerateCreateExtension(extension, model, builder); } foreach (var enumTypeToCreate in PostgresEnum.GetPostgresEnums(operation) .Where(ne => PostgresEnum.GetPostgresEnums(operation.OldDatabase).All(oe => oe.Name != ne.Name))) { GenerateCreateEnum(enumTypeToCreate, model, builder); } foreach (var enumTypeToDrop in PostgresEnum.GetPostgresEnums(operation.OldDatabase) .Where(oe => PostgresEnum.GetPostgresEnums(operation).All(ne => ne.Name != oe.Name))) { GenerateDropEnum(enumTypeToDrop, builder); } foreach (var enumTypeToAlter in from newEnum in PostgresEnum.GetPostgresEnums(operation) join oldEnum in PostgresEnum.GetPostgresEnums(operation.OldDatabase) on newEnum.Name equals oldEnum.Name select new { newEnum.Name, OldLabels = oldEnum.Labels, newLabels = newEnum.Labels }) { // TODO: Some forms of enum alterations are actually supported... At least log... } builder.EndCommand(); }
protected override void Generate( AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); foreach (var extension in PostgresExtension.GetPostgresExtensions(operation)) { builder .Append("CREATE EXTENSION IF NOT EXISTS ") .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(extension.Name)); if (extension.Schema != null) { builder .Append(" SCHEMA ") .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(extension.Schema)); } if (extension.Version != null) { builder .Append(" VERSION ") .Append(Dependencies.SqlGenerationHelper.DelimitIdentifier(extension.Version)); } builder.AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); EndStatement(builder, suppressTransaction: true); } }
public virtual AlterOperationBuilder <AlterDatabaseOperation> AlterDatabase() { var operation = new AlterDatabaseOperation(); Operations.Add(operation); return(new AlterOperationBuilder <AlterDatabaseOperation>(operation)); }
protected override void Generate( AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); }
public void DropPostgresEnum() { var op = new AlterDatabaseOperation(); PostgresEnum.GetOrAddPostgresEnum(op.OldDatabase, "public", "my_enum", new[] { "value1", "value2" }); Generate(op); Assert.Equal(@"DROP TYPE public.my_enum;" + EOL, Sql); }
public void CreatePostgresEnum() { var op = new AlterDatabaseOperation(); PostgresEnum.GetOrAddPostgresEnum(op, "public", "my_enum", new[] { "value1", "value2" }); Generate(op); Assert.Equal(@"CREATE TYPE public.my_enum AS ENUM ('value1', 'value2');" + EOL, Sql); }
public void EnsurePostgresExtension() { var op = new AlterDatabaseOperation(); PostgresExtension.GetOrAddPostgresExtension(op, "hstore"); Generate(op); Assert.Equal( @"CREATE EXTENSION IF NOT EXISTS hstore;" + EOL, Sql); }
public void EnsurePostgresExtension_with_schema() { var op = new AlterDatabaseOperation(); op.Npgsql().GetOrAddPostgresExtension("myschema", "hstore", null); Generate(op); Assert.Equal( @"CREATE EXTENSION IF NOT EXISTS hstore SCHEMA myschema;" + EOL, Sql); }
public void EnsurePostgresExtension_with_schema() { var op = new AlterDatabaseOperation(); var extension = PostgresExtension.GetOrAddPostgresExtension(op, "hstore"); extension.Schema = "myschema"; Generate(op); Assert.Equal( @"CREATE EXTENSION IF NOT EXISTS hstore SCHEMA myschema;" + EOL, Sql); }
protected virtual void Generate([NotNull] AlterDatabaseOperation operation, [NotNull] IndentedStringBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); builder.Append(".AlterDatabase()"); using (builder.Indent()) { Annotations(operation.GetAnnotations(), builder); OldAnnotations(operation.OldDatabase.GetAnnotations(), builder); } }
/// <summary> /// Builds commands for the given <see cref="AlterDatabaseOperation" /> by making calls on the given /// <see cref="MigrationCommandListBuilder" />. /// </summary> /// <param name="operation"> The operation. </param> /// <param name="model"> The target model which may be <c>null</c> if the operations exist without a model. </param> /// <param name="builder"> The command builder to use to build the commands. </param> protected override void Generate(AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) { if (operation[SqliteAnnotationNames.InitSpatialMetaData] as bool? != true || operation.OldDatabase[SqliteAnnotationNames.InitSpatialMetaData] as bool? == true) { return; } builder .Append("SELECT InitSpatialMetaData()") .AppendLine(Dependencies.SqlGenerationHelper.StatementTerminator); EndStatement(builder); }
public void CreatePostgresEnumWithSchema() { var op = new AlterDatabaseOperation(); PostgresEnum.GetOrAddPostgresEnum(op, "some_schema", "my_enum", new[] { "value1", "value2" }); Generate(op); Assert.Equal( @"CREATE SCHEMA IF NOT EXISTS some_schema;" + EOL + @"GO" + EOL + EOL + @"CREATE TYPE some_schema.my_enum AS ENUM ('value1', 'value2');" + EOL, Sql); }
public static MigrationBuilder EnsurePostgresExtension( this MigrationBuilder builder, string name, string?schema = null, string?version = null) { Check.NotEmpty(name, nameof(name)); Check.NullButNotEmpty(schema, nameof(schema)); Check.NullButNotEmpty(version, nameof(schema)); var op = new AlterDatabaseOperation(); op.GetOrAddPostgresExtension(schema, name, version); builder.Operations.Add(op); return(builder); }
protected override void Generate( AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(model, nameof(model)); Check.NotNull(builder, nameof(builder)); GenerateEnumStatements(operation, model, builder); GenerateRangeStatements(operation, model, builder); foreach (var extension in operation.Npgsql().PostgresExtensions) { GenerateCreateExtension(extension, model, builder); } builder.EndCommand(); }
protected override void Generate(AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) { var changeTrackingEnabled = operation.IsChangeTrackingEnabled(); var changeTrackingWasEnabled = operation.OldDatabase.FindAnnotation(SqlChangeTrackingAnnotationNames.Enabled)?.Value as bool? ?? false; if (!changeTrackingEnabled && !changeTrackingWasEnabled) { base.Generate(operation, model, builder); return; } var sqlHelper = Dependencies.SqlGenerationHelper; var database = Dependencies.CurrentContext.Context.Database.GetDbConnection().Database; if (changeTrackingEnabled) { Generate(new EnableChangeTrackingForDatabaseOperation(operation.ChangeTrackingRetentionDays(), operation.ChangeTrackingAutoCleanUp()), model, builder); } else { Generate(new DisableChangeTrackingForDatabaseOperation(), model, builder); } //if (serviceBrokerEnabled) //{ // builder // .Append("ALTER DATABASE ") // .Append(sqlHelper.DelimitIdentifier(database)) // .Append(" SET ALLOW_SNAPSHOT_ISOLATION ON ") // .AppendLine(sqlHelper.StatementTerminator) // .EndCommand(); //} //else //{ // builder // .Append("ALTER DATABASE ") // .Append(sqlHelper.DelimitIdentifier(database)) // .Append(" SET ALLOW_SNAPSHOT_ISOLATION OFF ") // .AppendLine(sqlHelper.StatementTerminator) // .EndCommand(); //} }
public static MigrationBuilder EnsurePostgresExtension( this MigrationBuilder builder, [NotNull] string name, string schema = null, string version = null ) { Check.NotEmpty(name, nameof(name)); Check.NullButNotEmpty(schema, nameof(schema)); Check.NullButNotEmpty(version, nameof(schema)); var op = new AlterDatabaseOperation(); var extension = PostgresExtension.GetOrAddPostgresExtension(op, name); extension.Schema = schema; extension.Version = version; builder.Operations.Add(op); return(builder); }
protected virtual IEnumerable <MigrationOperation> PostFilterOperations(IEnumerable <MigrationOperation> migrationOperations) { foreach (var migrationOperation in migrationOperations) { var resultOperation = migrationOperation switch { AlterDatabaseOperation operation => PostFilterOperation(operation), CreateTableOperation operation => PostFilterOperation(operation), AlterTableOperation operation => PostFilterOperation(operation), AddColumnOperation operation => PostFilterOperation(operation), AlterColumnOperation operation => PostFilterOperation(operation), _ => migrationOperation }; if (resultOperation != null) { yield return(resultOperation); } } }
private IEnumerable <MigrationOperation> DiffAnnotations( IModel source, IModel target) { var sourceMigrationsAnnotations = source == null ? null : MigrationsAnnotations.For(source).ToList(); var targetMigrationsAnnotations = target == null ? null : MigrationsAnnotations.For(target).ToList(); if (source == null) { if (targetMigrationsAnnotations?.Count > 0) { var alterDatabaseOperation = new AlterDatabaseOperation(); alterDatabaseOperation.AddAnnotations(targetMigrationsAnnotations); yield return(alterDatabaseOperation); } yield break; } if (target == null) { sourceMigrationsAnnotations = MigrationsAnnotations.ForRemove(source).ToList(); if (sourceMigrationsAnnotations.Count > 0) { var alterDatabaseOperation = new AlterDatabaseOperation(); alterDatabaseOperation.OldDatabase.AddAnnotations(MigrationsAnnotations.ForRemove(source)); yield return(alterDatabaseOperation); } yield break; } if (HasDifferences(sourceMigrationsAnnotations, targetMigrationsAnnotations)) { var alterDatabaseOperation = new AlterDatabaseOperation(); alterDatabaseOperation.AddAnnotations(targetMigrationsAnnotations); alterDatabaseOperation.OldDatabase.AddAnnotations(sourceMigrationsAnnotations); yield return(alterDatabaseOperation); } }
protected override void Generate( AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); foreach (var extension in PostgresExtension.GetPostgresExtensions(operation)) { GenerateCreateExtension(extension, model, builder); } foreach (var enumType in PostgresEnum.GetPostgresEnums(operation)) { GenerateCreateEnum(enumType, model, builder); } // TODO: Some forms of enum alterations are actually supported... foreach (var enumType in PostgresEnum.GetPostgresEnums(operation.OldDatabase)) { GenerateDropEnum(enumType, builder); } builder.EndCommand(); }
protected virtual void GenerateRangeStatements( [NotNull] AlterDatabaseOperation operation, [NotNull] IModel model, [NotNull] MigrationCommandListBuilder builder) { foreach (var rangeTypeToCreate in operation.Npgsql().PostgresRanges .Where(ne => operation.Npgsql().OldPostgresRanges.All(oe => oe.Name != ne.Name))) { GenerateCreateRange(rangeTypeToCreate, model, builder); } foreach (var rangeTypeToDrop in operation.Npgsql().OldPostgresRanges .Where(oe => operation.Npgsql().PostgresRanges.All(ne => ne.Name != oe.Name))) { GenerateDropRange(rangeTypeToDrop, model, builder); } if (operation.Npgsql().PostgresRanges.FirstOrDefault(nr => operation.Npgsql().OldPostgresRanges.Any(or => or.Name == nr.Name) ) is PostgresRange rangeTypeToAlter) { throw new NotSupportedException($"Altering range type ${rangeTypeToAlter} isn't supported."); } }
protected virtual void Generate( [NotNull] AlterDatabaseOperation operation, [CanBeNull] IModel model, [NotNull] MigrationCommandListBuilder builder) { }
public static IReadOnlyList <PostgresEnum> GetPostgresEnums([NotNull] this AlterDatabaseOperation operation) => PostgresEnum.GetPostgresEnums(operation).ToArray();
public static PostgresExtension GetOrAddPostgresExtension( this AlterDatabaseOperation operation, string?schema, string name, string?version) => PostgresExtension.GetOrAddPostgresExtension(operation, schema, name, version);
public static IReadOnlyList <PostgresRange> GetOldPostgresRanges([NotNull] this AlterDatabaseOperation operation) => PostgresRange.GetPostgresRanges(operation.OldDatabase).ToArray();
public static PostgresExtension GetOrAddPostgresExtension( [NotNull] this AlterDatabaseOperation operation, [CanBeNull] string schema, [NotNull] string name, [CanBeNull] string version) => PostgresExtension.GetOrAddPostgresExtension(operation, schema, name, version);
protected override void Generate( AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) { Check.NotNull(operation, nameof(operation)); Check.NotNull(builder, nameof(builder)); builder.AppendLine("IF SERVERPROPERTY('IsXTPSupported') = 1 AND SERVERPROPERTY('EngineEdition') <> 5"); using (builder.Indent()) { builder .AppendLine("BEGIN") .AppendLine("IF NOT EXISTS ("); using (builder.Indent()) { builder .Append("SELECT 1 FROM [sys].[filegroups] [FG] ") .Append("JOIN [sys].[database_files] [F] ON [FG].[data_space_id] = [F].[data_space_id] ") .AppendLine("WHERE [FG].[type] = N'FX' AND [F].[type] = 2)"); } using (builder.Indent()) { builder .AppendLine("BEGIN") .AppendLine("DECLARE @db_name NVARCHAR(MAX) = DB_NAME();") .AppendLine("DECLARE @fg_name NVARCHAR(MAX);") .AppendLine("SELECT TOP(1) @fg_name = [name] FROM [sys].[filegroups] WHERE [type] = N'FX';") .AppendLine() .AppendLine("IF @fg_name IS NULL"); using (builder.Indent()) { builder .AppendLine("BEGIN") .AppendLine("SET @fg_name = @db_name + N'_MODFG';") .AppendLine("EXEC(N'ALTER DATABASE CURRENT ADD FILEGROUP [' + @fg_name + '] CONTAINS MEMORY_OPTIMIZED_DATA;');") .AppendLine("END"); } builder .AppendLine() .AppendLine("DECLARE @path NVARCHAR(MAX);") .Append("SELECT TOP(1) @path = [physical_name] FROM [sys].[database_files] ") .AppendLine("WHERE charindex('\\', [physical_name]) > 0 ORDER BY [file_id];") .AppendLine("IF (@path IS NULL)") .IncrementIndent().AppendLine("SET @path = '\\' + @db_name;").DecrementIndent() .AppendLine() .AppendLine("DECLARE @filename NVARCHAR(MAX) = right(@path, charindex('\\', reverse(@path)) - 1);") .AppendLine("SET @filename = REPLACE(left(@filename, len(@filename) - charindex('.', reverse(@filename))), '''', '''''') + N'_MOD';") .AppendLine("DECLARE @new_path NVARCHAR(MAX) = REPLACE(CAST(SERVERPROPERTY('InstanceDefaultDataPath') AS NVARCHAR(MAX)), '''', '''''') + @filename;") .AppendLine() .AppendLine("EXEC(N'"); using (builder.Indent()) { builder .AppendLine("ALTER DATABASE CURRENT") .AppendLine("ADD FILE (NAME=''' + @filename + ''', filename=''' + @new_path + ''')") .AppendLine("TO FILEGROUP [' + @fg_name + '];')"); } builder.AppendLine("END"); } builder.AppendLine("END"); } builder.AppendLine() .AppendLine("IF SERVERPROPERTY('IsXTPSupported') = 1") .AppendLine("EXEC(N'"); using (builder.Indent()) { builder .AppendLine("ALTER DATABASE CURRENT") .AppendLine("SET MEMORY_OPTIMIZED_ELEVATE_TO_SNAPSHOT ON;')"); } builder.EndCommand(suppressTransaction: true); }
protected override void Generate(AlterDatabaseOperation operation, IModel model, MigrationCommandListBuilder builder) => base.Generate(operation, model, builder);
/// <summary> /// 修数据库。 /// </summary> /// <param name="operation">操作实例。</param> /// <param name="builder"><see cref="MigrationCommandListBuilder"/>实例对象。</param> protected virtual void Generate( AlterDatabaseOperation operation, MigrationCommandListBuilder builder) { }