Skip to content

Commit

Permalink
feat(migrations): add migrations module (#1143)
Browse files Browse the repository at this point in the history
  • Loading branch information
garrappachc authored Aug 5, 2021
1 parent ae20c34 commit 576ac21
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 2 deletions.
14 changes: 14 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
"test": "jest --watch",
"test:ci": "jest --ci --maxWorkers 4",
"test:e2e": "NODE_ENV=test jest --config e2e.jest.config.ts --forceExit --runInBand",
"release": "release-it",
"migrate": "migrate"
"release": "release-it"
},
"dependencies": {
"@hapi/joi": "17.1.1",
Expand All @@ -29,6 +28,7 @@
"@nestjs/schedule": "1.0.1",
"@nestjs/serve-static": "2.2.2",
"@nestjs/websockets": "8.0.6",
"app-root-path": "3.0.0",
"async-mutex": "0.3.1",
"cache-manager": "3.4.4",
"class-transformer": "0.4.0",
Expand Down
2 changes: 2 additions & 0 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { PluginsModule } from './plugins/plugins.module';
import { LogReceiverModule } from './log-receiver/log-receiver.module';
import { createMongoDbUri } from './utils/create-mongo-db-uri';
import { MongooseModule } from '@nestjs/mongoose';
import { MigrationsModule } from './migrations/migrations.module';

@Module({
imports: [
Expand Down Expand Up @@ -69,6 +70,7 @@ import { MongooseModule } from '@nestjs/mongoose';
ConfigurationModule,
PluginsModule.configure(),
LogReceiverModule,
MigrationsModule,
],
controllers: [AppController],
providers: [AppService],
Expand Down
11 changes: 11 additions & 0 deletions src/migrations/migration.store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// https://github.com/tj/node-migrate/blob/main/examples/custom-state-storage/mongo-state-storage.js

interface MigrationSet {
lastRun: string;
migrations: any[];
}

export interface MigrationStore {
load: (callback: (error: any, data: MigrationSet) => any) => any;
save: (set: MigrationSet, callback: (error: any, result: any) => any) => any;
}
17 changes: 17 additions & 0 deletions src/migrations/migrations.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Module } from '@nestjs/common';
import { getConnectionToken } from '@nestjs/mongoose';
import { Connection } from 'mongoose';
import { MigrationsService } from './services/migrations.service';
import { MongoDbStore } from './stores/mongo-db.store';

@Module({
providers: [
{
provide: 'MIGRATION_STORE',
inject: [getConnectionToken()],
useFactory: (connection: Connection) => new MongoDbStore(connection),
},
MigrationsService,
],
})
export class MigrationsModule {}
48 changes: 48 additions & 0 deletions src/migrations/services/migrations.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {
Inject,
Injectable,
Logger,
OnApplicationBootstrap,
} from '@nestjs/common';
import { MigrationStore } from '../migration.store';
import { load } from 'migrate';
import { resolve as pathResolve } from 'path';
import * as appRoot from 'app-root-path';

@Injectable()
export class MigrationsService implements OnApplicationBootstrap {
private logger = new Logger(MigrationsService.name);

constructor(
@Inject('MIGRATION_STORE') private migrationStore: MigrationStore,
) {}

async onApplicationBootstrap() {
this.logger.log('running migrations...');
await this.runMigrations();
this.logger.log('migrations run successfully');
}

private async runMigrations() {
return new Promise<void>((resolve, reject) => {
load(
{
stateStore: this.migrationStore,
migrationsDirectory: pathResolve(appRoot.toString(), 'migrations'),
},
(error, set) => {
if (error) {
return reject(error);
}

set.up((error) => {
if (error) {
return reject(error);
}
resolve();
});
},
);
});
}
}
30 changes: 30 additions & 0 deletions src/migrations/stores/mongo-db.store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Connection } from 'mongoose';
import { MigrationStore } from '../migration.store';

export class MongoDbStore implements MigrationStore {
constructor(private connection: Connection) {}

async load(callback) {
const data = await this.connection.db.collection('migrations').findOne({});
return callback(null, data ?? {});
}

async save(data, callback) {
const result = await this.connection.db.collection('migrations').updateOne(
{},
{
$set: {
lastRun: data.lastRun,
},
$push: {
migrations: { $each: data.migrations },
},
},
{
upsert: true,
},
);

return callback(null, result);
}
}

0 comments on commit 576ac21

Please sign in to comment.