mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
parent
25c9b779e4
commit
4b39d37cae
19 changed files with 494 additions and 275 deletions
|
|
@ -1,31 +1,21 @@
|
|||
#!/usr/bin/env node
|
||||
import { INestApplication } from '@nestjs/common';
|
||||
import { Reflector } from '@nestjs/core';
|
||||
import { EventEmitterModule } from '@nestjs/event-emitter';
|
||||
import { SchedulerRegistry } from '@nestjs/schedule';
|
||||
import { Test } from '@nestjs/testing';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { OpenTelemetryModule } from 'nestjs-otel';
|
||||
import { mkdir, rm, writeFile } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { format } from 'sql-formatter';
|
||||
import { databaseConfig } from 'src/database.config';
|
||||
import { GENERATE_SQL_KEY, GenerateSqlQueries } from 'src/decorators';
|
||||
import { databaseEntities } from 'src/entities';
|
||||
import { ISystemConfigRepository } from 'src/interfaces/system-config.interface';
|
||||
import { entities } from 'src/entities';
|
||||
import { repositories } from 'src/repositories';
|
||||
import { AccessRepository } from 'src/repositories/access.repository';
|
||||
import { AlbumRepository } from 'src/repositories/album.repository';
|
||||
import { ApiKeyRepository } from 'src/repositories/api-key.repository';
|
||||
import { AssetRepository } from 'src/repositories/asset.repository';
|
||||
import { AuditRepository } from 'src/repositories/audit.repository';
|
||||
import { LibraryRepository } from 'src/repositories/library.repository';
|
||||
import { MoveRepository } from 'src/repositories/move.repository';
|
||||
import { PartnerRepository } from 'src/repositories/partner.repository';
|
||||
import { PersonRepository } from 'src/repositories/person.repository';
|
||||
import { SearchRepository } from 'src/repositories/search.repository';
|
||||
import { SharedLinkRepository } from 'src/repositories/shared-link.repository';
|
||||
import { SystemConfigRepository } from 'src/repositories/system-config.repository';
|
||||
import { SystemMetadataRepository } from 'src/repositories/system-metadata.repository';
|
||||
import { TagRepository } from 'src/repositories/tag.repository';
|
||||
import { UserTokenRepository } from 'src/repositories/user-token.repository';
|
||||
import { UserRepository } from 'src/repositories/user.repository';
|
||||
import { AuthService } from 'src/services/auth.service';
|
||||
import { otelConfig } from 'src/utils/instrumentation';
|
||||
import { Logger } from 'typeorm';
|
||||
|
||||
export class SqlLogger implements Logger {
|
||||
|
|
@ -52,26 +42,9 @@ export class SqlLogger implements Logger {
|
|||
}
|
||||
|
||||
const reflector = new Reflector();
|
||||
const repositories = [
|
||||
AccessRepository,
|
||||
AlbumRepository,
|
||||
ApiKeyRepository,
|
||||
AssetRepository,
|
||||
AuditRepository,
|
||||
LibraryRepository,
|
||||
MoveRepository,
|
||||
PartnerRepository,
|
||||
PersonRepository,
|
||||
SharedLinkRepository,
|
||||
SearchRepository,
|
||||
SystemConfigRepository,
|
||||
SystemMetadataRepository,
|
||||
TagRepository,
|
||||
UserTokenRepository,
|
||||
UserRepository,
|
||||
];
|
||||
|
||||
type Repository = (typeof repositories)[0];
|
||||
type Repository = (typeof repositories)[0]['useClass'];
|
||||
type Provider = { provide: any; useClass: Repository };
|
||||
type SqlGeneratorOptions = { targetDir: string };
|
||||
|
||||
class SqlGenerator {
|
||||
|
|
@ -84,8 +57,8 @@ class SqlGenerator {
|
|||
async run() {
|
||||
try {
|
||||
await this.setup();
|
||||
for (const Repository of repositories) {
|
||||
await this.process(Repository);
|
||||
for (const repository of repositories) {
|
||||
await this.process(repository);
|
||||
}
|
||||
await this.write();
|
||||
this.stats();
|
||||
|
|
@ -102,25 +75,27 @@ class SqlGenerator {
|
|||
imports: [
|
||||
TypeOrmModule.forRoot({
|
||||
...databaseConfig,
|
||||
entities: databaseEntities,
|
||||
entities,
|
||||
logging: ['query'],
|
||||
logger: this.sqlLogger,
|
||||
}),
|
||||
TypeOrmModule.forFeature(databaseEntities),
|
||||
TypeOrmModule.forFeature(entities),
|
||||
EventEmitterModule.forRoot(),
|
||||
OpenTelemetryModule.forRoot(otelConfig),
|
||||
],
|
||||
providers: [{ provide: ISystemConfigRepository, useClass: SystemConfigRepository }, ...repositories],
|
||||
providers: [...repositories, AuthService, SchedulerRegistry],
|
||||
}).compile();
|
||||
|
||||
this.app = await moduleFixture.createNestApplication().init();
|
||||
}
|
||||
|
||||
async process(Repository: Repository) {
|
||||
async process({ provide: token, useClass: Repository }: Provider) {
|
||||
if (!this.app) {
|
||||
throw new Error('Not initialized');
|
||||
}
|
||||
|
||||
const data: string[] = [`-- NOTE: This file is auto generated by ./sql-generator`];
|
||||
const instance = this.app.get<Repository>(Repository);
|
||||
const instance = this.app.get<Repository>(token);
|
||||
|
||||
// normal repositories
|
||||
data.push(...(await this.runTargets(instance, `${Repository.name}`)));
|
||||
|
|
@ -180,6 +155,10 @@ class SqlGenerator {
|
|||
|
||||
private async write() {
|
||||
for (const [repoName, data] of Object.entries(this.results)) {
|
||||
// only contains the header
|
||||
if (data.length === 1) {
|
||||
continue;
|
||||
}
|
||||
const filename = repoName.replaceAll(/[A-Z]/g, (letter) => `.${letter.toLowerCase()}`).replace('.', '');
|
||||
const file = join(this.options.targetDir, `${filename}.sql`);
|
||||
await writeFile(file, data.join('\n\n') + '\n');
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue