UNPKG

@webdocgroup/realm-migrations

Version:
128 lines (127 loc) 4.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RealmMigrationService = void 0; const realm_1 = __importDefault(require("realm")); const shouldRunMigrationsHook_1 = require("../HookPipelines/shouldRunMigrationsHook"); const Enabled_1 = require("../Hooks/Enabled"); class RealmMigrationService { constructor({ databaseName, migrations, hooks = {}, enabled = true, }) { this.migrations = []; this.databaseName = databaseName; this.migrations = migrations; this.hooks = hooks; this.enabled = enabled; } currentSchemaVersion() { const dbPath = `${this.databaseName}.realm`; const currentSchemaVersion = realm_1.default.schemaVersion(dbPath); return currentSchemaVersion; } latestMigrationVersion() { return this.migrations.length; } nextSchemaVersion() { const currentSchemaVersion = this.currentSchemaVersion(); const nextSchemaVersion = currentSchemaVersion + 1; if (this.migrations[nextSchemaVersion]) { return nextSchemaVersion; } return currentSchemaVersion; } shouldRun({ currentVersion, latestMigrationVersion, }) { return (0, shouldRunMigrationsHook_1.shouldRunMigrationsHook)({ props: { currentVersion, latestMigrationVersion, }, hooks: [ (0, Enabled_1.enabled)({ enabled: this.enabled }), ...(this.hooks.shouldRunMigrations ? this.hooks.shouldRunMigrations : []), ], callback: () => { return currentVersion < latestMigrationVersion; }, }); } /** * Derives the schemas for a given version by combining all migrations * up to that version. * * @param version The version to derive schemas for. * * @returns An array of schemas that represent the state of the database * at the specified version. */ derriveSchemas(version) { const migrationsForVersion = this.migrations.slice(0, version); const schemasByName = migrationsForVersion.reduce((schemasByName, migration) => { const schemasByNameInMigration = migration.schemas.reduce((acc, schema) => { return { ...acc, [schema.name]: schema }; }, {}); return { ...schemasByName, ...schemasByNameInMigration }; }, {}); return Object.values(schemasByName); } migrationsToRun() { const currentSchemaVersion = Math.max(0, this.currentSchemaVersion() - 1); return this.migrations .map((migration, index) => ({ ...migration, version: index + 1, })) .slice(currentSchemaVersion, this.migrations.length); } run() { const currentVersion = this.currentSchemaVersion(); const latestMigrationVersion = this.latestMigrationVersion(); if (!this.shouldRun({ currentVersion, latestMigrationVersion })) { console.info('No migrations to run', { currentVersion, latestMigrationVersion, }); return { schema: this.derriveSchemas(currentVersion), schemaVersion: currentVersion, }; } const migrations = this.migrationsToRun(); let latestMigratedSchemas = []; let schemaVersion = -1; console.info(`Running ${migrations.length} migrations`, { currentVersion, latestMigrationVersion, }); migrations.forEach((migration) => { console.info(`Running migration: ${migration.description}`, { migrationVersion: migration.version, schemaCount: migration.schemas.length, }); const derivedSchema = this.derriveSchemas(migration.version); console.info('Derived schemas for migration', { count: derivedSchema.length, }); const migrated = new realm_1.default({ path: `${this.databaseName}.realm`, onMigration: migration.migrate, schema: derivedSchema, schemaVersion: migration.version, }); migrated.close(); latestMigratedSchemas = derivedSchema; schemaVersion = migration.version; }); console.info('Migrations completed', { currentSchemaVersion: this.currentSchemaVersion(), }); return { schema: latestMigratedSchemas, schemaVersion, }; } } exports.RealmMigrationService = RealmMigrationService;