Packages 包@downcity/city

Database Adapter

使用统一 Database 基类连接 SQLite、Cloudflare D1 或 PostgreSQL。

Federation 不接收裸 Drizzle db。它接收一个继承自 @downcity/cityDatabase 实例,由 Adapter 统一拥有 Driver、事务、DDL 与连接生命周期。

SQLite

pnpm add @downcity/city @downcity/database-sqlite
import { Federation } from "@downcity/city";
import { Database } from "@downcity/database-sqlite";

const database = new Database({ filename: "./federation.sqlite" });
const federation = new Federation({ database });

本地测试可使用 filename: ":memory:"。文件数据库默认启用 WAL。

Cloudflare D1

pnpm add @downcity/city @downcity/database-d1
import { Federation } from "@downcity/city";
import { Database } from "@downcity/database-d1";

export interface Env {
  DB: D1Database;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const database = new Database({ binding: env.DB });
    const federation = new Federation({ database });
    await federation.health();
    return federation.fetch(request);
  },
};

D1 Adapter 使用读取快照、冲突重试和原子 batch() 提供与其他运行时一致的 context.transaction()。事务内后续读取可以看到尚未提交的插入、更新和删除。

PostgreSQL

pnpm add @downcity/city @downcity/database-postgresql
import { Federation } from "@downcity/city";
import { Database } from "@downcity/database-postgresql";

const database = new Database({ url: process.env.DATABASE_URL! });
const federation = new Federation({ database });

PostgreSQL Adapter 使用 postgres-js 与 Drizzle 原生事务。

Service 看到什么

普通 Service 通过 context.table()context.transaction() 访问数据库。需要参数化 SQL 的官方 Service 只能使用受限的 context.database.query() / atomic();不会拿到 D1 binding、better-sqlite3 connection 或 postgres-js client。

生命周期

Federation 拥有传入的 Database。服务关闭时调用:

await federation.dispose();

Adapter 会幂等释放自己拥有的连接;释放后的数据库操作会失败。