• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

safe-global / safe-client-gateway / 9546514333

17 Jun 2024 11:01AM UTC coverage: 49.473% (-42.8%) from 92.296%
9546514333

push

github

web-flow
Add `PostgresDatabaseMigrator` for (testing) migration (#1655)

Adds a new `PostgresDatabaseMigrator` that has the core logic of `postgres-shift`, as well as a testing method. The `migrate` method mirrors `postgres-shift` and the `test` method reuses part of it, executing each migration in a separate transaction. It allows us to interact with the database _before_ and _after_ a migration has executed, stopping after the desired migration:

- Create `PostgresDatabaseMigrator` and inject it
- Remove `postgres-shift` and associated definition/patch, replacing usage with the above
- Add appropriate test coverage

394 of 2367 branches covered (16.65%)

Branch coverage included in aggregate %.

10 of 62 new or added lines in 3 files covered. (16.13%)

2191 existing lines in 221 files now uncovered.

3969 of 6452 relevant lines covered (61.52%)

12.49 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

35.29
/src/datasources/db/postgres-database.migration.hook.ts
1
import { Inject, Injectable, OnModuleInit } from '@nestjs/common';
16✔
2
import { ILoggingService, LoggingService } from '@/logging/logging.interface';
16✔
3
import postgres from 'postgres';
16✔
4
import { PostgresDatabaseMigrator } from '@/datasources/db/postgres-database.migrator';
16✔
5

6
/**
7
 * The {@link PostgresDatabaseMigrationHook} is a Module Init hook meaning
8
 * that it will be executed once the dependencies are resolved.
9
 *
10
 * This happens before the Application Bootstraps, so route listeners are not
11
 * initiated and potentially generating queries.
12
 */
13
@Injectable({})
14
export class PostgresDatabaseMigrationHook implements OnModuleInit {
16✔
15
  private static LOCK_MAGIC_NUMBER = 132;
16✔
16

17
  constructor(
UNCOV
18
    @Inject('DB_INSTANCE') private readonly sql: postgres.Sql,
×
19
    @Inject(PostgresDatabaseMigrator)
NEW
20
    private readonly migrator: PostgresDatabaseMigrator,
×
UNCOV
21
    @Inject(LoggingService) private readonly loggingService: ILoggingService,
×
22
  ) {}
23

24
  async onModuleInit(): Promise<void> {
25
    this.loggingService.info('Checking migrations');
×
26
    try {
×
27
      // Acquire lock to perform a migration.
28
      // If the lock is not acquired, then a migration is being executed by another instance.
29
      // Migrations should strive to be idempotent as they can be executed by multiple instances
30
      // on the same database.
31
      await this
×
32
        .sql`SELECT pg_advisory_lock(${PostgresDatabaseMigrationHook.LOCK_MAGIC_NUMBER})`;
33
      // Perform migration
NEW
34
      await this.migrator.migrate();
×
35
      this.loggingService.info('Pending migrations executed');
×
36
    } catch (e) {
37
      // If there's an error performing a migration, we should throw the error
38
      // and prevent the service from starting
39
      this.loggingService.error(e);
×
40
      throw e;
×
41
    } finally {
42
      // the lock should be released if the migration completed (successfully or not)
43
      await this
×
44
        .sql`SELECT pg_advisory_unlock(${PostgresDatabaseMigrationHook.LOCK_MAGIC_NUMBER})`;
45
    }
46
  }
47
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc