Use ordered SQLite migrations (Refs #75)
CI / checks (push) Successful in 5m6s

This commit is contained in:
2026-10-10 00:01:18 -04:00
parent a0663e43b8
commit 8d1bb69591
56 changed files with 1085 additions and 736 deletions
+1 -4
View File
@@ -1,6 +1,5 @@
import { fleetSettings } from '../settings.js';
import { db } from '../db/index.js';
import { ensureHostSchema } from './schema.js';
import type {
CapacityCalibration,
CapacitySample,
@@ -25,9 +24,7 @@ interface AllowanceRow {
computed_at: string;
}
function database() {
const handle = db();
ensureHostSchema(handle);
return handle;
return db();
}
/** Read retained minute peaks without contacting agents or recalculating allowances. */
-2
View File
@@ -1,5 +1,4 @@
import { db } from '../db/index.js';
import { ensureHostSchema } from './schema.js';
import type { CapacityHistory, CapacityQuery, CapacityRange } from '../../capacity.js';
const windows: Record<CapacityRange, { duration: number; bucketMs: number }> = {
@@ -11,7 +10,6 @@ const windows: Record<CapacityRange, { duration: number; bucketMs: number }> = {
/** Read on the report worker: heartbeat history can contain millions of rows. */
export function readCapacityHistory(query: CapacityQuery, now = Date.now()): CapacityHistory {
const handle = db();
ensureHostSchema(handle);
const { duration, bucketMs } = windows[query.range];
const startAt = now - duration;
const count = duration / bucketMs;
+1 -4
View File
@@ -5,7 +5,6 @@ import { EventEmitter } from 'node:events';
import { createHash, randomBytes, randomUUID, timingSafeEqual } from 'node:crypto';
import { isIP } from 'node:net';
import { db } from '../db/index.js';
import { ensureHostSchema } from './schema.js';
import {
successfulObservation,
routineObservationSql,
@@ -60,9 +59,7 @@ export function waitForHostWork(
}
const digest = (token: string) => createHash('sha256').update(token).digest('hex');
function database() {
const handle = db();
ensureHostSchema(handle);
return handle;
return db();
}
type HostRow = {
id: string;
+1 -14
View File
@@ -7,7 +7,6 @@ import {
} from '../db/file-blobs.js';
import { retentionClocks } from '../db/retention-clocks.js';
import { installHistoryCounts } from './history-counts.js';
import { migrationStep } from '../db/connection.js';
import type Database from 'better-sqlite3';
import {
successfulObservationSql,
@@ -16,19 +15,7 @@ import {
importantOperationSql
} from './observations.js';
const initialized = new WeakSet<Database.Database>();
export function ensureHostSchema(handle: Database.Database): void {
if (initialized.has(handle)) return;
// Background readers open only after controller migrations have completed.
if (handle.readonly) {
initialized.add(handle);
return;
}
migrationStep('host schema and saved command files', () => migrateHostSchema(handle));
initialized.add(handle);
}
function migrateHostSchema(handle: Database.Database): void {
export function migrateHostSchema(handle: Database.Database): void {
ensureFileBlobSchema(handle);
handle.exec(`
CREATE TABLE IF NOT EXISTS ec_hosts (