2022-01-24 23:48:59 +13:00
|
|
|
const { DEFAULT_TENANT_ID } = require("../constants")
|
2021-10-27 00:40:30 +13:00
|
|
|
const { DocumentTypes } = require("../db/constants")
|
2022-01-24 23:48:59 +13:00
|
|
|
const { getAllApps } = require("../db/utils")
|
|
|
|
const environment = require("../environment")
|
|
|
|
const { doInTenant, getTenantIds, getGlobalDBName } = require("../tenancy")
|
2021-10-27 00:40:30 +13:00
|
|
|
|
2022-01-24 23:48:59 +13:00
|
|
|
exports.MIGRATION_TYPES = {
|
|
|
|
GLOBAL: "global", // run once, recorded in global db, global db is provided as an argument
|
|
|
|
APP: "app", // run per app, recorded in each app db, app db is provided as an argument
|
2021-10-27 00:40:30 +13:00
|
|
|
}
|
|
|
|
|
2021-10-27 03:47:36 +13:00
|
|
|
exports.getMigrationsDoc = async db => {
|
2021-10-27 00:40:30 +13:00
|
|
|
// get the migrations doc
|
|
|
|
try {
|
|
|
|
return await db.get(DocumentTypes.MIGRATIONS)
|
|
|
|
} catch (err) {
|
|
|
|
if (err.status && err.status === 404) {
|
|
|
|
return { _id: DocumentTypes.MIGRATIONS }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-01-24 23:48:59 +13:00
|
|
|
const runMigration = async (tenantId, CouchDB, migration, options = {}) => {
|
|
|
|
const migrationType = migration.type
|
|
|
|
const migrationName = migration.name
|
|
|
|
|
|
|
|
// get the db to store the migration in
|
|
|
|
let dbNames
|
|
|
|
if (migrationType === exports.MIGRATION_TYPES.GLOBAL) {
|
|
|
|
dbNames = [getGlobalDBName(tenantId)]
|
|
|
|
} else if (migrationType === exports.MIGRATION_TYPES.APP) {
|
|
|
|
dbNames = await getAllApps(CouchDB, { all: true })
|
|
|
|
} else {
|
|
|
|
throw new Error(
|
|
|
|
`[Tenant: ${tenantId}] Unrecognised migration type [${migrationType}]`
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
// run the migration against each db
|
|
|
|
for (const dbName of dbNames) {
|
|
|
|
const db = new CouchDB(dbName)
|
|
|
|
try {
|
|
|
|
const doc = await exports.getMigrationsDoc(db)
|
2021-10-27 03:47:36 +13:00
|
|
|
|
2022-01-24 23:48:59 +13:00
|
|
|
// exit if the migration has been performed already
|
|
|
|
if (doc[migrationName]) {
|
|
|
|
if (
|
|
|
|
options.force &&
|
|
|
|
options.force[migrationType] &&
|
|
|
|
options.force[migrationType].includes(migrationName)
|
|
|
|
) {
|
|
|
|
console.log(
|
|
|
|
`[Tenant: ${tenantId}] Forcing migration [${migrationName}]`
|
|
|
|
)
|
|
|
|
} else {
|
|
|
|
// the migration has already been performed
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
console.log(
|
|
|
|
`[Tenant: ${tenantId}] Performing migration: ${migrationName}`
|
2021-10-27 03:47:36 +13:00
|
|
|
)
|
2022-01-24 23:48:59 +13:00
|
|
|
// run the migration with tenant context
|
|
|
|
await doInTenant(tenantId, () => migration.fn(db))
|
|
|
|
console.log(`[Tenant: ${tenantId}] Migration complete: ${migrationName}`)
|
2021-10-27 00:40:30 +13:00
|
|
|
|
2022-01-24 23:48:59 +13:00
|
|
|
// mark as complete
|
|
|
|
doc[migrationName] = Date.now()
|
|
|
|
await db.put(doc)
|
|
|
|
} catch (err) {
|
|
|
|
console.error(
|
|
|
|
`[Tenant: ${tenantId}] Error performing migration: ${migrationName} on db: ${db.name}: `,
|
|
|
|
err
|
|
|
|
)
|
|
|
|
throw err
|
2021-10-27 00:40:30 +13:00
|
|
|
}
|
2022-01-24 23:48:59 +13:00
|
|
|
}
|
|
|
|
}
|
2021-10-27 00:40:30 +13:00
|
|
|
|
2022-01-24 23:48:59 +13:00
|
|
|
exports.runMigrations = async (CouchDB, migrations, options = {}) => {
|
|
|
|
console.log("Running migrations")
|
|
|
|
let tenantIds
|
|
|
|
if (environment.MULTI_TENANCY) {
|
|
|
|
if (!options.tenantIds || !options.tenantIds.length) {
|
|
|
|
// run for all tenants
|
|
|
|
tenantIds = await getTenantIds()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// single tenancy
|
|
|
|
tenantIds = [DEFAULT_TENANT_ID]
|
|
|
|
}
|
2021-10-27 00:40:30 +13:00
|
|
|
|
2022-01-24 23:48:59 +13:00
|
|
|
// for all tenants
|
|
|
|
for (const tenantId of tenantIds) {
|
|
|
|
// for all migrations
|
|
|
|
for (const migration of migrations) {
|
|
|
|
// run the migration
|
|
|
|
await runMigration(tenantId, CouchDB, migration, options)
|
|
|
|
}
|
2021-10-27 00:40:30 +13:00
|
|
|
}
|
2022-01-24 23:48:59 +13:00
|
|
|
console.log("Migrations complete")
|
2021-10-27 00:40:30 +13:00
|
|
|
}
|