Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion packages/opencode/src/storage/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { readFileSync, readdirSync, existsSync } from "fs"
import type { Database as BunDatabase } from "bun:sqlite"
import { Flag } from "@opencode-ai/core/flag/flag"
import { InstallationChannel } from "@opencode-ai/core/installation/version"
import { EffectBridge } from "@/effect/bridge"
import { init } from "#db"
import { Schema } from "effect"
Expand All @@ -27,13 +28,24 @@
if (Flag.OPENCODE_DB === ":memory:" || path.isAbsolute(Flag.OPENCODE_DB)) return Flag.OPENCODE_DB
return path.join(Global.Path.data, Flag.OPENCODE_DB)
}
return path.join(Global.Path.data, "opencode.db")
// Mirror the channel-aware path that packages/core/src/database/database.ts
// uses so both systems open the same SQLite file. Pre-PR72, db.ts already
// did this via getChannelPath; losing the suffix caused ECS deployments to
// open a fresh opencode.db while the production data lived in opencode-local.db.
if (
["latest", "beta", "prod"].includes(InstallationChannel) ||
process.env["OPENCODE_DISABLE_CHANNEL_DB"] === "1" ||
process.env["OPENCODE_DISABLE_CHANNEL_DB"] === "true"
)
return path.join(Global.Path.data, "opencode.db")
const safe = InstallationChannel.replace(/[^a-zA-Z0-9._-]/g, "-")
return path.join(Global.Path.data, `opencode-${safe}.db`)
}

type Journal = { sql: string; timestamp: number; name: string }[]

// Drizzle's migrate overloads trigger expensive variance checks here; narrow to the journal overload we actually use.
const migrateFromJournal = migrate as unknown as (db: SQLiteBunDatabase, entries: Journal) => void

Check warning on line 48 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-unsafe-type-assertion)

Unsafe type assertion: type '(db: SQLiteBunDatabase<Record<string, never>, EmptyRelations>, entries: Journal) => void' is more narrow than the original type.

function applyMigrations(db: SQLiteBunDatabase, entries: Journal) {
migrateFromJournal(db, entries)
Expand All @@ -57,15 +69,15 @@
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)

const sql = dirs
.map((name) => {
const file = path.join(dir, name, "migration.sql")
if (!existsSync(file)) return
return {
sql: readFileSync(file, "utf-8"),
timestamp: time(name),
name,
}

Check warning on line 80 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(consistent-return)

Function expected no return value.
})
.filter(Boolean) as Journal

Check warning on line 82 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-unsafe-type-assertion)

Unsafe type assertion: type 'Journal' is more narrow than the original type.

Expand All @@ -81,7 +93,7 @@

export const Client = Object.assign(
(): TxOrDb => {
if (loaded) return client as TxOrDb

Check warning on line 96 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-unsafe-type-assertion)

Unsafe type assertion: type 'TxOrDb' is more narrow than the original type.

const dbPath = getPath()
log.info("opening database", { path: dbPath })
Expand Down Expand Up @@ -113,15 +125,15 @@
// which then crashes because the schema columns already exist.
// Fix: seed "__drizzle_migrations" from the legacy "migration" table
// before handing off to applyMigrations so rc.2 skips already-done work.
const hasLegacyTable = (db as unknown as TxOrDb).$client

Check warning on line 128 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-unsafe-type-assertion)

Unsafe type assertion: type 'TxOrDb' is more narrow than the original type.
.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='migration'")
.get()
if (hasLegacyTable) {
const oldRows = (db as unknown as TxOrDb).$client

Check warning on line 132 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-unsafe-type-assertion)

Unsafe type assertion: type 'TxOrDb' is more narrow than the original type.
.prepare("SELECT id FROM migration")
.all() as Array<{ id: string }>

Check warning on line 134 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-unsafe-type-assertion)

Unsafe type assertion: type '{ id: string; }[]' is more narrow than the original type.
const oldNames = new Set(oldRows.map((r) => r.id));
(db as unknown as TxOrDb).$client.exec(`

Check warning on line 136 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-unsafe-type-assertion)

Unsafe type assertion: type 'TxOrDb' is more narrow than the original type.
CREATE TABLE IF NOT EXISTS "__drizzle_migrations" (
id INTEGER PRIMARY KEY,
hash text NOT NULL,
Expand All @@ -130,7 +142,7 @@
applied_at TEXT
)
`)
const insert = (db as unknown as TxOrDb).$client.prepare(

Check warning on line 145 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-unsafe-type-assertion)

Unsafe type assertion: type 'TxOrDb' is more narrow than the original type.
`INSERT OR IGNORE INTO "__drizzle_migrations" (hash, created_at, name, applied_at) VALUES (?, ?, ?, ?)`,
)
const now = Date.now()
Expand Down Expand Up @@ -178,7 +190,7 @@
if (err instanceof LocalContext.NotFound) {
const effects: (() => void | Promise<void>)[] = []
const result = ctx.provide({ effects, tx: Client() }, () => callback(Client()))
for (const effect of effects) effect()

Check warning on line 193 in packages/opencode/src/storage/db.ts

View workflow job for this annotation

GitHub Actions / Lint changed files (oxlint)

typescript-eslint(no-floating-promises)

Promises must be awaited, add void operator to ignore.
return result
}
throw err
Expand Down
Loading