Skip to content

Config migration table name #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,18 @@ The production database sees the migrations applied out of order with respect to

A `migrations` table is created as the first migration, before any user-supplied migrations. This keeps track of all the migrations which have already been run.

You can specify a different name by passing a config object as the third parameter to `migrate` with the property `migrationTableName`, as shown below:

```js
const { migrate} = require("postgres-migrations")

migrate(
dbConfig
"path/to/migration/files",
{ migrationTableName: "custom_migrations_table"}
)
```

### Hash checks for previous migrations

Previously run migration scripts shouldn't be modified, since we want the process to be repeated in the same way for every new environment.
Expand Down
72 changes: 53 additions & 19 deletions src/__tests__/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ const migrate = require("../migrate")
const CONTAINER_NAME = "pg-migrations-test-migrate"
const PASSWORD = startPostgres.PASSWORD

const MIGRATION_TABLE = "test_migrations_table"

const runMigration = (dbConfig, migrationsDirectory) =>
migrate(dbConfig, migrationsDirectory, {
migrationTableName: MIGRATION_TABLE,
})

let port

process.on("uncaughtException", function(err) {
Expand All @@ -21,6 +28,24 @@ test.cb.before(t => {
port = startPostgres(CONTAINER_NAME, t)
})

test("create migration table", t => {
const databaseName = "migration-table-name-test"
const dbConfig = {
database: databaseName,
user: "postgres",
password: PASSWORD,
host: "localhost",
port,
}

return createDb(databaseName, dbConfig)
.then(() => runMigration(dbConfig, "src/__tests__/fixtures/success-first"))
.then(() => doesTableExist(dbConfig, MIGRATION_TABLE))
.then(exists => {
t.truthy(exists)
})
})

test("successful first migration", t => {
const databaseName = "migration-test-success-first"
const dbConfig = {
Expand All @@ -32,7 +57,7 @@ test("successful first migration", t => {
}

return createDb(databaseName, dbConfig)
.then(() => migrate(dbConfig, "src/__tests__/fixtures/success-first"))
.then(() => runMigration(dbConfig, "src/__tests__/fixtures/success-first"))
.then(() => doesTableExist(dbConfig, "success"))
.then(exists => {
t.truthy(exists)
Expand All @@ -50,8 +75,8 @@ test("successful second migration", t => {
}

return createDb(databaseName, dbConfig)
.then(() => migrate(dbConfig, "src/__tests__/fixtures/success-first"))
.then(() => migrate(dbConfig, "src/__tests__/fixtures/success-second"))
.then(() => runMigration(dbConfig, "src/__tests__/fixtures/success-first"))
.then(() => runMigration(dbConfig, "src/__tests__/fixtures/success-second"))
.then(() => doesTableExist(dbConfig, "more_success"))
.then(exists => {
t.truthy(exists)
Expand All @@ -69,7 +94,9 @@ test("successful first javascript migration", t => {
}

return createDb(databaseName, dbConfig)
.then(() => migrate(dbConfig, "src/__tests__/fixtures/success-js-first"))
.then(() =>
runMigration(dbConfig, "src/__tests__/fixtures/success-js-first"),
)
.then(() => doesTableExist(dbConfig, "success"))
.then(exists => {
t.truthy(exists)
Expand All @@ -87,9 +114,14 @@ test("successful second mixed js and sql migration", t => {
}

return createDb(databaseName, dbConfig)
.then(() => migrate(dbConfig, "src/__tests__/fixtures/success-js-first"))
.then(() =>
migrate(dbConfig, "src/__tests__/fixtures/success-second-mixed-js-sql"),
runMigration(dbConfig, "src/__tests__/fixtures/success-js-first"),
)
.then(() =>
runMigration(
dbConfig,
"src/__tests__/fixtures/success-second-mixed-js-sql",
),
)
.then(() => doesTableExist(dbConfig, "more_success"))
.then(exists => {
Expand All @@ -108,7 +140,9 @@ test("successful complex js migration", t => {
}

return createDb(databaseName, dbConfig)
.then(() => migrate(dbConfig, "src/__tests__/fixtures/success-complex-js"))
.then(() =>
runMigration(dbConfig, "src/__tests__/fixtures/success-complex-js"),
)
.then(() => doesTableExist(dbConfig, "complex"))
.then(exists => {
t.truthy(exists)
Expand Down Expand Up @@ -246,7 +280,7 @@ test("no migrations dir", t => {
}

const promise = createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "some/path")
return runMigration(dbConfig, "some/path")
})

return t.throws(promise).then(err => {
Expand All @@ -266,7 +300,7 @@ test("empty migrations dir", t => {
}

return createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "src/__tests__/fixtures/empty")
return runMigration(dbConfig, "src/__tests__/fixtures/empty")
})
})

Expand All @@ -281,7 +315,7 @@ test("non-consecutive ordering", t => {
}

const promise = createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "src/__tests__/fixtures/non-consecutive")
return runMigration(dbConfig, "src/__tests__/fixtures/non-consecutive")
})

return t.throws(promise).then(err => {
Expand All @@ -300,7 +334,7 @@ test("not starting from one", t => {
}

const promise = createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "src/__tests__/fixtures/start-from-2")
return runMigration(dbConfig, "src/__tests__/fixtures/start-from-2")
})

return t.throws(promise).then(err => {
Expand All @@ -319,7 +353,7 @@ test("negative ID", t => {
}

const promise = createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "src/__tests__/fixtures/negative")
return runMigration(dbConfig, "src/__tests__/fixtures/negative")
})

return t.throws(promise).then(err => {
Expand All @@ -339,7 +373,7 @@ test("invalid file name", t => {
}

const promise = createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "src/__tests__/fixtures/invalid-file-name")
return runMigration(dbConfig, "src/__tests__/fixtures/invalid-file-name")
})

return t.throws(promise).then(err => {
Expand All @@ -359,7 +393,7 @@ test("syntax error", t => {
}

const promise = createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "src/__tests__/fixtures/syntax-error")
return runMigration(dbConfig, "src/__tests__/fixtures/syntax-error")
})

return t.throws(promise).then(err => {
Expand All @@ -378,7 +412,7 @@ test("bad javascript file - no generateSql method exported", t => {
}

const promise = createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "src/__tests__/fixtures/js-no-generate-sql")
return runMigration(dbConfig, "src/__tests__/fixtures/js-no-generate-sql")
})

return t.throws(promise).then(err => {
Expand All @@ -397,7 +431,7 @@ test("bad javascript file - generateSql not returning string literal", t => {
}

const promise = createDb(databaseName, dbConfig).then(() => {
return migrate(dbConfig, "src/__tests__/fixtures/js-no-string-literal")
return runMigration(dbConfig, "src/__tests__/fixtures/js-no-string-literal")
})

return t.throws(promise).then(err => {
Expand All @@ -417,10 +451,10 @@ test("hash check failure", t => {

const promise = createDb(databaseName, dbConfig)
.then(() =>
migrate(dbConfig, "src/__tests__/fixtures/hash-check/first-run"),
runMigration(dbConfig, "src/__tests__/fixtures/hash-check/first-run"),
)
.then(() =>
migrate(dbConfig, "src/__tests__/fixtures/hash-check/second-run"),
runMigration(dbConfig, "src/__tests__/fixtures/hash-check/second-run"),
)

return t.throws(promise).then(err => {
Expand All @@ -440,7 +474,7 @@ test("rollback", t => {
}

const promise = createDb(databaseName, dbConfig).then(() =>
migrate(dbConfig, "src/__tests__/fixtures/rollback"),
runMigration(dbConfig, "src/__tests__/fixtures/rollback"),
)

return t
Expand Down
2 changes: 1 addition & 1 deletion src/files-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ module.exports.load = async (directory, log) => {
let orderedMigrations = []
if (fileNames) {
const migrationFiles = [
path.join(__dirname, "migrations/0_create-migrations-table.sql"),
path.join(__dirname, "migrations/0_index-place-holder.sql"),
...fileNames.reduce(filterAndResolveFileName(directory), []),
]

Expand Down
16 changes: 15 additions & 1 deletion src/migrate.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module.exports = async function migrate(
async function runMigrations(dbConfig, migrationsDirectory, config) {
const log = config.logger || (() => {})

const migrationTableName = "migrations"
const migrationTableName = config.migrationTableName || "migrations"

const client = new pg.Client(dbConfig)

Expand All @@ -54,6 +54,9 @@ async function runMigrations(dbConfig, migrationsDirectory, config) {

validateMigrations(migrations, appliedMigrations)

await createMigrationsTable(client, migrationTableName)
log("Migrations table created")

const filteredMigrations = filterMigrations(migrations, appliedMigrations)

const completedMigrations = []
Expand All @@ -80,6 +83,17 @@ async function runMigrations(dbConfig, migrationsDirectory, config) {
}
}

function createMigrationsTable(client, migrationTableName) {
return client.query(`
CREATE TABLE IF NOT EXISTS ${migrationTableName} (
id integer PRIMARY KEY,
name varchar(100) UNIQUE NOT NULL,
hash varchar(40) NOT NULL,
executed_at timestamp DEFAULT current_timestamp
);
`)
}

// Queries the database for migrations table and retrieve it rows if exists
async function fetchAppliedMigrationFromDB(migrationTableName, client, log) {
let appliedMigrations = []
Expand Down
6 changes: 0 additions & 6 deletions src/migrations/0_create-migrations-table.sql

This file was deleted.

3 changes: 3 additions & 0 deletions src/migrations/0_index-place-holder.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- This file exists so that the other migration files' orders and array index will match
-- (e.g. 1-script.sql will be the 2nd row (index 1) in the database)
-- It makes the code much simpler in a few places