fix: update

Signed-off-by: Avior <git@avior.me>
This commit is contained in:
2024-10-09 17:47:31 +02:00
parent 7fa18d682d
commit e38bc9b0b2
69 changed files with 3482 additions and 2071 deletions

141
src/models/Clients/index.ts Normal file
View File

@ -0,0 +1,141 @@
import config from 'models/config'
import type MigrationObj from 'models/Migrations'
export enum ConnectionStatus {
DISCONNECTED,
MIGRATING,
READY
}
export interface ClientStatic<C extends Client = Client> {
get(): Promise<C>
}
export default abstract class Client {
public status: ConnectionStatus = ConnectionStatus.DISCONNECTED
/**
* -1: unknown
* 0: migrating
* 1: migrated
*/
public migrationStatus = -1
/**
* get the current migration version
*
* -1 nothing/error
* 0+ current migration
*/
public abstract getVersion(): Promise<number>
public abstract setVersion(version: number): Promise<void>
public abstract execute(query: string, params?: Array<unknown> | object, ...options: Array<any>): Promise<Array<Record<string, unknown>>>
public abstract connect(): Promise<void>
/**
* Migrate the database to the latest version
*/
public async migrateToLatest() {
const migrations = this.getMigrations()
const latest = migrations[migrations.length - 1]
if (!latest) {
return
}
return await this.migrateTo(latest.date)
}
public getMigrations(): ReadonlyArray<MigrationObj> {
return config.migrations as ReadonlyArray<MigrationObj>
}
/**
* migrate to a specific date in time
* @param newVersion the date to try to migrate to
*/
public async migrateTo(newVersion: number) {
if (this.migrationStatus === 0) {
return
}
this.migrationStatus = 0
let currentVersion = await this.getVersion() ?? -1
const migrations = this.getMigrations()
// same version, don't to anything
if (newVersion === currentVersion) {
this.migrationStatus = 1
return
}
console.log('\x1b[35mCurrent DB version', currentVersion, '\x1b[0m')
// run up migrations
if (currentVersion < newVersion) {
console.log('\x1b[35m', 'Migrating up to', newVersion, '\x1b[0m')
const migrationsToRun = migrations.filter((it) => it.date > currentVersion && it.date <= newVersion)
for (const migration of migrationsToRun) {
console.log('\x1b[35m', 'Migrating from', currentVersion, 'to', migration.date, '\x1b[0m')
await migration.up(this)
await this.setVersion(migration.date)
currentVersion = migration.date
}
} else if (currentVersion > newVersion) { // run down migrations
console.log('\x1b[35m', 'Migrating down to', newVersion, '\x1b[0m')
const migrationsToRun = migrations.filter((it) => it.date < currentVersion && it.date >= newVersion)
.toReversed()
for (const migration of migrationsToRun) {
console.log('\x1b[35m', 'Migrating from', currentVersion, 'to', migration.date, '\x1b[0m')
await migration.down?.(this)
await this.setVersion(migration.date)
currentVersion = migration.date
}
}
console.log('\x1b[32mDone migrating\x1b[0m')
this.migrationStatus = 1
}
// public getStatus(): Promise<ClientStatus>
// public abstract isMigrated(): Promise<boolean>
/**
* indicate if the client is ready for new requests (not if migrations are done or not)
*/
public abstract isReady(): Promise<boolean>
/**
* wait until every migrations are done or fail
*/
public async waitForMigrations(): Promise<void> {
if (this.migrationStatus === -1) {
await this.migrateToLatest()
}
while (!await this.isMigrated()) {
console.log('waiting...')
await new Promise((res) => setTimeout(res, 100))
}
}
public isMigrating(): boolean {
return this.migrationStatus === 0
}
public async isMigrated(): Promise<boolean> {
return this.migrationStatus === 1
// if (this.migrationStatus < 1) {
// return false
// } else if (this.migrationStatus === 1) {
// return
// }
// const migrations = this.getMigrations()
// const last = migrations[migrations.length - 1]
// if (!last) {
// return true
// }
// return last.date === await this.getVersion()
}
}