Skip to content

Commit

Permalink
Add cockroachdb README and add ForceLock functionality
Browse files Browse the repository at this point in the history
Adds a readme to the cockroachdb database package, following the
postgres readme style.

Also adds the ability to force acquisition of the migration lock
via a connect URL parameter/WithInstance config, to allow for fixing
cases where an implementation error causes the schema lock to not
be released.

Lastly, tweaks the CLI readme to include information on building a
CLI for databases other than postgres.
  • Loading branch information
taywrobel committed Jul 12, 2017
1 parent 23a2745 commit 40a4061
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 2 deletions.
8 changes: 7 additions & 1 deletion cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ $ go get -u -d github.com/mattes/migrate/cli github.com/lib/pq
$ go build -tags 'postgres' -o /usr/local/bin/migrate github.com/mattes/migrate/cli
```

Note: This example builds the cli which will only work with postgres. In order
to build the cli for use with other databases, replace the `postgres` build tag
with the appropriate database tag(s) for the databases desired. The tags
correspond to the names of the sub-packages underneath the
[`database`](../database) package.

#### MacOS

([todo #156](https://github.com/mattes/migrate/issues/156))
Expand Down Expand Up @@ -45,7 +51,7 @@ Usage: migrate OPTIONS COMMAND [arg...]
Options:
-source Location of the migrations (driver://url)
-path Shorthand for -source=file://path
-path Shorthand for -source=file://path
-database Run migrations against this database (driver://url)
-prefetch N Number of migrations to load in advance before executing (default 10)
-lock-timeout N Allow N seconds to acquire database lock (default 15)
Expand Down
19 changes: 19 additions & 0 deletions database/cockroachdb/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# cockroachdb

`cockroachdb://user:password@host:port/dbname?query` (`cockroach://`, and `crdb-postgres://` work, too)

| URL Query | WithInstance Config | Description |
|------------|---------------------|-------------|
| `x-migrations-table` | `MigrationsTable` | Name of the migrations table |
| `x-lock-table` | `LockTable` | Name of the table which maintains the migration lock |
| `x-force-lock` | `ForceLock` | Force lock acquisition to fix faulty migrations which may not have released the schema lock (Boolean, default is `false`) |
| `dbname` | `DatabaseName` | The name of the database to connect to |
| `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) |
| `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) |
20 changes: 19 additions & 1 deletion database/cockroachdb/cockroachdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/mattes/migrate"
"github.com/mattes/migrate/database"
"regexp"
"strconv"
)

func init() {
Expand All @@ -32,6 +33,7 @@ var (
type Config struct {
MigrationsTable string
LockTable string
ForceLock bool
DatabaseName string
}

Expand Down Expand Up @@ -114,10 +116,17 @@ func (c *CockroachDb) Open(url string) (database.Driver, error) {
lockTable = DefaultLockTable
}

forceLockQuery := purl.Query().Get("x-force-lock")
forceLock, err := strconv.ParseBool(forceLockQuery)
if err != nil {
forceLock = false
}

px, err := WithInstance(db, &Config{
DatabaseName: purl.Path,
MigrationsTable: migrationsTable,
LockTable: lockTable,
ForceLock: forceLock,
})
if err != nil {
return nil, err
Expand Down Expand Up @@ -148,7 +157,7 @@ func (c *CockroachDb) Lock() error {

// If row exists at all, lock is present
locked := rows.Next()
if locked {
if locked && !c.config.ForceLock {
return database.Error{Err: "lock could not be acquired; already locked", Query: []byte(query)}
}

Expand Down Expand Up @@ -180,6 +189,15 @@ func (c *CockroachDb) Unlock() error {
// a better locking mechanism is added, a manual purging of the lock table may be required in such circumstances
query := "DELETE FROM " + c.config.LockTable + " WHERE lock_id = $1"
if _, err := c.db.Exec(query, aid); err != nil {
if e, ok := err.(*pq.Error); ok {
// 42P01 is "UndefinedTableError" in CockroachDB
// https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/pgwire/pgerror/codes.go
if e.Code == "42P01" {
// On drops, the lock table is fully removed; This is fine, and is a valid "unlocked" state for the schema
c.isLocked = false
return nil
}
}
return database.Error{OrigErr: err, Err: "failed to release migration lock", Query: []byte(query)}
}

Expand Down

0 comments on commit 40a4061

Please sign in to comment.