-
-
Notifications
You must be signed in to change notification settings - Fork 497
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(mongo): add support for migrations in mongo driver
Adds new `@mikro-orm/migrations-mongodb` package that needs to be explicitly installed. Current CLI commands will work with it transparently. Mongo migrations have some limitations: - no nested transaction support - no schema diffing - only blank migrations are generated - use `this.driver` or `this.getCollection()` to manipulate with the database Closes #295
- Loading branch information
Showing
29 changed files
with
1,036 additions
and
32 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
node_modules | ||
src | ||
tests | ||
coverage | ||
temp | ||
yarn-error.log | ||
data | ||
tsconfig.* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
{ | ||
"name": "@mikro-orm/migrations-mongodb", | ||
"version": "5.2.4", | ||
"description": "TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, PostgreSQL and SQLite databases as well as usage with vanilla JavaScript.", | ||
"main": "dist/index.js", | ||
"module": "dist/index.mjs", | ||
"typings": "dist/index.d.ts", | ||
"exports": { | ||
"./package.json": "./package.json", | ||
".": { | ||
"import": { | ||
"types": "./dist/index.d.ts", | ||
"default": "./dist/index.mjs" | ||
}, | ||
"require": "./dist/index.js" | ||
} | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+ssh://git@github.com/mikro-orm/mikro-orm.git" | ||
}, | ||
"keywords": [ | ||
"orm", | ||
"mongo", | ||
"mongodb", | ||
"mysql", | ||
"mariadb", | ||
"postgresql", | ||
"sqlite", | ||
"sqlite3", | ||
"ts", | ||
"typescript", | ||
"js", | ||
"javascript", | ||
"entity", | ||
"ddd", | ||
"mikro-orm", | ||
"unit-of-work", | ||
"data-mapper", | ||
"identity-map" | ||
], | ||
"author": "Martin Adámek", | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/mikro-orm/mikro-orm/issues" | ||
}, | ||
"homepage": "https://mikro-orm.io", | ||
"engines": { | ||
"node": ">= 14.0.0" | ||
}, | ||
"scripts": { | ||
"build": "yarn clean && yarn compile && yarn copy", | ||
"postbuild": "yarn gen-esm-wrapper dist/index.js dist/index.mjs", | ||
"clean": "rimraf ./dist", | ||
"compile": "tsc -p tsconfig.build.json", | ||
"copy": "ts-node -T ../../scripts/copy.ts" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"@mikro-orm/mongodb": "^5.2.4", | ||
"fs-extra": "10.1.0", | ||
"mongodb": "^4.8.1", | ||
"umzug": "3.1.1" | ||
}, | ||
"devDependencies": { | ||
"@mikro-orm/core": "^5.2.4" | ||
}, | ||
"peerDependencies": { | ||
"@mikro-orm/core": "^5.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { MigrationGenerator } from './MigrationGenerator'; | ||
|
||
export class JSMigrationGenerator extends MigrationGenerator { | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
generateMigrationFile(className: string, diff: { up: string[]; down: string[] }): string { | ||
let ret = `'use strict';\n`; | ||
ret += `Object.defineProperty(exports, '__esModule', { value: true });\n`; | ||
ret += `const { Migration } = require('@mikro-orm/migrations-mongodb');\n\n`; | ||
ret += `class ${className} extends Migration {\n\n`; | ||
ret += ` async up() {\n`; | ||
/* istanbul ignore next */ | ||
diff.up.forEach(sql => ret += this.createStatement(sql, 4)); | ||
ret += ` }\n\n`; | ||
|
||
/* istanbul ignore next */ | ||
if (diff.down.length > 0) { | ||
ret += ` async down() {\n`; | ||
diff.down.forEach(sql => ret += this.createStatement(sql, 4)); | ||
ret += ` }\n\n`; | ||
} | ||
|
||
ret += `}\n`; | ||
ret += `exports.${className} = ${className};\n`; | ||
|
||
return ret; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import type { Configuration, Transaction, EntityName } from '@mikro-orm/core'; | ||
import type { MongoDriver } from '@mikro-orm/mongodb'; | ||
import type { Collection } from 'mongodb'; | ||
|
||
export abstract class Migration { | ||
|
||
protected ctx?: Transaction; | ||
|
||
constructor(protected readonly driver: MongoDriver, | ||
protected readonly config: Configuration) { } | ||
|
||
abstract up(): Promise<void>; | ||
|
||
async down(): Promise<void> { | ||
throw new Error('This migration cannot be reverted'); | ||
} | ||
|
||
isTransactional(): boolean { | ||
return true; | ||
} | ||
|
||
reset(): void { | ||
this.ctx = undefined; | ||
} | ||
|
||
setTransactionContext(ctx: Transaction): void { | ||
this.ctx = ctx; | ||
} | ||
|
||
getCollection(entityName: EntityName<any>): Collection { | ||
return this.driver.getConnection().getCollection(entityName); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { ensureDir, writeFile } from 'fs-extra'; | ||
import type { IMigrationGenerator, MigrationsOptions, NamingStrategy } from '@mikro-orm/core'; | ||
import { Utils } from '@mikro-orm/core'; | ||
import type { MongoDriver } from '@mikro-orm/mongodb'; | ||
|
||
/* istanbul ignore next */ | ||
export abstract class MigrationGenerator implements IMigrationGenerator { | ||
|
||
constructor(protected readonly driver: MongoDriver, | ||
protected readonly namingStrategy: NamingStrategy, | ||
protected readonly options: MigrationsOptions) { } | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
async generate(diff: { up: string[]; down: string[] }, path?: string): Promise<[string, string]> { | ||
/* istanbul ignore next */ | ||
const defaultPath = this.options.emit === 'ts' && this.options.pathTs ? this.options.pathTs : this.options.path!; | ||
path = Utils.normalizePath(this.driver.config.get('baseDir'), path ?? defaultPath); | ||
await ensureDir(path); | ||
const timestamp = new Date().toISOString().replace(/[-T:]|\.\d{3}z$/ig, ''); | ||
const className = this.namingStrategy.classToMigrationName(timestamp); | ||
const fileName = `${this.options.fileName!(timestamp)}.${this.options.emit}`; | ||
const ret = this.generateMigrationFile(className, diff); | ||
await writeFile(path + '/' + fileName, ret); | ||
|
||
return [ret, fileName]; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
createStatement(query: string, padLeft: number): string { | ||
if (query) { | ||
const padding = ' '.repeat(padLeft); | ||
return `${padding}console.log('${query}');\n`; | ||
} | ||
|
||
return '\n'; | ||
} | ||
|
||
/** | ||
* @inheritDoc | ||
*/ | ||
abstract generateMigrationFile(className: string, diff: { up: string[]; down: string[] }): string; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import type { MigrationsOptions, Transaction } from '@mikro-orm/core'; | ||
import type { MongoDriver } from '@mikro-orm/mongodb'; | ||
import type { Migration } from './Migration'; | ||
|
||
export class MigrationRunner { | ||
|
||
private readonly connection = this.driver.getConnection(); | ||
private masterTransaction?: Transaction; | ||
|
||
constructor(protected readonly driver: MongoDriver, | ||
protected readonly options: MigrationsOptions) { } | ||
|
||
async run(migration: Migration, method: 'up' | 'down'): Promise<void> { | ||
migration.reset(); | ||
|
||
if (!this.options.transactional || !migration.isTransactional()) { | ||
await migration[method](); | ||
} else if (this.masterTransaction) { | ||
migration.setTransactionContext(this.masterTransaction); | ||
await migration[method](); | ||
} else { | ||
await this.connection.transactional(async tx => { | ||
migration.setTransactionContext(tx); | ||
await migration[method](); | ||
}, { ctx: this.masterTransaction }); | ||
} | ||
} | ||
|
||
setMasterMigration(trx: Transaction) { | ||
this.masterTransaction = trx; | ||
} | ||
|
||
unsetMasterMigration() { | ||
delete this.masterTransaction; | ||
} | ||
|
||
} |
Oops, something went wrong.