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);
            }
        }
Example #2
0
        public override async Task CreateTablesAsync(CancellationToken cancellationToken = default)
        {
            var operations = Dependencies.ModelDiffer.GetDifferences(null, Dependencies.Model);
            var commands   = Dependencies.MigrationsSqlGenerator.Generate(operations, Dependencies.Model);

            // Adding a PostgreSQL extension might define new types (e.g. hstore), which we
            // Npgsql to reload
            var reloadTypes = operations.Any(o => o is AlterDatabaseOperation && PostgresExtension.GetPostgresExtensions(o).Any());

            try
            {
                await Dependencies.MigrationCommandExecutor.ExecuteNonQueryAsync(commands, _connection,
                                                                                 cancellationToken);
            }
            catch (PostgresException e) when(
                e.SqlState == "23505" && e.ConstraintName == "pg_type_typname_nsp_index"
                )
            {
                // This occurs when two connections are trying to create the same database concurrently
                // (happens in the tests). Simply ignore the error.
            }

            // TODO: Not async
            if (reloadTypes)
            {
                var npgsqlConn = (NpgsqlConnection)_connection.DbConnection;
                if (npgsqlConn.FullState == ConnectionState.Open)
                {
                    npgsqlConn.ReloadTypes();
                }
            }
        }
Example #3
0
        public override void CreateTables()
        {
            var operations = Dependencies.ModelDiffer.GetDifferences(null, Dependencies.Model);
            var commands   = Dependencies.MigrationsSqlGenerator.Generate(operations, Dependencies.Model);

            // If a PostgreSQL extension or enum was added, we want Npgsql to reload all types at the ADO.NET level.
            var reloadTypes = operations.Any(o => o is AlterDatabaseOperation &&
                                             (PostgresExtension.GetPostgresExtensions(o).Any() ||
                                              PostgresEnum.GetPostgresEnums(o).Any()));

            try
            {
                Dependencies.MigrationCommandExecutor.ExecuteNonQuery(commands, _connection);
            }
            catch (PostgresException e) when(
                e.SqlState == "23505" && e.ConstraintName == "pg_type_typname_nsp_index"
                )
            {
                // This occurs when two connections are trying to create the same database concurrently
                // (happens in the tests). Simply ignore the error.
            }

            if (reloadTypes)
            {
                _connection.Open();
                try
                {
                    ((NpgsqlConnection)_connection.DbConnection).ReloadTypes();
                }
                catch
                {
                    _connection.Close();
                }
            }
        }
        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();
        }
        public override void CreateTables()
        {
            var operations = _modelDiffer.GetDifferences(null, Model);
            var commands   = _migrationsSqlGenerator.Generate(operations, Model);

            // Adding a PostgreSQL extension might define new types (e.g. hstore), which we
            // Npgsql to reload
            var reloadTypes = operations.Any(o => o is AlterDatabaseOperation && PostgresExtension.GetPostgresExtensions(o).Any());

            MigrationCommandExecutor.ExecuteNonQuery(commands, Connection);

            if (reloadTypes)
            {
                var npgsqlConn = (NpgsqlConnection)Connection.DbConnection;
                if (npgsqlConn.FullState == ConnectionState.Open)
                {
                    npgsqlConn.ReloadTypes();
                }
            }
        }
Example #6
0
        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();
        }
 public static IReadOnlyList <PostgresExtension> GetPostgresExtensions(this IReadOnlyModel model)
 => PostgresExtension.GetPostgresExtensions(model).ToArray();
 public static IReadOnlyList <PostgresExtension> GetOldPostgresExtensions([NotNull] this AlterDatabaseOperation operation)
 => PostgresExtension.GetPostgresExtensions(operation.OldDatabase).ToArray();
Example #9
0
 public static IReadOnlyList <PostgresExtension> GetPostgresExtensions(this AlterDatabaseOperation operation)
 => PostgresExtension.GetPostgresExtensions(operation).ToArray();
 public static IReadOnlyList <PostgresExtension> GetPostgresExtensions([NotNull] this DatabaseModel model)
 => PostgresExtension.GetPostgresExtensions(model).ToArray();