| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- export * as Database from "./database"
- import { EffectDrizzleSqlite } from "@opencode-ai/effect-drizzle-sqlite"
- import { layer } from "#sqlite"
- import { Context, Effect, Layer } from "effect"
- import { Global } from "../global"
- import { Flag } from "../flag/flag"
- import { isAbsolute, join } from "path"
- import { DatabaseMigration } from "./migration"
- import { InstallationChannel } from "../installation/version"
- import { makeGlobalNode } from "../effect/app-node"
- const makeDatabase = EffectDrizzleSqlite.makeWithDefaults()
- type DatabaseShape = Effect.Success<typeof makeDatabase>
- export interface Interface {
- db: DatabaseShape
- }
- export class Service extends Context.Service<Service, Interface>()("@opencode/v2/storage/Database") {}
- const databaseLayer = Layer.effect(
- Service,
- Effect.gen(function* () {
- const db = yield* makeDatabase
- yield* db.run("PRAGMA journal_mode = WAL")
- yield* db.run("PRAGMA synchronous = NORMAL")
- yield* db.run("PRAGMA busy_timeout = 5000")
- yield* db.run("PRAGMA cache_size = -64000")
- yield* db.run("PRAGMA foreign_keys = ON")
- yield* db.run("PRAGMA wal_checkpoint(PASSIVE)")
- yield* DatabaseMigration.apply(db)
- return { db }
- }).pipe(Effect.orDie),
- )
- export function layerFromPath(filename: string) {
- return databaseLayer.pipe(Layer.provide(layer({ filename })))
- }
- export function path() {
- if (Flag.OPENCODE_DB) {
- if (Flag.OPENCODE_DB === ":memory:" || isAbsolute(Flag.OPENCODE_DB)) return Flag.OPENCODE_DB
- return join(Global.Path.data, Flag.OPENCODE_DB)
- }
- if (
- ["latest", "beta", "prod"].includes(InstallationChannel) ||
- process.env.OPENCODE_DISABLE_CHANNEL_DB === "1" ||
- process.env.OPENCODE_DISABLE_CHANNEL_DB === "true"
- )
- return join(Global.Path.data, "opencode.db")
- return join(Global.Path.data, `opencode-${InstallationChannel.replace(/[^a-zA-Z0-9._-]/g, "-")}.db`)
- }
- // Resolve the database path lazily so tests and embedders that set
- // Flag.OPENCODE_DB after module evaluation still control the storage target.
- export const node = makeGlobalNode({
- service: Service,
- layer: Layer.suspend(() => layerFromPath(path())),
- deps: [],
- })
|