Docker images / prepare-release (push) Successful in 10s
Docker images / backend-test (push) Successful in 2m2s
Docker images / frontend-image (push) Successful in 3m23s
Docker images / updater-image (push) Successful in 44s
Docker images / backend-image (push) Successful in 2m47s
Docker images / notify-webhook (push) Skipped
Docker images / publish-release (push) Successful in 11s
При первом рестарте wipe всех таблиц и импорт из SQLite в компактную схему. Retention через DROP PARTITION, lz4 и AIO worker. Co-authored-by: Cursor <cursoragent@cursor.com>
55 lines
1.6 KiB
TypeScript
55 lines
1.6 KiB
TypeScript
import { readdirSync, readFileSync } from "node:fs"
|
|
import { dirname, join } from "node:path"
|
|
import { fileURLToPath } from "node:url"
|
|
import type { Pool } from "pg"
|
|
|
|
const FIRST_MIGRATION = "0000_postgresql.sql"
|
|
|
|
function migrationsDir(): string {
|
|
const here = dirname(fileURLToPath(import.meta.url))
|
|
const candidates = [
|
|
join(here, "..", "..", "drizzle"),
|
|
join(process.cwd(), "drizzle"),
|
|
join(process.cwd(), "backend", "drizzle"),
|
|
]
|
|
for (const dir of candidates) {
|
|
try {
|
|
readFileSync(join(dir, FIRST_MIGRATION), "utf8")
|
|
return dir
|
|
} catch {
|
|
/* try next */
|
|
}
|
|
}
|
|
throw new Error("Не найден backend/drizzle/0000_postgresql.sql")
|
|
}
|
|
|
|
function migrationId(file: string): string {
|
|
return file.replace(/\.sql$/i, "")
|
|
}
|
|
|
|
export async function applySqlMigrations(pool: Pool): Promise<void> {
|
|
await pool.query(`
|
|
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
id TEXT PRIMARY KEY,
|
|
applied_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
)
|
|
`)
|
|
const dir = migrationsDir()
|
|
const files = readdirSync(dir)
|
|
.filter((f) => /^\d{4}_.+\.sql$/i.test(f))
|
|
.sort((a, b) => a.localeCompare(b))
|
|
const applied = new Set(
|
|
(await pool.query<{ id: string }>(`SELECT id FROM schema_migrations`)).rows.map((r) => r.id),
|
|
)
|
|
for (const file of files) {
|
|
const id = migrationId(file)
|
|
if (applied.has(id)) continue
|
|
const sql = readFileSync(join(dir, file), "utf8")
|
|
await pool.query(sql)
|
|
await pool.query(
|
|
`INSERT INTO schema_migrations (id) VALUES ($1) ON CONFLICT (id) DO NOTHING`,
|
|
[id],
|
|
)
|
|
}
|
|
}
|