private bool Exists(bool retryOnNotExists)
        => Dependencies.ExecutionStrategyFactory.Create().Execute(
            DateTime.UtcNow + RetryTimeout, giveUp =>
        {
            while (true)
            {
                try
                {
                    using (new TransactionScope(TransactionScopeOption.Suppress))
                    {
                        _connection.Open(errorsExpected: true);
                        _connection.Close();
                    }
                    return(true);
                }
                catch (PostgresException e)
                {
                    if (!retryOnNotExists &&
                        IsDoesNotExist(e))
                    {
                        return(false);
                    }

                    if (DateTime.UtcNow > giveUp ||
                        !RetryOnExistsFailure(e))
                    {
                        throw;
                    }

                    Thread.Sleep(RetryDelay);
                }
            }
        });
        public override void CreateTables()
        {
            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
            {
                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();
                }
            }
        }
Exemplo n.º 3
0
        public override void CreateTables()
        {
            var operations = Dependencies.ModelDiffer.GetDifferences(null, Dependencies.Model.GetRelationalModel());
            var commands   = Dependencies.MigrationsSqlGenerator.Generate(operations, Dependencies.Model);

            // If a PostgreSQL extension, enum or range was added, we want Npgsql to reload all types at the ADO.NET level.
            var reloadTypes =
                operations.OfType <AlterDatabaseOperation>()
                .Any(o =>
                     o.GetPostgresExtensions().Any() ||
                     o.GetPostgresEnums().Any() ||
                     o.GetPostgresRanges().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();
                }
            }
        }