Skip to content

Commit 339275a

Browse files
committed
fix: fix db refresh not running in transaction
1 parent 1b26f12 commit 339275a

File tree

3 files changed

+34
-34
lines changed

3 files changed

+34
-34
lines changed

data/drop-schema.sql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
pragma foreign_keys = off;
22

3-
drop table if exists `users`;
4-
drop table if exists `meetups`;
53
drop table if exists `agenda_items`;
6-
drop table if exists `images`;
74
drop table if exists `participation`;
5+
drop table if exists `meetups`;
6+
drop table if exists `images`;
7+
drop table if exists `users`;
88

99
pragma foreign_keys = on;
Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import * as fs from 'fs';
22
import path from 'path';
3-
import { EntityManager } from 'mikro-orm';
3+
import { EntityManager, Transaction } from 'mikro-orm';
44
import { getDataToSeed } from './seed-data';
5+
import { InternalServerErrorException } from '@nestjs/common';
56

67
export class DatabaseManager {
78
private dropSchemaPath = path.join(__dirname, '../../data/drop-schema.sql');
@@ -18,47 +19,34 @@ export class DatabaseManager {
1819
this.createSchemaQuery = fs.readFileSync(this.createSchemaPath, 'utf-8');
1920
}
2021

21-
private async execute(em: EntityManager, sql: string) {
22+
private async execute(em: EntityManager, sql: string, ctx?: Transaction) {
2223
const lines = sql.split('\n').filter((i) => i.trim());
2324

2425
for (const line of lines) {
25-
await em.getConnection().execute(line);
26+
await em.getConnection().execute(line, [], 'run', ctx);
2627
}
2728
}
2829

29-
dropSchema(em: EntityManager): Promise<void> {
30-
return this.execute(em, this.dropSchemaQuery);
30+
dropSchema(em: EntityManager, ctx?: Transaction): Promise<void> {
31+
return this.execute(em, this.dropSchemaQuery, ctx);
3132
}
3233

3334
seed(em: EntityManager): Promise<void> {
3435
const meetups = getDataToSeed();
3536
return em.persistAndFlush(meetups);
3637
}
3738

38-
createSchema(em: EntityManager): Promise<void> {
39-
return this.execute(em, this.createSchemaQuery);
39+
createSchema(em: EntityManager, ctx?: Transaction): Promise<void> {
40+
return this.execute(em, this.createSchemaQuery, ctx);
4041
}
4142

42-
async refresh(em: EntityManager, attempt?: number): Promise<void> {
43-
// TODO: add transaction here
44-
// for some reason, thi.em.transactional fails with sqlite
45-
// Not the best solution, but it seems to work
46-
try {
47-
await this.dropSchema(em);
48-
await this.createSchema(em);
49-
await this.seed(em);
50-
} catch {
51-
if (attempt < 10) {
52-
return new Promise((resolve, reject) => {
53-
setTimeout(() => {
54-
this.refresh(em, attempt + 1)
55-
.then(resolve)
56-
.catch(reject);
57-
}, 100);
58-
});
59-
} else {
60-
throw new Error('Error on database refresh');
61-
}
62-
}
43+
async refresh(em: EntityManager) {
44+
return em.transactional(async (_em) => {
45+
const ctx: Transaction = _em.getTransactionContext();
46+
await this.dropSchema(_em, ctx);
47+
await this.createSchema(_em, ctx);
48+
await this.seed(_em);
49+
return true;
50+
});
6351
}
6452
}

src/maintenance/maintenance.service.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
import { EntityManager } from 'mikro-orm';
2-
import { Inject, Injectable } from '@nestjs/common';
2+
import {
3+
Inject,
4+
Injectable,
5+
InternalServerErrorException,
6+
Logger,
7+
} from '@nestjs/common';
38
import { ConfigService } from '@nestjs/config';
49
import { SchedulerRegistry } from '@nestjs/schedule';
510
import { CronJob } from 'cron';
611
import { DatabaseManager } from './database-manager';
712

813
@Injectable()
914
export class MaintenanceService {
15+
private readonly logger = new Logger('Maintenance');
16+
1017
constructor(
1118
private readonly em: EntityManager,
1219
private readonly schedulerRegistry: SchedulerRegistry,
@@ -29,7 +36,12 @@ export class MaintenanceService {
2936
return 'pong';
3037
}
3138

32-
dbRefresh() {
33-
return this.databaseManager.refresh(this.em);
39+
async dbRefresh() {
40+
try {
41+
await this.databaseManager.refresh(this.em);
42+
} catch (e) {
43+
this.logger.error(e.message);
44+
throw new InternalServerErrorException('Error on DB refresh');
45+
}
3446
}
3547
}

0 commit comments

Comments
 (0)