// --------------------------------------------------------------------------- // Postgres adapter conformance test // --------------------------------------------------------------------------- // // Runs against PGlite spun up by `scripts/test-globalsetup.ts` (same // pattern apps/cloud uses). Port 5435 so it doesn't clash with the // cloud test DB on 5434. import { Effect } from "effect"; import postgres from "postgres"; import { drizzle } from "drizzle-orm/postgres-js"; import { relations } from "drizzle-orm"; import { pgTable, text, doublePrecision, boolean, timestamp, jsonb, } from "drizzle-orm/pg-core"; import type { DBAdapter } from "@executor/storage-core"; import { conformanceSchema, runAdapterConformance, } from "@executor/storage-core/testing"; import { makePostgresAdapter } from "./index"; const url = "postgresql://postgres:postgres@127.0.0.1:5435/postgres"; // max=1 so BEGIN/COMMIT sent via `db.execute(sql.raw(...))` always hit // the same connection — postgres.js with a larger pool rejects unsafe // transaction control that isn't bound to a single reserved client. const sql = postgres(url, { max: 1, idle_timeout: 0, max_lifetime: 60, connect_timeout: 10, onnotice: () => undefined, }); // Drizzle table definitions matching conformanceSchema const source = pgTable("source", { id: text("id").primaryKey(), name: text("name"), priority: doublePrecision("priority"), enabled: boolean("enabled"), createdAt: timestamp("createdAt"), metadata: jsonb("metadata"), }); const tag = pgTable("tag", { id: text("id").primaryKey(), label: text("label"), }); const source_tag = pgTable("source_tag", { id: text("id").primaryKey(), sourceId: text("sourceId").references(() => source.id, { onDelete: "cascade" }), note: text("note"), }); const with_defaults = pgTable("with_defaults", { id: text("id").primaryKey(), name: text("name"), nickname: text("nickname"), touchedAt: timestamp("touchedAt"), }); const sourceRelations = relations(source, ({ many }) => ({ source_tag: many(source_tag), })); const sourceTagRelations = relations(source_tag, ({ one }) => ({ source: one(source, { fields: [source_tag.sourceId], references: [source.id], }), })); const conformanceTables = { source, tag, source_tag, with_defaults, sourceRelations, sourceTagRelations, }; const createConformanceTables = Effect.tryPromise({ try: async () => { await sql.unsafe( `CREATE TABLE IF NOT EXISTS "source" ( "id" TEXT PRIMARY KEY, "name" TEXT, "priority" DOUBLE PRECISION, "enabled" BOOLEAN, "createdAt" TIMESTAMPTZ, "metadata" JSONB )`, ); await sql.unsafe( `CREATE TABLE IF NOT EXISTS "tag" ( "id" TEXT PRIMARY KEY, "label" TEXT )`, ); await sql.unsafe( `CREATE TABLE IF NOT EXISTS "source_tag" ( "id" TEXT PRIMARY KEY, "sourceId" TEXT REFERENCES "source"("id") ON DELETE CASCADE, "note" TEXT )`, ); await sql.unsafe( `CREATE TABLE IF NOT EXISTS "with_defaults" ( "id" TEXT PRIMARY KEY, "name" TEXT, "nickname" TEXT, "touchedAt" TIMESTAMPTZ )`, ); }, catch: (cause) => new Error( `failed to create postgres conformance tables: ${String(cause)}`, ), }); const resetTables = Effect.gen(function* () { yield* Effect.tryPromise({ try: () => sql`DROP TABLE IF EXISTS "source", "tag", "source_tag", "with_defaults", "blob" CASCADE`.then( () => undefined, ), catch: (cause) => new Error( `failed to reset postgres conformance tables: ${String(cause)}`, ), }); yield* createConformanceTables; }); const withAdapter = ( fn: (adapter: DBAdapter) => Effect.Effect, ): Effect.Effect => Effect.gen(function* () { yield* resetTables; // eslint-disable-next-line @typescript-eslint/no-explicit-any const db = drizzle(sql, { schema: conformanceTables as any }); const adapter = makePostgresAdapter({ db, schema: conformanceSchema, }); return yield* fn(adapter); }) as Effect.Effect; runAdapterConformance("postgres", withAdapter);