Files
EvoFirewall/packages/db/src/client.ts
T
DenozordecandCursor ebadf70e2b
Build and Push EvoFirewall Docker Image / build-and-push (push) Failing after 25s
Build and Push EvoFirewall Docker Image / create-release (push) Skipped
feat: реализовать EvoFirewall V1 control plane
API, UI, Linux/MikroTik agents, IP lists, политики, stats, CI и интеграция с auth-portal/EvoBGP.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-20 19:50:54 +07:00

74 lines
2.1 KiB
TypeScript

import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { readFileSync, readdirSync, mkdirSync } from 'node:fs'
import Database from 'better-sqlite3'
import { drizzle } from 'drizzle-orm/better-sqlite3'
import { schema } from './schema.js'
export type Sqlite = Database.Database
export type Db = ReturnType<typeof drizzle<typeof schema>>
const __dirname = dirname(fileURLToPath(import.meta.url))
export function resolveDatabasePath(databaseUrl: string): string {
const url = databaseUrl.startsWith('sqlite:')
? databaseUrl.slice('sqlite:'.length)
: databaseUrl
return url
}
export function createDb(databaseUrl: string): { db: Db; sqlite: Sqlite } {
const path = resolveDatabasePath(databaseUrl)
const dir = dirname(path)
if (dir && dir !== '.') {
try {
mkdirSync(dir, { recursive: true })
} catch {
/* exists */
}
}
const sqlite = new Database(path)
sqlite.pragma('journal_mode = WAL')
sqlite.pragma('synchronous = NORMAL')
sqlite.pragma('foreign_keys = ON')
const db = drizzle(sqlite, { schema })
return { db, sqlite }
}
export function createMemoryDb(): { db: Db; sqlite: Sqlite } {
const sqlite = new Database(':memory:')
sqlite.pragma('foreign_keys = ON')
const db = drizzle(sqlite, { schema })
return { db, sqlite }
}
export function runMigrations(sqlite: Sqlite): void {
const migrationsDir = join(__dirname, '..', 'migrations')
const files = readdirSync(migrationsDir)
.filter((f) => f.endsWith('.sql'))
.sort()
sqlite.exec(
`CREATE TABLE IF NOT EXISTS _migrations (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
applied_at TEXT NOT NULL DEFAULT (datetime('now'))
)`,
)
for (const file of files) {
const applied = sqlite
.prepare('SELECT 1 FROM _migrations WHERE name = ?')
.get(file)
if (applied) continue
const sql = readFileSync(join(migrationsDir, file), 'utf-8')
sqlite.exec(sql)
sqlite.prepare('INSERT INTO _migrations (name) VALUES (?)').run(file)
}
}
export function healthCheck(sqlite: Sqlite): void {
sqlite.prepare('SELECT 1').get()
}