Skip to content
This repository has been archived by the owner on Aug 23, 2024. It is now read-only.

Commit

Permalink
Postgres - Add x-schema-name URL Query support (golang-migrate#95)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephane-klein committed Nov 29, 2020
1 parent a53e6fc commit f01f70f
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 20 deletions.
34 changes: 18 additions & 16 deletions database/postgres/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,24 @@

`postgres://user:password@host:port/dbname?query` (`postgresql://` works, too)

| URL Query | WithInstance Config | Description |
|------------|---------------------|-------------|
| `x-migrations-table` | `MigrationsTable` | Name of the migrations table |
| `x-statement-timeout` | `StatementTimeout` | Abort any statement that takes more than the specified number of milliseconds |
| `dbname` | `DatabaseName` | The name of the database to connect to |
| `search_path` | | This variable specifies the order in which schemas are searched when an object is referenced by a simple name with no schema specified. |
| `user` | | The user to sign in as |
| `password` | | The user's password |
| `host` | | The host to connect to. Values that start with / are for unix domain sockets. (default is localhost) |
| `port` | | The port to bind to. (default is 5432) |
| `fallback_application_name` | | An application_name to fall back to if one isn't provided. |
| `connect_timeout` | | Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely. |
| `sslcert` | | Cert file location. The file must contain PEM encoded data. |
| `sslkey` | | Key file location. The file must contain PEM encoded data. |
| `sslrootcert` | | The location of the root certificate file. The file must contain PEM encoded data. |
| `sslmode` | | Whether or not to use SSL (disable\|require\|verify-ca\|verify-full) |
| URL Query | WithInstance Config | Description | Default value |
|------------|---------------------|-------------|---------------|
| `x-migrations-table` | `MigrationsTable` | Name of the migrations table | `schema_migrations` |
| `x-migrations-schema-name` | `SchemaName` | Schema name of the migrations table | `SELECT CURRENT_SCHEMA()` result |
| `x-statement-timeout` | `StatementTimeout` | Abort any statement that takes more than the specified number of milliseconds | `0` |
| `dbname` | `DatabaseName` | The name of the database to connect to (default )| `SELECT CURRENT_DATABASE()` result |
| `search_path` | | This variable specifies the order in which schemas are searched when an object is referenced by a simple name with no schema specified. | |
| `user` | | The user to sign in as | |
| `password` | | The user's password | |
| `host` | | The host to connect to. Values that start with / are for unix domain sockets | `localhost` |
| `port` | | The port to bind to| `5432` |
| `fallback_application_name` | | An application_name to fall back to if one isn't provided. | |
| `connect_timeout` | | Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely. | |
| `sslcert` | | Cert file location. The file must contain PEM encoded data. | |
| `sslkey` | | Key file location. The file must contain PEM encoded data. | |
| `sslrootcert` | | The location of the root certificate file. The file must contain PEM encoded data. | |
| `sslmode` | | Whether or not to use SSL (disable\|require\|verify-ca\|verify-full) | |



## Upgrading from v1
Expand Down
10 changes: 6 additions & 4 deletions database/postgres/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ func (p *Postgres) Open(url string) (database.Driver, error) {
}

migrationsTable := purl.Query().Get("x-migrations-table")
schemaName := purl.Query().Get("x-migrations-schema-name")
statementTimeoutString := purl.Query().Get("x-statement-timeout")
statementTimeout := 0
if statementTimeoutString != "" {
Expand All @@ -135,6 +136,7 @@ func (p *Postgres) Open(url string) (database.Driver, error) {
px, err := WithInstance(db, &Config{
DatabaseName: purl.Path,
MigrationsTable: migrationsTable,
SchemaName: schemaName,
StatementTimeout: time.Duration(statementTimeout) * time.Millisecond,
})

Expand Down Expand Up @@ -272,7 +274,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error {
return &database.Error{OrigErr: err, Err: "transaction start failed"}
}

query := `TRUNCATE ` + pq.QuoteIdentifier(p.config.MigrationsTable)
query := `TRUNCATE ` + pq.QuoteIdentifier(p.config.SchemaName) + `.` + pq.QuoteIdentifier(p.config.MigrationsTable)
if _, err := tx.Exec(query); err != nil {
if errRollback := tx.Rollback(); errRollback != nil {
err = multierror.Append(err, errRollback)
Expand All @@ -284,7 +286,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error {
// empty schema version for failed down migration on the first migration
// See: https://github.com/golang-migrate/migrate/issues/330
if version >= 0 || (version == database.NilVersion && dirty) {
query = `INSERT INTO ` + pq.QuoteIdentifier(p.config.MigrationsTable) +
query = `INSERT INTO ` + pq.QuoteIdentifier(p.config.SchemaName) + `.` + pq.QuoteIdentifier(p.config.MigrationsTable) +
` (version, dirty) VALUES ($1, $2)`
if _, err := tx.Exec(query, version, dirty); err != nil {
if errRollback := tx.Rollback(); errRollback != nil {
Expand All @@ -302,7 +304,7 @@ func (p *Postgres) SetVersion(version int, dirty bool) error {
}

func (p *Postgres) Version() (version int, dirty bool, err error) {
query := `SELECT version, dirty FROM ` + pq.QuoteIdentifier(p.config.MigrationsTable) + ` LIMIT 1`
query := `SELECT version, dirty FROM ` + pq.QuoteIdentifier(p.config.SchemaName) + `.` + pq.QuoteIdentifier(p.config.MigrationsTable) + ` LIMIT 1`
err = p.conn.QueryRowContext(context.Background(), query).Scan(&version, &dirty)
switch {
case err == sql.ErrNoRows:
Expand Down Expand Up @@ -380,7 +382,7 @@ func (p *Postgres) ensureVersionTable() (err error) {
}
}()

query := `CREATE TABLE IF NOT EXISTS ` + pq.QuoteIdentifier(p.config.MigrationsTable) + ` (version bigint not null primary key, dirty boolean not null)`
query := `CREATE TABLE IF NOT EXISTS ` + pq.QuoteIdentifier(p.config.SchemaName) + `.` + pq.QuoteIdentifier(p.config.MigrationsTable) + ` (version bigint not null primary key, dirty boolean not null)`
if _, err = p.conn.ExecContext(context.Background(), query); err != nil {
return &database.Error{OrigErr: err, Query: []byte(query)}
}
Expand Down

0 comments on commit f01f70f

Please sign in to comment.