History

kill sqlite

Rhys Sullivan committed 8 months ago

Commit a5d22a21 parent 41edbe819 files · +408 −2090Browse files

Unified · Split

19 files
  1. apps/pm/src/approval-runtime.e2e.test.ts +1 −1
  2. apps/pm/src/execute.e2e.test.ts +4 −4
  3. apps/pm/src/main.ts +3 −3
  4. apps/web/README.md +4 −4
  5. apps/web/lib/control-plane/server.ts +4 −4
  6. bun.lock +3 −0
  7. packages/persistence-sql/drizzle.config.pg.ts +0 −14
  8. packages/persistence-sql/drizzle.config.ts +5 −3
  9. packages/persistence-sql/drizzle/0000_colorful_mentallo.sql +0 −0
  10. packages/persistence-sql/drizzle/meta/0000_snapshot.json +1 −1
  11. packages/persistence-sql/drizzle/meta/_journal.json +2 −2
  12. packages/persistence-sql/drizzle/sqlite/0000_curved_raider.sql +0 −224
  13. packages/persistence-sql/drizzle/sqlite/meta/0000_snapshot.json +0 −1437
  14. packages/persistence-sql/drizzle/sqlite/meta/_journal.json +0 −13
  15. packages/persistence-sql/package.json +1 −3
  16. packages/persistence-sql/src/index.ts +7 −7
  17. packages/persistence-sql/src/schema-pg.ts +0 −304
  18. packages/persistence-sql/src/schema.ts +67 −66
  19. packages/persistence-sql/src/sql-internals.ts +306 −0
apps/pm/src/approval-runtime.e2e.test.ts+1−1
@@ -153,7 +153,7 @@ const setupApprovalRuntimeHarness = (runId: string) => · 152 unmodified lines
153153
154154 const persistence = yield* Effect.acquireRelease(
155155 makeSqlControlPlanePersistence({
156− sqlitePath: path.resolve(stateDir, "control-plane.sqlite"),
156+ localDataDir: path.resolve(stateDir, "control-plane-pgdata"),
157157 }),
158158 (resource) => Effect.promise(() => resource.close()).pipe(Effect.orDie),
159159 );
apps/pm/src/execute.e2e.test.ts+4−4
@@ -95,7 +95,7 @@ const withStateDir = Effect.acquireRelease( · 94 unmodified lines
9595 ),
9696 );
9797
98−const withPmProcess = (port: number, sqlitePath: string) =>
98+const withPmProcess = (port: number, localDataDir: string) =>
9999 Effect.acquireRelease(
100100 Effect.sync(() =>
101101 spawn("bun", ["src/main.ts"], {
@@ -103,7 +103,7 @@ const withPmProcess = (port: number, sqlitePath: string) => · 1 unmodified line
103103 env: {
104104 ...process.env,
105105 PORT: String(port),
106− PM_CONTROL_PLANE_SQLITE_PATH: sqlitePath,
106+ PM_CONTROL_PLANE_DATA_DIR: localDataDir,
107107 },
108108 stdio: "pipe",
109109 }),
@@ -153,9 +153,9 @@ describe("PM execute E2E", () => { · 43 unmodified lines
153153 Effect.gen(function* () {
154154 const port = yield* findFreePort;
155155 const stateDir = yield* withStateDir;
156− const sqlitePath = path.resolve(stateDir, "control-plane.sqlite");
156+ const localDataDir = path.resolve(stateDir, "control-plane-pgdata");
157157
158− yield* withPmProcess(port, sqlitePath);
158+ yield* withPmProcess(port, localDataDir);
159159 yield* waitForHealth(port);
160160
161161 const { client } = yield* withMcpClient(port);
apps/pm/src/main.ts+3−3
@@ -179,9 +179,9 @@ const defaultRuntimeKind = · 178 unmodified lines
179179 const persistence: SqlControlPlanePersistence = await Effect.runPromise(
180180 makeSqlControlPlanePersistence({
181181 databaseUrl: process.env.PM_CONTROL_PLANE_DATABASE_URL,
182− sqlitePath:
183− process.env.PM_CONTROL_PLANE_SQLITE_PATH
184− ?? path.resolve(pmStateRootDir, "control-plane.sqlite"),
182+ localDataDir:
183+ process.env.PM_CONTROL_PLANE_DATA_DIR
184+ ?? path.resolve(pmStateRootDir, "control-plane-pgdata"),
185185 postgresApplicationName: "executor-v2-pm",
186186 }),
187187 );
apps/web/README.md+4−4
@@ -21,10 +21,10 @@ Database selection priority: · 20 unmodified lines
2121 - `DATABASE_URL`
2222 - `POSTGRES_URL`
2323
24−If none are set, fallback is local SQLite at:
24+If none are set, fallback is local PGlite data at:
2525
26−- `CONTROL_PLANE_SQLITE_PATH`
27−- default: `.executor-v2/web-state/control-plane.sqlite`
26+- `CONTROL_PLANE_DATA_DIR`
27+- default: `.executor-v2/web-state/control-plane-pgdata`
2828
2929 If needed, `NEXT_PUBLIC_CONTROL_PLANE_BASE_URL` can override the browser base URL.
3030
@@ -32,7 +32,7 @@ MCP install URL generation: · 1 unmodified line
3232
3333 - Derives from existing control-plane/frontend config.
3434 - Prioritizes server-side `CONTROL_PLANE_UPSTREAM_URL` (or server/base control-plane URL) when available.
35−- In local dev with no DB URL, defaults to local SQLite-backed control-plane in this Next.js app.
35+- In local dev with no DB URL, defaults to local PGlite-backed control-plane in this Next.js app.
3636
3737 WorkOS auth setup (optional but recommended):
3838
apps/web/lib/control-plane/server.ts+4−4
@@ -40,7 +40,7 @@ const trim = (value: string | undefined): string | undefined => { · 39 unmodified lines
4040 };
4141
4242 const defaultControlPlaneStateRootDir = ".executor-v2/web-state";
43−const defaultControlPlaneSqliteFile = `${defaultControlPlaneStateRootDir}/control-plane.sqlite`;
43+const defaultControlPlaneDataDir = `${defaultControlPlaneStateRootDir}/control-plane-pgdata`;
4444
4545 type ControlPlaneRuntime = {
4646 persistence: SqlControlPlanePersistence;
@@ -91,8 +91,8 @@ const resolveDatabaseUrl = (): string | undefined => { · 44 unmodified lines
9191 return undefined;
9292 };
9393
94−const resolveSqlitePath = (): string =>
95− trim(process.env.CONTROL_PLANE_SQLITE_PATH) ?? defaultControlPlaneSqliteFile;
94+const resolveControlPlaneDataDir = (): string =>
95+ trim(process.env.CONTROL_PLANE_DATA_DIR) ?? defaultControlPlaneDataDir;
9696
9797 const resolveStateRootDir = (): string =>
9898 trim(process.env.CONTROL_PLANE_STATE_ROOT_DIR) ?? defaultControlPlaneStateRootDir;
@@ -184,7 +184,7 @@ const createControlPlaneRuntime = async (): Promise<ControlPlaneRuntime> => { · 85 unmodified lines
184184 const persistence = await Effect.runPromise(
185185 makeSqlControlPlanePersistence({
186186 databaseUrl: resolveDatabaseUrl(),
187− sqlitePath: resolveSqlitePath(),
187+ localDataDir: resolveControlPlaneDataDir(),
188188 postgresApplicationName: "executor-v2-web",
189189 }),
190190 );
bun.lock+3−0
@@ -163,6 +163,7 @@ · 162 unmodified lines
163163 "packages/persistence-sql": {
164164 "name": "@executor-v2/persistence-sql",
165165 "dependencies": {
166+ "@electric-sql/pglite": "^0.3.10",
166167 "@executor-v2/persistence-ports": "workspace:*",
167168 "@executor-v2/schema": "workspace:*",
168169 "drizzle-orm": "^0.44.7",
@@ -359,6 +360,8 @@ · 190 unmodified lines
359360
360361 "@effect/workflow": ["@effect/workflow@0.15.2", "", { "peerDependencies": { "@effect/experimental": "^0.57.11", "@effect/platform": "^0.93.6", "@effect/rpc": "^0.72.2", "effect": "^3.19.10" } }, "sha512-UAo5QWEvyyKsnf4EQ7WL3zwiuZS4Wd5fmAxdpcpZSIxNOvsABp3DOuyRCiidD8l3sQhdPwES/UsVK4QOCQ7wew=="],
361362
363+ "@electric-sql/pglite": ["@electric-sql/pglite@0.3.15", "", {}, "sha512-Cj++n1Mekf9ETfdc16TlDi+cDDQF0W7EcbyRHYOAeZdsAe8M/FJg18itDTSwyHfar2WIezawM9o0EKaRGVKygQ=="],
364+
362365 "@emmetio/abbreviation": ["@emmetio/abbreviation@2.3.3", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA=="],
363366
364367 "@emmetio/css-abbreviation": ["@emmetio/css-abbreviation@2.1.8", "", { "dependencies": { "@emmetio/scanner": "^1.0.4" } }, "sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw=="],
packages/persistence-sql/drizzle.config.pg.ts+0−14
@@ -1,14 +0,0 @@
1−import { defineConfig } from "drizzle-kit";
2−
3−const databaseUrl = process.env.DATABASE_URL ?? "postgres://localhost:5432/executor_v2";
4−
5−export default defineConfig({
6− dialect: "postgresql",
7− schema: "./src/schema-pg.ts",
8− out: "./drizzle/postgres",
9− dbCredentials: {
10− url: databaseUrl,
11− },
12− strict: true,
13− verbose: true,
14−});
packages/persistence-sql/drizzle.config.ts+5−3
@@ -1,11 +1,13 @@
11 import { defineConfig } from "drizzle-kit";
22
3+const databaseUrl = process.env.DATABASE_URL ?? "postgres://localhost:5432/executor_v2";
4+
35 export default defineConfig({
4− dialect: "sqlite",
6+ dialect: "postgresql",
57 schema: "./src/schema.ts",
6− out: "./drizzle/sqlite",
8+ out: "./drizzle",
79 dbCredentials: {
8− url: "./.executor-v2/control-plane.sqlite",
10+ url: databaseUrl,
911 },
1012 strict: true,
1113 verbose: true,
packages/persistence-sql/drizzle/0000_colorful_mentallo.sqlrenamed from packages/persistence-sql/drizzle/postgres/0000_spicy_barracuda.sql+0−0

File renamed without changes.

packages/persistence-sql/drizzle/meta/0000_snapshot.jsonrenamed from packages/persistence-sql/drizzle/postgres/meta/0000_snapshot.json+1−1
@@ -1,5 +1,5 @@
11 {
2− "id": "5ce8d2a0-b31c-4d34-bd01-c638ca0d5d87",
2+ "id": "ab2ffa01-b774-4a84-bb66-50979a649de7",
33 "prevId": "00000000-0000-0000-0000-000000000000",
44 "version": "7",
55 "dialect": "postgresql",
packages/persistence-sql/drizzle/meta/_journal.jsonrenamed from packages/persistence-sql/drizzle/postgres/meta/_journal.json+2−2
@@ -5,8 +5,8 @@ · 4 unmodified lines
55 {
66 "idx": 0,
77 "version": "7",
8− "when": 1772506152805,
9− "tag": "0000_spicy_barracuda",
8+ "when": 1772507285421,
9+ "tag": "0000_colorful_mentallo",
1010 "breakpoints": true
1111 }
1212 ]
packages/persistence-sql/drizzle/sqlite/0000_curved_raider.sql+0−224
@@ -1,224 +0,0 @@
1−CREATE TABLE `approvals` (
2− `id` text PRIMARY KEY NOT NULL,
3− `workspace_id` text NOT NULL,
4− `task_run_id` text NOT NULL,
5− `call_id` text NOT NULL,
6− `tool_path` text NOT NULL,
7− `status` text NOT NULL,
8− `input_preview_json` text NOT NULL,
9− `reason` text,
10− `requested_at` integer NOT NULL,
11− `resolved_at` integer
12−);
13−--> statement-breakpoint
14−CREATE INDEX `approvals_workspace_idx` ON `approvals` (`workspace_id`);--> statement-breakpoint
15−CREATE INDEX `approvals_task_run_idx` ON `approvals` (`task_run_id`);--> statement-breakpoint
16−CREATE TABLE `auth_connections` (
17− `id` text PRIMARY KEY NOT NULL,
18− `organization_id` text NOT NULL,
19− `workspace_id` text,
20− `account_id` text,
21− `owner_type` text NOT NULL,
22− `strategy` text NOT NULL,
23− `display_name` text NOT NULL,
24− `status` text NOT NULL,
25− `status_reason` text,
26− `last_auth_error_class` text,
27− `metadata_json` text,
28− `additional_headers_json` text,
29− `created_by_account_id` text,
30− `created_at` integer NOT NULL,
31− `updated_at` integer NOT NULL,
32− `last_used_at` integer
33−);
34−--> statement-breakpoint
35−CREATE INDEX `auth_connections_org_idx` ON `auth_connections` (`organization_id`);--> statement-breakpoint
36−CREATE INDEX `auth_connections_workspace_idx` ON `auth_connections` (`workspace_id`);--> statement-breakpoint
37−CREATE INDEX `auth_connections_account_idx` ON `auth_connections` (`account_id`);--> statement-breakpoint
38−CREATE TABLE `auth_materials` (
39− `id` text PRIMARY KEY NOT NULL,
40− `connection_id` text NOT NULL,
41− `ciphertext` text NOT NULL,
42− `key_version` text NOT NULL,
43− `created_at` integer NOT NULL,
44− `updated_at` integer NOT NULL
45−);
46−--> statement-breakpoint
47−CREATE INDEX `auth_materials_connection_idx` ON `auth_materials` (`connection_id`);--> statement-breakpoint
48−CREATE TABLE `oauth_states` (
49− `id` text PRIMARY KEY NOT NULL,
50− `connection_id` text NOT NULL,
51− `access_token_ciphertext` text NOT NULL,
52− `refresh_token_ciphertext` text,
53− `key_version` text NOT NULL,
54− `expires_at` integer,
55− `scope` text,
56− `token_type` text,
57− `issuer` text,
58− `refresh_config_json` text,
59− `token_version` integer NOT NULL,
60− `lease_holder` text,
61− `lease_expires_at` integer,
62− `lease_fence` integer NOT NULL,
63− `last_refresh_at` integer,
64− `last_refresh_error_class` text,
65− `last_refresh_error` text,
66− `reauth_required_at` integer,
67− `created_at` integer NOT NULL,
68− `updated_at` integer NOT NULL
69−);
70−--> statement-breakpoint
71−CREATE INDEX `oauth_states_connection_idx` ON `oauth_states` (`connection_id`);--> statement-breakpoint
72−CREATE TABLE `organization_memberships` (
73− `id` text PRIMARY KEY NOT NULL,
74− `organization_id` text NOT NULL,
75− `account_id` text NOT NULL,
76− `role` text NOT NULL,
77− `status` text NOT NULL,
78− `billable` integer NOT NULL,
79− `invited_by_account_id` text,
80− `joined_at` integer,
81− `created_at` integer NOT NULL,
82− `updated_at` integer NOT NULL
83−);
84−--> statement-breakpoint
85−CREATE INDEX `organization_memberships_org_idx` ON `organization_memberships` (`organization_id`);--> statement-breakpoint
86−CREATE INDEX `organization_memberships_account_idx` ON `organization_memberships` (`account_id`);--> statement-breakpoint
87−CREATE TABLE `organizations` (
88− `id` text PRIMARY KEY NOT NULL,
89− `slug` text NOT NULL,
90− `name` text NOT NULL,
91− `status` text NOT NULL,
92− `created_by_account_id` text,
93− `created_at` integer NOT NULL,
94− `updated_at` integer NOT NULL
95−);
96−--> statement-breakpoint
97−CREATE TABLE `policies` (
98− `id` text PRIMARY KEY NOT NULL,
99− `workspace_id` text NOT NULL,
100− `tool_path_pattern` text NOT NULL,
101− `decision` text NOT NULL,
102− `created_at` integer NOT NULL,
103− `updated_at` integer NOT NULL
104−);
105−--> statement-breakpoint
106−CREATE INDEX `policies_workspace_idx` ON `policies` (`workspace_id`);--> statement-breakpoint
107−CREATE TABLE `profile` (
108− `id` text PRIMARY KEY NOT NULL,
109− `default_workspace_id` text,
110− `display_name` text NOT NULL,
111− `runtime_mode` text NOT NULL,
112− `created_at` integer NOT NULL,
113− `updated_at` integer NOT NULL
114−);
115−--> statement-breakpoint
116−CREATE TABLE `source_auth_bindings` (
117− `id` text PRIMARY KEY NOT NULL,
118− `source_id` text NOT NULL,
119− `connection_id` text NOT NULL,
120− `organization_id` text NOT NULL,
121− `workspace_id` text,
122− `account_id` text,
123− `scope_type` text NOT NULL,
124− `selector` text,
125− `enabled` integer NOT NULL,
126− `created_at` integer NOT NULL,
127− `updated_at` integer NOT NULL
128−);
129−--> statement-breakpoint
130−CREATE INDEX `source_auth_bindings_source_idx` ON `source_auth_bindings` (`source_id`);--> statement-breakpoint
131−CREATE INDEX `source_auth_bindings_connection_idx` ON `source_auth_bindings` (`connection_id`);--> statement-breakpoint
132−CREATE INDEX `source_auth_bindings_org_idx` ON `source_auth_bindings` (`organization_id`);--> statement-breakpoint
133−CREATE INDEX `source_auth_bindings_workspace_idx` ON `source_auth_bindings` (`workspace_id`);--> statement-breakpoint
134−CREATE INDEX `source_auth_bindings_account_idx` ON `source_auth_bindings` (`account_id`);--> statement-breakpoint
135−CREATE TABLE `sources` (
136− `workspace_id` text NOT NULL,
137− `source_id` text NOT NULL,
138− `name` text NOT NULL,
139− `kind` text NOT NULL,
140− `endpoint` text NOT NULL,
141− `status` text NOT NULL,
142− `enabled` integer NOT NULL,
143− `config_json` text NOT NULL,
144− `source_hash` text,
145− `last_error` text,
146− `created_at` integer NOT NULL,
147− `updated_at` integer NOT NULL,
148− PRIMARY KEY(`workspace_id`, `source_id`)
149−);
150−--> statement-breakpoint
151−CREATE INDEX `sources_workspace_name_idx` ON `sources` (`workspace_id`,`name`);--> statement-breakpoint
152−CREATE TABLE `storage_instances` (
153− `id` text PRIMARY KEY NOT NULL,
154− `scope_type` text NOT NULL,
155− `durability` text NOT NULL,
156− `status` text NOT NULL,
157− `provider` text NOT NULL,
158− `backend_key` text NOT NULL,
159− `organization_id` text NOT NULL,
160− `workspace_id` text,
161− `account_id` text,
162− `created_by_account_id` text,
163− `purpose` text,
164− `size_bytes` integer,
165− `file_count` integer,
166− `created_at` integer NOT NULL,
167− `updated_at` integer NOT NULL,
168− `last_seen_at` integer NOT NULL,
169− `closed_at` integer,
170− `expires_at` integer
171−);
172−--> statement-breakpoint
173−CREATE INDEX `storage_instances_org_idx` ON `storage_instances` (`organization_id`);--> statement-breakpoint
174−CREATE INDEX `storage_instances_workspace_idx` ON `storage_instances` (`workspace_id`);--> statement-breakpoint
175−CREATE TABLE `sync_states` (
176− `id` text PRIMARY KEY NOT NULL,
177− `workspace_id` text NOT NULL,
178− `target` text NOT NULL,
179− `target_url` text NOT NULL,
180− `linked_subject` text,
181− `cursor` text,
182− `last_sync_at` integer,
183− `updated_at` integer NOT NULL
184−);
185−--> statement-breakpoint
186−CREATE INDEX `sync_states_workspace_idx` ON `sync_states` (`workspace_id`);--> statement-breakpoint
187−CREATE TABLE `task_runs` (
188− `id` text PRIMARY KEY NOT NULL,
189− `workspace_id` text NOT NULL,
190− `account_id` text NOT NULL,
191− `session_id` text NOT NULL,
192− `runtime_id` text NOT NULL,
193− `code_hash` text NOT NULL,
194− `status` text NOT NULL,
195− `started_at` integer,
196− `completed_at` integer,
197− `exit_code` integer,
198− `error` text
199−);
200−--> statement-breakpoint
201−CREATE INDEX `task_runs_workspace_idx` ON `task_runs` (`workspace_id`);--> statement-breakpoint
202−CREATE TABLE `tool_artifacts` (
203− `id` text NOT NULL,
204− `workspace_id` text NOT NULL,
205− `source_id` text NOT NULL,
206− `source_hash` text NOT NULL,
207− `tool_count` integer NOT NULL,
208− `manifest_json` text NOT NULL,
209− `created_at` integer NOT NULL,
210− `updated_at` integer NOT NULL,
211− PRIMARY KEY(`workspace_id`, `source_id`)
212−);
213−--> statement-breakpoint
214−CREATE UNIQUE INDEX `tool_artifacts_id_idx` ON `tool_artifacts` (`id`);--> statement-breakpoint
215−CREATE TABLE `workspaces` (
216− `id` text PRIMARY KEY NOT NULL,
217− `organization_id` text NOT NULL,
218− `name` text NOT NULL,
219− `created_by_account_id` text,
220− `created_at` integer NOT NULL,
221− `updated_at` integer NOT NULL
222−);
223−--> statement-breakpoint
224−CREATE INDEX `workspaces_org_idx` ON `workspaces` (`organization_id`);
packages/persistence-sql/drizzle/sqlite/meta/0000_snapshot.json+0−1437
@@ -1,1437 +0,0 @@
1−{
2− "version": "6",
3− "dialect": "sqlite",
4− "id": "012495d1-d78e-4f31-a64f-7328fdf970c0",
5− "prevId": "00000000-0000-0000-0000-000000000000",
6− "tables": {
7− "approvals": {
8− "name": "approvals",
9− "columns": {
10− "id": {
11− "name": "id",
12− "type": "text",
13− "primaryKey": true,
14− "notNull": true,
15− "autoincrement": false
16− },
17− "workspace_id": {
18− "name": "workspace_id",
19− "type": "text",
20− "primaryKey": false,
21− "notNull": true,
22− "autoincrement": false
23− },
24− "task_run_id": {
25− "name": "task_run_id",
26− "type": "text",
27− "primaryKey": false,
28− "notNull": true,
29− "autoincrement": false
30− },
31− "call_id": {
32− "name": "call_id",
33− "type": "text",
34− "primaryKey": false,
35− "notNull": true,
36− "autoincrement": false
37− },
38− "tool_path": {
39− "name": "tool_path",
40− "type": "text",
41− "primaryKey": false,
42− "notNull": true,
43− "autoincrement": false
44− },
45− "status": {
46− "name": "status",
47− "type": "text",
48− "primaryKey": false,
49− "notNull": true,
50− "autoincrement": false
51− },
52− "input_preview_json": {
53− "name": "input_preview_json",
54− "type": "text",
55− "primaryKey": false,
56− "notNull": true,
57− "autoincrement": false
58− },
59− "reason": {
60− "name": "reason",
61− "type": "text",
62− "primaryKey": false,
63− "notNull": false,
64− "autoincrement": false
65− },
66− "requested_at": {
67− "name": "requested_at",
68− "type": "integer",
69− "primaryKey": false,
70− "notNull": true,
71− "autoincrement": false
72− },
73− "resolved_at": {
74− "name": "resolved_at",
75− "type": "integer",
76− "primaryKey": false,
77− "notNull": false,
78− "autoincrement": false
79− }
80− },
81− "indexes": {
82− "approvals_workspace_idx": {
83− "name": "approvals_workspace_idx",
84− "columns": [
85− "workspace_id"
86− ],
87− "isUnique": false
88− },
89− "approvals_task_run_idx": {
90− "name": "approvals_task_run_idx",
91− "columns": [
92− "task_run_id"
93− ],
94− "isUnique": false
95− }
96− },
97− "foreignKeys": {},
98− "compositePrimaryKeys": {},
99− "uniqueConstraints": {},
100− "checkConstraints": {}
101− },
102− "auth_connections": {
103− "name": "auth_connections",
104− "columns": {
105− "id": {
106− "name": "id",
107− "type": "text",
108− "primaryKey": true,
109− "notNull": true,
110− "autoincrement": false
111− },
112− "organization_id": {
113− "name": "organization_id",
114− "type": "text",
115− "primaryKey": false,
116− "notNull": true,
117− "autoincrement": false
118− },
119− "workspace_id": {
120− "name": "workspace_id",
121− "type": "text",
122− "primaryKey": false,
123− "notNull": false,
124− "autoincrement": false
125− },
126− "account_id": {
127− "name": "account_id",
128− "type": "text",
129− "primaryKey": false,
130− "notNull": false,
131− "autoincrement": false
132− },
133− "owner_type": {
134− "name": "owner_type",
135− "type": "text",
136− "primaryKey": false,
137− "notNull": true,
138− "autoincrement": false
139− },
140− "strategy": {
141− "name": "strategy",
142− "type": "text",
143− "primaryKey": false,
144− "notNull": true,
145− "autoincrement": false
146− },
147− "display_name": {
148− "name": "display_name",
149− "type": "text",
150− "primaryKey": false,
151− "notNull": true,
152− "autoincrement": false
153− },
154− "status": {
155− "name": "status",
156− "type": "text",
157− "primaryKey": false,
158− "notNull": true,
159− "autoincrement": false
160− },
161− "status_reason": {
162− "name": "status_reason",
163− "type": "text",
164− "primaryKey": false,
165− "notNull": false,
166− "autoincrement": false
167− },
168− "last_auth_error_class": {
169− "name": "last_auth_error_class",
170− "type": "text",
171− "primaryKey": false,
172− "notNull": false,
173− "autoincrement": false
174− },
175− "metadata_json": {
176− "name": "metadata_json",
177− "type": "text",
178− "primaryKey": false,
179− "notNull": false,
180− "autoincrement": false
181− },
182− "additional_headers_json": {
183− "name": "additional_headers_json",
184− "type": "text",
185− "primaryKey": false,
186− "notNull": false,
187− "autoincrement": false
188− },
189− "created_by_account_id": {
190− "name": "created_by_account_id",
191− "type": "text",
192− "primaryKey": false,
193− "notNull": false,
194− "autoincrement": false
195− },
196− "created_at": {
197− "name": "created_at",
198− "type": "integer",
199− "primaryKey": false,
200− "notNull": true,
201− "autoincrement": false
202− },
203− "updated_at": {
204− "name": "updated_at",
205− "type": "integer",
206− "primaryKey": false,
207− "notNull": true,
208− "autoincrement": false
209− },
210− "last_used_at": {
211− "name": "last_used_at",
212− "type": "integer",
213− "primaryKey": false,
214− "notNull": false,
215− "autoincrement": false
216− }
217− },
218− "indexes": {
219− "auth_connections_org_idx": {
220− "name": "auth_connections_org_idx",
221− "columns": [
222− "organization_id"
223− ],
224− "isUnique": false
225− },
226− "auth_connections_workspace_idx": {
227− "name": "auth_connections_workspace_idx",
228− "columns": [
229− "workspace_id"
230− ],
231− "isUnique": false
232− },
233− "auth_connections_account_idx": {
234− "name": "auth_connections_account_idx",
235− "columns": [
236− "account_id"
237− ],
238− "isUnique": false
239− }
240− },
241− "foreignKeys": {},
242− "compositePrimaryKeys": {},
243− "uniqueConstraints": {},
244− "checkConstraints": {}
245− },
246− "auth_materials": {
247− "name": "auth_materials",
248− "columns": {
249− "id": {
250− "name": "id",
251− "type": "text",
252− "primaryKey": true,
253− "notNull": true,
254− "autoincrement": false
255− },
256− "connection_id": {
257− "name": "connection_id",
258− "type": "text",
259− "primaryKey": false,
260− "notNull": true,
261− "autoincrement": false
262− },
263− "ciphertext": {
264− "name": "ciphertext",
265− "type": "text",
266− "primaryKey": false,
267− "notNull": true,
268− "autoincrement": false
269− },
270− "key_version": {
271− "name": "key_version",
272− "type": "text",
273− "primaryKey": false,
274− "notNull": true,
275− "autoincrement": false
276− },
277− "created_at": {
278− "name": "created_at",
279− "type": "integer",
280− "primaryKey": false,
281− "notNull": true,
282− "autoincrement": false
283− },
284− "updated_at": {
285− "name": "updated_at",
286− "type": "integer",
287− "primaryKey": false,
288− "notNull": true,
289− "autoincrement": false
290− }
291− },
292− "indexes": {
293− "auth_materials_connection_idx": {
294− "name": "auth_materials_connection_idx",
295− "columns": [
296− "connection_id"
297− ],
298− "isUnique": false
299− }
300− },
301− "foreignKeys": {},
302− "compositePrimaryKeys": {},
303− "uniqueConstraints": {},
304− "checkConstraints": {}
305− },
306− "oauth_states": {
307− "name": "oauth_states",
308− "columns": {
309− "id": {
310− "name": "id",
311− "type": "text",
312− "primaryKey": true,
313− "notNull": true,
314− "autoincrement": false
315− },
316− "connection_id": {
317− "name": "connection_id",
318− "type": "text",
319− "primaryKey": false,
320− "notNull": true,
321− "autoincrement": false
322− },
323− "access_token_ciphertext": {
324− "name": "access_token_ciphertext",
325− "type": "text",
326− "primaryKey": false,
327− "notNull": true,
328− "autoincrement": false
329− },
330− "refresh_token_ciphertext": {
331− "name": "refresh_token_ciphertext",
332− "type": "text",
333− "primaryKey": false,
334− "notNull": false,
335− "autoincrement": false
336− },
337− "key_version": {
338− "name": "key_version",
339− "type": "text",
340− "primaryKey": false,
341− "notNull": true,
342− "autoincrement": false
343− },
344− "expires_at": {
345− "name": "expires_at",
346− "type": "integer",
347− "primaryKey": false,
348− "notNull": false,
349− "autoincrement": false
350− },
351− "scope": {
352− "name": "scope",
353− "type": "text",
354− "primaryKey": false,
355− "notNull": false,
356− "autoincrement": false
357− },
358− "token_type": {
359− "name": "token_type",
360− "type": "text",
361− "primaryKey": false,
362− "notNull": false,
363− "autoincrement": false
364− },
365− "issuer": {
366− "name": "issuer",
367− "type": "text",
368− "primaryKey": false,
369− "notNull": false,
370− "autoincrement": false
371− },
372− "refresh_config_json": {
373− "name": "refresh_config_json",
374− "type": "text",
375− "primaryKey": false,
376− "notNull": false,
377− "autoincrement": false
378− },
379− "token_version": {
380− "name": "token_version",
381− "type": "integer",
382− "primaryKey": false,
383− "notNull": true,
384− "autoincrement": false
385− },
386− "lease_holder": {
387− "name": "lease_holder",
388− "type": "text",
389− "primaryKey": false,
390− "notNull": false,
391− "autoincrement": false
392− },
393− "lease_expires_at": {
394− "name": "lease_expires_at",
395− "type": "integer",
396− "primaryKey": false,
397− "notNull": false,
398− "autoincrement": false
399− },
400− "lease_fence": {
401− "name": "lease_fence",
402− "type": "integer",
403− "primaryKey": false,
404− "notNull": true,
405− "autoincrement": false
406− },
407− "last_refresh_at": {
408− "name": "last_refresh_at",
409− "type": "integer",
410− "primaryKey": false,
411− "notNull": false,
412− "autoincrement": false
413− },
414− "last_refresh_error_class": {
415− "name": "last_refresh_error_class",
416− "type": "text",
417− "primaryKey": false,
418− "notNull": false,
419− "autoincrement": false
420− },
421− "last_refresh_error": {
422− "name": "last_refresh_error",
423− "type": "text",
424− "primaryKey": false,
425− "notNull": false,
426− "autoincrement": false
427− },
428− "reauth_required_at": {
429− "name": "reauth_required_at",
430− "type": "integer",
431− "primaryKey": false,
432− "notNull": false,
433− "autoincrement": false
434− },
435− "created_at": {
436− "name": "created_at",
437− "type": "integer",
438− "primaryKey": false,
439− "notNull": true,
440− "autoincrement": false
441− },
442− "updated_at": {
443− "name": "updated_at",
444− "type": "integer",
445− "primaryKey": false,
446− "notNull": true,
447− "autoincrement": false
448− }
449− },
450− "indexes": {
451− "oauth_states_connection_idx": {
452− "name": "oauth_states_connection_idx",
453− "columns": [
454− "connection_id"
455− ],
456− "isUnique": false
457− }
458− },
459− "foreignKeys": {},
460− "compositePrimaryKeys": {},
461− "uniqueConstraints": {},
462− "checkConstraints": {}
463− },
464− "organization_memberships": {
465− "name": "organization_memberships",
466− "columns": {
467− "id": {
468− "name": "id",
469− "type": "text",
470− "primaryKey": true,
471− "notNull": true,
472− "autoincrement": false
473− },
474− "organization_id": {
475− "name": "organization_id",
476− "type": "text",
477− "primaryKey": false,
478− "notNull": true,
479− "autoincrement": false
480− },
481− "account_id": {
482− "name": "account_id",
483− "type": "text",
484− "primaryKey": false,
485− "notNull": true,
486− "autoincrement": false
487− },
488− "role": {
489− "name": "role",
490− "type": "text",
491− "primaryKey": false,
492− "notNull": true,
493− "autoincrement": false
494− },
495− "status": {
496− "name": "status",
497− "type": "text",
498− "primaryKey": false,
499− "notNull": true,
500− "autoincrement": false
501− },
502− "billable": {
503− "name": "billable",
504− "type": "integer",
505− "primaryKey": false,
506− "notNull": true,
507− "autoincrement": false
508− },
509− "invited_by_account_id": {
510− "name": "invited_by_account_id",
511− "type": "text",
512− "primaryKey": false,
513− "notNull": false,
514− "autoincrement": false
515− },
516− "joined_at": {
517− "name": "joined_at",
518− "type": "integer",
519− "primaryKey": false,
520− "notNull": false,
521− "autoincrement": false
522− },
523− "created_at": {
524− "name": "created_at",
525− "type": "integer",
526− "primaryKey": false,
527− "notNull": true,
528− "autoincrement": false
529− },
530− "updated_at": {
531− "name": "updated_at",
532− "type": "integer",
533− "primaryKey": false,
534− "notNull": true,
535− "autoincrement": false
536− }
537− },
538− "indexes": {
539− "organization_memberships_org_idx": {
540− "name": "organization_memberships_org_idx",
541− "columns": [
542− "organization_id"
543− ],
544− "isUnique": false
545− },
546− "organization_memberships_account_idx": {
547− "name": "organization_memberships_account_idx",
548− "columns": [
549− "account_id"
550− ],
551− "isUnique": false
552− }
553− },
554− "foreignKeys": {},
555− "compositePrimaryKeys": {},
556− "uniqueConstraints": {},
557− "checkConstraints": {}
558− },
559− "organizations": {
560− "name": "organizations",
561− "columns": {
562− "id": {
563− "name": "id",
564− "type": "text",
565− "primaryKey": true,
566− "notNull": true,
567− "autoincrement": false
568− },
569− "slug": {
570− "name": "slug",
571− "type": "text",
572− "primaryKey": false,
573− "notNull": true,
574− "autoincrement": false
575− },
576− "name": {
577− "name": "name",
578− "type": "text",
579− "primaryKey": false,
580− "notNull": true,
581− "autoincrement": false
582− },
583− "status": {
584− "name": "status",
585− "type": "text",
586− "primaryKey": false,
587− "notNull": true,
588− "autoincrement": false
589− },
590− "created_by_account_id": {
591− "name": "created_by_account_id",
592− "type": "text",
593− "primaryKey": false,
594− "notNull": false,
595− "autoincrement": false
596− },
597− "created_at": {
598− "name": "created_at",
599− "type": "integer",
600− "primaryKey": false,
601− "notNull": true,
602− "autoincrement": false
603− },
604− "updated_at": {
605− "name": "updated_at",
606− "type": "integer",
607− "primaryKey": false,
608− "notNull": true,
609− "autoincrement": false
610− }
611− },
612− "indexes": {},
613− "foreignKeys": {},
614− "compositePrimaryKeys": {},
615− "uniqueConstraints": {},
616− "checkConstraints": {}
617− },
618− "policies": {
619− "name": "policies",
620− "columns": {
621− "id": {
622− "name": "id",
623− "type": "text",
624− "primaryKey": true,
625− "notNull": true,
626− "autoincrement": false
627− },
628− "workspace_id": {
629− "name": "workspace_id",
630− "type": "text",
631− "primaryKey": false,
632− "notNull": true,
633− "autoincrement": false
634− },
635− "tool_path_pattern": {
636− "name": "tool_path_pattern",
637− "type": "text",
638− "primaryKey": false,
639− "notNull": true,
640− "autoincrement": false
641− },
642− "decision": {
643− "name": "decision",
644− "type": "text",
645− "primaryKey": false,
646− "notNull": true,
647− "autoincrement": false
648− },
649− "created_at": {
650− "name": "created_at",
651− "type": "integer",
652− "primaryKey": false,
653− "notNull": true,
654− "autoincrement": false
655− },
656− "updated_at": {
657− "name": "updated_at",
658− "type": "integer",
659− "primaryKey": false,
660− "notNull": true,
661− "autoincrement": false
662− }
663− },
664− "indexes": {
665− "policies_workspace_idx": {
666− "name": "policies_workspace_idx",
667− "columns": [
668− "workspace_id"
669− ],
670− "isUnique": false
671− }
672− },
673− "foreignKeys": {},
674− "compositePrimaryKeys": {},
675− "uniqueConstraints": {},
676− "checkConstraints": {}
677− },
678− "profile": {
679− "name": "profile",
680− "columns": {
681− "id": {
682− "name": "id",
683− "type": "text",
684− "primaryKey": true,
685− "notNull": true,
686− "autoincrement": false
687− },
688− "default_workspace_id": {
689− "name": "default_workspace_id",
690− "type": "text",
691− "primaryKey": false,
692− "notNull": false,
693− "autoincrement": false
694− },
695− "display_name": {
696− "name": "display_name",
697− "type": "text",
698− "primaryKey": false,
699− "notNull": true,
700− "autoincrement": false
701− },
702− "runtime_mode": {
703− "name": "runtime_mode",
704− "type": "text",
705− "primaryKey": false,
706− "notNull": true,
707− "autoincrement": false
708− },
709− "created_at": {
710− "name": "created_at",
711− "type": "integer",
712− "primaryKey": false,
713− "notNull": true,
714− "autoincrement": false
715− },
716− "updated_at": {
717− "name": "updated_at",
718− "type": "integer",
719− "primaryKey": false,
720− "notNull": true,
721− "autoincrement": false
722− }
723− },
724− "indexes": {},
725− "foreignKeys": {},
726− "compositePrimaryKeys": {},
727− "uniqueConstraints": {},
728− "checkConstraints": {}
729− },
730− "source_auth_bindings": {
731− "name": "source_auth_bindings",
732− "columns": {
733− "id": {
734− "name": "id",
735− "type": "text",
736− "primaryKey": true,
737− "notNull": true,
738− "autoincrement": false
739− },
740− "source_id": {
741− "name": "source_id",
742− "type": "text",
743− "primaryKey": false,
744− "notNull": true,
745− "autoincrement": false
746− },
747− "connection_id": {
748− "name": "connection_id",
749− "type": "text",
750− "primaryKey": false,
751− "notNull": true,
752− "autoincrement": false
753− },
754− "organization_id": {
755− "name": "organization_id",
756− "type": "text",
757− "primaryKey": false,
758− "notNull": true,
759− "autoincrement": false
760− },
761− "workspace_id": {
762− "name": "workspace_id",
763− "type": "text",
764− "primaryKey": false,
765− "notNull": false,
766− "autoincrement": false
767− },
768− "account_id": {
769− "name": "account_id",
770− "type": "text",
771− "primaryKey": false,
772− "notNull": false,
773− "autoincrement": false
774− },
775− "scope_type": {
776− "name": "scope_type",
777− "type": "text",
778− "primaryKey": false,
779− "notNull": true,
780− "autoincrement": false
781− },
782− "selector": {
783− "name": "selector",
784− "type": "text",
785− "primaryKey": false,
786− "notNull": false,
787− "autoincrement": false
788− },
789− "enabled": {
790− "name": "enabled",
791− "type": "integer",
792− "primaryKey": false,
793− "notNull": true,
794− "autoincrement": false
795− },
796− "created_at": {
797− "name": "created_at",
798− "type": "integer",
799− "primaryKey": false,
800− "notNull": true,
801− "autoincrement": false
802− },
803− "updated_at": {
804− "name": "updated_at",
805− "type": "integer",
806− "primaryKey": false,
807− "notNull": true,
808− "autoincrement": false
809− }
810− },
811− "indexes": {
812− "source_auth_bindings_source_idx": {
813− "name": "source_auth_bindings_source_idx",
814− "columns": [
815− "source_id"
816− ],
817− "isUnique": false
818− },
819− "source_auth_bindings_connection_idx": {
820− "name": "source_auth_bindings_connection_idx",
821− "columns": [
822− "connection_id"
823− ],
824− "isUnique": false
825− },
826− "source_auth_bindings_org_idx": {
827− "name": "source_auth_bindings_org_idx",
828− "columns": [
829− "organization_id"
830− ],
831− "isUnique": false
832− },
833− "source_auth_bindings_workspace_idx": {
834− "name": "source_auth_bindings_workspace_idx",
835− "columns": [
836− "workspace_id"
837− ],
838− "isUnique": false
839− },
840− "source_auth_bindings_account_idx": {
841− "name": "source_auth_bindings_account_idx",
842− "columns": [
843− "account_id"
844− ],
845− "isUnique": false
846− }
847− },
848− "foreignKeys": {},
849− "compositePrimaryKeys": {},
850− "uniqueConstraints": {},
851− "checkConstraints": {}
852− },
853− "sources": {
854− "name": "sources",
855− "columns": {
856− "workspace_id": {
857− "name": "workspace_id",
858− "type": "text",
859− "primaryKey": false,
860− "notNull": true,
861− "autoincrement": false
862− },
863− "source_id": {
864− "name": "source_id",
865− "type": "text",
866− "primaryKey": false,
867− "notNull": true,
868− "autoincrement": false
869− },
870− "name": {
871− "name": "name",
872− "type": "text",
873− "primaryKey": false,
874− "notNull": true,
875− "autoincrement": false
876− },
877− "kind": {
878− "name": "kind",
879− "type": "text",
880− "primaryKey": false,
881− "notNull": true,
882− "autoincrement": false
883− },
884− "endpoint": {
885− "name": "endpoint",
886− "type": "text",
887− "primaryKey": false,
888− "notNull": true,
889− "autoincrement": false
890− },
891− "status": {
892− "name": "status",
893− "type": "text",
894− "primaryKey": false,
895− "notNull": true,
896− "autoincrement": false
897− },
898− "enabled": {
899− "name": "enabled",
900− "type": "integer",
901− "primaryKey": false,
902− "notNull": true,
903− "autoincrement": false
904− },
905− "config_json": {
906− "name": "config_json",
907− "type": "text",
908− "primaryKey": false,
909− "notNull": true,
910− "autoincrement": false
911− },
912− "source_hash": {
913− "name": "source_hash",
914− "type": "text",
915− "primaryKey": false,
916− "notNull": false,
917− "autoincrement": false
918− },
919− "last_error": {
920− "name": "last_error",
921− "type": "text",
922− "primaryKey": false,
923− "notNull": false,
924− "autoincrement": false
925− },
926− "created_at": {
927− "name": "created_at",
928− "type": "integer",
929− "primaryKey": false,
930− "notNull": true,
931− "autoincrement": false
932− },
933− "updated_at": {
934− "name": "updated_at",
935− "type": "integer",
936− "primaryKey": false,
937− "notNull": true,
938− "autoincrement": false
939− }
940− },
941− "indexes": {
942− "sources_workspace_name_idx": {
943− "name": "sources_workspace_name_idx",
944− "columns": [
945− "workspace_id",
946− "name"
947− ],
948− "isUnique": false
949− }
950− },
951− "foreignKeys": {},
952− "compositePrimaryKeys": {
953− "sources_workspace_id_source_id_pk": {
954− "columns": [
955− "workspace_id",
956− "source_id"
957− ],
958− "name": "sources_workspace_id_source_id_pk"
959− }
960− },
961− "uniqueConstraints": {},
962− "checkConstraints": {}
963− },
964− "storage_instances": {
965− "name": "storage_instances",
966− "columns": {
967− "id": {
968− "name": "id",
969− "type": "text",
970− "primaryKey": true,
971− "notNull": true,
972− "autoincrement": false
973− },
974− "scope_type": {
975− "name": "scope_type",
976− "type": "text",
977− "primaryKey": false,
978− "notNull": true,
979− "autoincrement": false
980− },
981− "durability": {
982− "name": "durability",
983− "type": "text",
984− "primaryKey": false,
985− "notNull": true,
986− "autoincrement": false
987− },
988− "status": {
989− "name": "status",
990− "type": "text",
991− "primaryKey": false,
992− "notNull": true,
993− "autoincrement": false
994− },
995− "provider": {
996− "name": "provider",
997− "type": "text",
998− "primaryKey": false,
999− "notNull": true,
1000− "autoincrement": false
1001− },
1002− "backend_key": {
1003− "name": "backend_key",
1004− "type": "text",
1005− "primaryKey": false,
1006− "notNull": true,
1007− "autoincrement": false
1008− },
1009− "organization_id": {
1010− "name": "organization_id",
1011− "type": "text",
1012− "primaryKey": false,
1013− "notNull": true,
1014− "autoincrement": false
1015− },
1016− "workspace_id": {
1017− "name": "workspace_id",
1018− "type": "text",
1019− "primaryKey": false,
1020− "notNull": false,
1021− "autoincrement": false
1022− },
1023− "account_id": {
1024− "name": "account_id",
1025− "type": "text",
1026− "primaryKey": false,
1027− "notNull": false,
1028− "autoincrement": false
1029− },
1030− "created_by_account_id": {
1031− "name": "created_by_account_id",
1032− "type": "text",
1033− "primaryKey": false,
1034− "notNull": false,
1035− "autoincrement": false
1036− },
1037− "purpose": {
1038− "name": "purpose",
1039− "type": "text",
1040− "primaryKey": false,
1041− "notNull": false,
1042− "autoincrement": false
1043− },
1044− "size_bytes": {
1045− "name": "size_bytes",
1046− "type": "integer",
1047− "primaryKey": false,
1048− "notNull": false,
1049− "autoincrement": false
1050− },
1051− "file_count": {
1052− "name": "file_count",
1053− "type": "integer",
1054− "primaryKey": false,
1055− "notNull": false,
1056− "autoincrement": false
1057− },
1058− "created_at": {
1059− "name": "created_at",
1060− "type": "integer",
1061− "primaryKey": false,
1062− "notNull": true,
1063− "autoincrement": false
1064− },
1065− "updated_at": {
1066− "name": "updated_at",
1067− "type": "integer",
1068− "primaryKey": false,
1069− "notNull": true,
1070− "autoincrement": false
1071− },
1072− "last_seen_at": {
1073− "name": "last_seen_at",
1074− "type": "integer",
1075− "primaryKey": false,
1076− "notNull": true,
1077− "autoincrement": false
1078− },
1079− "closed_at": {
1080− "name": "closed_at",
1081− "type": "integer",
1082− "primaryKey": false,
1083− "notNull": false,
1084− "autoincrement": false
1085− },
1086− "expires_at": {
1087− "name": "expires_at",
1088− "type": "integer",
1089− "primaryKey": false,
1090− "notNull": false,
1091− "autoincrement": false
1092− }
1093− },
1094− "indexes": {
1095− "storage_instances_org_idx": {
1096− "name": "storage_instances_org_idx",
1097− "columns": [
1098− "organization_id"
1099− ],
1100− "isUnique": false
1101− },
1102− "storage_instances_workspace_idx": {
1103− "name": "storage_instances_workspace_idx",
1104− "columns": [
1105− "workspace_id"
1106− ],
1107− "isUnique": false
1108− }
1109− },
1110− "foreignKeys": {},
1111− "compositePrimaryKeys": {},
1112− "uniqueConstraints": {},
1113− "checkConstraints": {}
1114− },
1115− "sync_states": {
1116− "name": "sync_states",
1117− "columns": {
1118− "id": {
1119− "name": "id",
1120− "type": "text",
1121− "primaryKey": true,
1122− "notNull": true,
1123− "autoincrement": false
1124− },
1125− "workspace_id": {
1126− "name": "workspace_id",
1127− "type": "text",
1128− "primaryKey": false,
1129− "notNull": true,
1130− "autoincrement": false
1131− },
1132− "target": {
1133− "name": "target",
1134− "type": "text",
1135− "primaryKey": false,
1136− "notNull": true,
1137− "autoincrement": false
1138− },
1139− "target_url": {
1140− "name": "target_url",
1141− "type": "text",
1142− "primaryKey": false,
1143− "notNull": true,
1144− "autoincrement": false
1145− },
1146− "linked_subject": {
1147− "name": "linked_subject",
1148− "type": "text",
1149− "primaryKey": false,
1150− "notNull": false,
1151− "autoincrement": false
1152− },
1153− "cursor": {
1154− "name": "cursor",
1155− "type": "text",
1156− "primaryKey": false,
1157− "notNull": false,
1158− "autoincrement": false
1159− },
1160− "last_sync_at": {
1161− "name": "last_sync_at",
1162− "type": "integer",
1163− "primaryKey": false,
1164− "notNull": false,
1165− "autoincrement": false
1166− },
1167− "updated_at": {
1168− "name": "updated_at",
1169− "type": "integer",
1170− "primaryKey": false,
1171− "notNull": true,
1172− "autoincrement": false
1173− }
1174− },
1175− "indexes": {
1176− "sync_states_workspace_idx": {
1177− "name": "sync_states_workspace_idx",
1178− "columns": [
1179− "workspace_id"
1180− ],
1181− "isUnique": false
1182− }
1183− },
1184− "foreignKeys": {},
1185− "compositePrimaryKeys": {},
1186− "uniqueConstraints": {},
1187− "checkConstraints": {}
1188− },
1189− "task_runs": {
1190− "name": "task_runs",
1191− "columns": {
1192− "id": {
1193− "name": "id",
1194− "type": "text",
1195− "primaryKey": true,
1196− "notNull": true,
1197− "autoincrement": false
1198− },
1199− "workspace_id": {
1200− "name": "workspace_id",
1201− "type": "text",
1202− "primaryKey": false,
1203− "notNull": true,
1204− "autoincrement": false
1205− },
1206− "account_id": {
1207− "name": "account_id",
1208− "type": "text",
1209− "primaryKey": false,
1210− "notNull": true,
1211− "autoincrement": false
1212− },
1213− "session_id": {
1214− "name": "session_id",
1215− "type": "text",
1216− "primaryKey": false,
1217− "notNull": true,
1218− "autoincrement": false
1219− },
1220− "runtime_id": {
1221− "name": "runtime_id",
1222− "type": "text",
1223− "primaryKey": false,
1224− "notNull": true,
1225− "autoincrement": false
1226− },
1227− "code_hash": {
1228− "name": "code_hash",
1229− "type": "text",
1230− "primaryKey": false,
1231− "notNull": true,
1232− "autoincrement": false
1233− },
1234− "status": {
1235− "name": "status",
1236− "type": "text",
1237− "primaryKey": false,
1238− "notNull": true,
1239− "autoincrement": false
1240− },
1241− "started_at": {
1242− "name": "started_at",
1243− "type": "integer",
1244− "primaryKey": false,
1245− "notNull": false,
1246− "autoincrement": false
1247− },
1248− "completed_at": {
1249− "name": "completed_at",
1250− "type": "integer",
1251− "primaryKey": false,
1252− "notNull": false,
1253− "autoincrement": false
1254− },
1255− "exit_code": {
1256− "name": "exit_code",
1257− "type": "integer",
1258− "primaryKey": false,
1259− "notNull": false,
1260− "autoincrement": false
1261− },
1262− "error": {
1263− "name": "error",
1264− "type": "text",
1265− "primaryKey": false,
1266− "notNull": false,
1267− "autoincrement": false
1268− }
1269− },
1270− "indexes": {
1271− "task_runs_workspace_idx": {
1272− "name": "task_runs_workspace_idx",
1273− "columns": [
1274− "workspace_id"
1275− ],
1276− "isUnique": false
1277− }
1278− },
1279− "foreignKeys": {},
1280− "compositePrimaryKeys": {},
1281− "uniqueConstraints": {},
1282− "checkConstraints": {}
1283− },
1284− "tool_artifacts": {
1285− "name": "tool_artifacts",
1286− "columns": {
1287− "id": {
1288− "name": "id",
1289− "type": "text",
1290− "primaryKey": false,
1291− "notNull": true,
1292− "autoincrement": false
1293− },
1294− "workspace_id": {
1295− "name": "workspace_id",
1296− "type": "text",
1297− "primaryKey": false,
1298− "notNull": true,
1299− "autoincrement": false
1300− },
1301− "source_id": {
1302− "name": "source_id",
1303− "type": "text",
1304− "primaryKey": false,
1305− "notNull": true,
1306− "autoincrement": false
1307− },
1308− "source_hash": {
1309− "name": "source_hash",
1310− "type": "text",
1311− "primaryKey": false,
1312− "notNull": true,
1313− "autoincrement": false
1314− },
1315− "tool_count": {
1316− "name": "tool_count",
1317− "type": "integer",
1318− "primaryKey": false,
1319− "notNull": true,
1320− "autoincrement": false
1321− },
1322− "manifest_json": {
1323− "name": "manifest_json",
1324− "type": "text",
1325− "primaryKey": false,
1326− "notNull": true,
1327− "autoincrement": false
1328− },
1329− "created_at": {
1330− "name": "created_at",
1331− "type": "integer",
1332− "primaryKey": false,
1333− "notNull": true,
1334− "autoincrement": false
1335− },
1336− "updated_at": {
1337− "name": "updated_at",
1338− "type": "integer",
1339− "primaryKey": false,
1340− "notNull": true,
1341− "autoincrement": false
1342− }
1343− },
1344− "indexes": {
1345− "tool_artifacts_id_idx": {
1346− "name": "tool_artifacts_id_idx",
1347− "columns": [
1348− "id"
1349− ],
1350− "isUnique": true
1351− }
1352− },
1353− "foreignKeys": {},
1354− "compositePrimaryKeys": {
1355− "tool_artifacts_workspace_id_source_id_pk": {
1356− "columns": [
1357− "workspace_id",
1358− "source_id"
1359− ],
1360− "name": "tool_artifacts_workspace_id_source_id_pk"
1361− }
1362− },
1363− "uniqueConstraints": {},
1364− "checkConstraints": {}
1365− },
1366− "workspaces": {
1367− "name": "workspaces",
1368− "columns": {
1369− "id": {
1370− "name": "id",
1371− "type": "text",
1372− "primaryKey": true,
1373− "notNull": true,
1374− "autoincrement": false
1375− },
1376− "organization_id": {
1377− "name": "organization_id",
1378− "type": "text",
1379− "primaryKey": false,
1380− "notNull": true,
1381− "autoincrement": false
1382− },
1383− "name": {
1384− "name": "name",
1385− "type": "text",
1386− "primaryKey": false,
1387− "notNull": true,
1388− "autoincrement": false
1389− },
1390− "created_by_account_id": {
1391− "name": "created_by_account_id",
1392− "type": "text",
1393− "primaryKey": false,
1394− "notNull": false,
1395− "autoincrement": false
1396− },
1397− "created_at": {
1398− "name": "created_at",
1399− "type": "integer",
1400− "primaryKey": false,
1401− "notNull": true,
1402− "autoincrement": false
1403− },
1404− "updated_at": {
1405− "name": "updated_at",
1406− "type": "integer",
1407− "primaryKey": false,
1408− "notNull": true,
1409− "autoincrement": false
1410− }
1411− },
1412− "indexes": {
1413− "workspaces_org_idx": {
1414− "name": "workspaces_org_idx",
1415− "columns": [
1416− "organization_id"
1417− ],
1418− "isUnique": false
1419− }
1420− },
1421− "foreignKeys": {},
1422− "compositePrimaryKeys": {},
1423− "uniqueConstraints": {},
1424− "checkConstraints": {}
1425− }
1426− },
1427− "views": {},
1428− "enums": {},
1429− "_meta": {
1430− "schemas": {},
1431− "tables": {},
1432− "columns": {}
1433− },
1434− "internal": {
1435− "indexes": {}
1436− }
1437−}
packages/persistence-sql/drizzle/sqlite/meta/_journal.json+0−13
@@ -1,13 +0,0 @@
1−{
2− "version": "7",
3− "dialect": "sqlite",
4− "entries": [
5− {
6− "idx": 0,
7− "version": "6",
8− "when": 1772506139541,
9− "tag": "0000_curved_raider",
10− "breakpoints": true
11− }
12− ]
13−}
packages/persistence-sql/package.json+1−3
@@ -8,14 +8,12 @@ · 7 unmodified lines
88 "scripts": {
99 "typecheck": "bunx tsc --noEmit -p tsconfig.json",
1010 "db:generate": "drizzle-kit generate --config drizzle.config.ts",
11− "db:generate:pg": "drizzle-kit generate --config drizzle.config.pg.ts",
1211 "db:check": "drizzle-kit check --config drizzle.config.ts",
13− "db:check:pg": "drizzle-kit check --config drizzle.config.pg.ts",
1412 "db:migrate": "drizzle-kit migrate --config drizzle.config.ts",
15− "db:migrate:pg": "drizzle-kit migrate --config drizzle.config.pg.ts",
1613 "db:studio": "drizzle-kit studio --config drizzle.config.ts"
1714 },
1815 "dependencies": {
16+ "@electric-sql/pglite": "^0.3.10",
1917 "@executor-v2/persistence-ports": "workspace:*",
2018 "@executor-v2/schema": "workspace:*",
2119 "drizzle-orm": "^0.44.7",
packages/persistence-sql/src/index.ts+7−7
@@ -25,8 +25,8 @@ import { createRowOperations } from "./row-operations"; · 24 unmodified lines
2525 import { createRowsEffectApi } from "./rows-effect-api";
2626 import {
2727 createDrizzleContext,
28+ createPGliteAdapter,
2829 createPostgresAdapter,
29− createSqliteAdapter,
3030 runMigrations,
3131 type SqlBackend,
3232 } from "./sql-internals";
@@ -34,7 +34,7 @@ import { createSourceAndArtifactStores } from "./source-artifact-stores"; · 1 unmodified line
3434
3535 export type SqlControlPlanePersistenceOptions = {
3636 databaseUrl?: string;
37− sqlitePath?: string;
37+ localDataDir?: string;
3838 postgresApplicationName?: string;
3939 };
4040
@@ -141,20 +141,20 @@ export const makeSqlControlPlanePersistence = ( · 100 unmodified lines
141141 Effect.tryPromise({
142142 try: async () => {
143143 const databaseUrl = trim(options.databaseUrl);
144− const sqlitePath = path.resolve(
145− options.sqlitePath ?? ".executor-v2/control-plane.sqlite",
144+ const localDataDir = path.resolve(
145+ options.localDataDir ?? ".executor-v2/control-plane-pgdata",
146146 );
147147 const backend: SqlBackend =
148148 databaseUrl && (databaseUrl.startsWith("postgres://") || databaseUrl.startsWith("postgresql://"))
149149 ? "postgres"
150− : "sqlite";
150+ : "pglite";
151151
152152 const adapter =
153153 backend === "postgres"
154154 ? await createPostgresAdapter(databaseUrl!, trim(options.postgresApplicationName))
155− : await createSqliteAdapter(sqlitePath);
155+ : await createPGliteAdapter(localDataDir);
156156
157− await runMigrations(backend, adapter);
157+ await runMigrations(adapter);
158158 const drizzleContext = createDrizzleContext(adapter);
159159 const { db, tables } = drizzleContext;
160160
packages/persistence-sql/src/schema-pg.ts+0−304
@@ -1,304 +0,0 @@
1−import {
2− bigint,
3− boolean,
4− index,
5− pgTable,
6− primaryKey,
7− text,
8− uniqueIndex,
9−} from "drizzle-orm/pg-core";
10−
11−import { tableNames } from "./schema";
12−
13−export const profileTable = pgTable(tableNames.profile, {
14− id: text("id").notNull().primaryKey(),
15− defaultWorkspaceId: text("default_workspace_id"),
16− displayName: text("display_name").notNull(),
17− runtimeMode: text("runtime_mode").notNull(),
18− createdAt: bigint("created_at", { mode: "number" }).notNull(),
19− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
20−});
21−
22−export const organizationsTable = pgTable(tableNames.organizations, {
23− id: text("id").notNull().primaryKey(),
24− slug: text("slug").notNull(),
25− name: text("name").notNull(),
26− status: text("status").notNull(),
27− createdByAccountId: text("created_by_account_id"),
28− createdAt: bigint("created_at", { mode: "number" }).notNull(),
29− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
30−});
31−
32−export const organizationMembershipsTable = pgTable(
33− tableNames.organizationMemberships,
34− {
35− id: text("id").notNull().primaryKey(),
36− organizationId: text("organization_id").notNull(),
37− accountId: text("account_id").notNull(),
38− role: text("role").notNull(),
39− status: text("status").notNull(),
40− billable: boolean("billable").notNull(),
41− invitedByAccountId: text("invited_by_account_id"),
42− joinedAt: bigint("joined_at", { mode: "number" }),
43− createdAt: bigint("created_at", { mode: "number" }).notNull(),
44− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
45− },
46− (table) => [
47− index("organization_memberships_org_idx").on(table.organizationId),
48− index("organization_memberships_account_idx").on(table.accountId),
49− ],
50−);
51−
52−export const workspacesTable = pgTable(
53− tableNames.workspaces,
54− {
55− id: text("id").notNull().primaryKey(),
56− organizationId: text("organization_id").notNull(),
57− name: text("name").notNull(),
58− createdByAccountId: text("created_by_account_id"),
59− createdAt: bigint("created_at", { mode: "number" }).notNull(),
60− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
61− },
62− (table) => [
63− index("workspaces_org_idx").on(table.organizationId),
64− ],
65−);
66−
67−export const sourcesTable = pgTable(
68− tableNames.sources,
69− {
70− workspaceId: text("workspace_id").notNull(),
71− sourceId: text("source_id").notNull(),
72− name: text("name").notNull(),
73− kind: text("kind").notNull(),
74− endpoint: text("endpoint").notNull(),
75− status: text("status").notNull(),
76− enabled: boolean("enabled").notNull(),
77− configJson: text("config_json").notNull(),
78− sourceHash: text("source_hash"),
79− lastError: text("last_error"),
80− createdAt: bigint("created_at", { mode: "number" }).notNull(),
81− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
82− },
83− (table) => [
84− primaryKey({
85− columns: [table.workspaceId, table.sourceId],
86− }),
87− index("sources_workspace_name_idx").on(table.workspaceId, table.name),
88− ],
89−);
90−
91−export const toolArtifactsTable = pgTable(
92− tableNames.toolArtifacts,
93− {
94− id: text("id").notNull(),
95− workspaceId: text("workspace_id").notNull(),
96− sourceId: text("source_id").notNull(),
97− sourceHash: text("source_hash").notNull(),
98− toolCount: bigint("tool_count", { mode: "number" }).notNull(),
99− manifestJson: text("manifest_json").notNull(),
100− createdAt: bigint("created_at", { mode: "number" }).notNull(),
101− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
102− },
103− (table) => [
104− primaryKey({
105− columns: [table.workspaceId, table.sourceId],
106− }),
107− uniqueIndex("tool_artifacts_id_idx").on(table.id),
108− ],
109−);
110−
111−export const authConnectionsTable = pgTable(
112− tableNames.authConnections,
113− {
114− id: text("id").notNull().primaryKey(),
115− organizationId: text("organization_id").notNull(),
116− workspaceId: text("workspace_id"),
117− accountId: text("account_id"),
118− ownerType: text("owner_type").notNull(),
119− strategy: text("strategy").notNull(),
120− displayName: text("display_name").notNull(),
121− status: text("status").notNull(),
122− statusReason: text("status_reason"),
123− lastAuthErrorClass: text("last_auth_error_class"),
124− metadataJson: text("metadata_json"),
125− additionalHeadersJson: text("additional_headers_json"),
126− createdByAccountId: text("created_by_account_id"),
127− createdAt: bigint("created_at", { mode: "number" }).notNull(),
128− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
129− lastUsedAt: bigint("last_used_at", { mode: "number" }),
130− },
131− (table) => [
132− index("auth_connections_org_idx").on(table.organizationId),
133− index("auth_connections_workspace_idx").on(table.workspaceId),
134− index("auth_connections_account_idx").on(table.accountId),
135− ],
136−);
137−
138−export const sourceAuthBindingsTable = pgTable(
139− tableNames.sourceAuthBindings,
140− {
141− id: text("id").notNull().primaryKey(),
142− sourceId: text("source_id").notNull(),
143− connectionId: text("connection_id").notNull(),
144− organizationId: text("organization_id").notNull(),
145− workspaceId: text("workspace_id"),
146− accountId: text("account_id"),
147− scopeType: text("scope_type").notNull(),
148− selector: text("selector"),
149− enabled: boolean("enabled").notNull(),
150− createdAt: bigint("created_at", { mode: "number" }).notNull(),
151− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
152− },
153− (table) => [
154− index("source_auth_bindings_source_idx").on(table.sourceId),
155− index("source_auth_bindings_connection_idx").on(table.connectionId),
156− index("source_auth_bindings_org_idx").on(table.organizationId),
157− index("source_auth_bindings_workspace_idx").on(table.workspaceId),
158− index("source_auth_bindings_account_idx").on(table.accountId),
159− ],
160−);
161−
162−export const authMaterialsTable = pgTable(
163− tableNames.authMaterials,
164− {
165− id: text("id").notNull().primaryKey(),
166− connectionId: text("connection_id").notNull(),
167− ciphertext: text("ciphertext").notNull(),
168− keyVersion: text("key_version").notNull(),
169− createdAt: bigint("created_at", { mode: "number" }).notNull(),
170− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
171− },
172− (table) => [
173− index("auth_materials_connection_idx").on(table.connectionId),
174− ],
175−);
176−
177−export const oauthStatesTable = pgTable(
178− tableNames.oauthStates,
179− {
180− id: text("id").notNull().primaryKey(),
181− connectionId: text("connection_id").notNull(),
182− accessTokenCiphertext: text("access_token_ciphertext").notNull(),
183− refreshTokenCiphertext: text("refresh_token_ciphertext"),
184− keyVersion: text("key_version").notNull(),
185− expiresAt: bigint("expires_at", { mode: "number" }),
186− scope: text("scope"),
187− tokenType: text("token_type"),
188− issuer: text("issuer"),
189− refreshConfigJson: text("refresh_config_json"),
190− tokenVersion: bigint("token_version", { mode: "number" }).notNull(),
191− leaseHolder: text("lease_holder"),
192− leaseExpiresAt: bigint("lease_expires_at", { mode: "number" }),
193− leaseFence: bigint("lease_fence", { mode: "number" }).notNull(),
194− lastRefreshAt: bigint("last_refresh_at", { mode: "number" }),
195− lastRefreshErrorClass: text("last_refresh_error_class"),
196− lastRefreshError: text("last_refresh_error"),
197− reauthRequiredAt: bigint("reauth_required_at", { mode: "number" }),
198− createdAt: bigint("created_at", { mode: "number" }).notNull(),
199− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
200− },
201− (table) => [
202− index("oauth_states_connection_idx").on(table.connectionId),
203− ],
204−);
205−
206−export const policiesTable = pgTable(
207− tableNames.policies,
208− {
209− id: text("id").notNull().primaryKey(),
210− workspaceId: text("workspace_id").notNull(),
211− toolPathPattern: text("tool_path_pattern").notNull(),
212− decision: text("decision").notNull(),
213− createdAt: bigint("created_at", { mode: "number" }).notNull(),
214− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
215− },
216− (table) => [
217− index("policies_workspace_idx").on(table.workspaceId),
218− ],
219−);
220−
221−export const approvalsTable = pgTable(
222− tableNames.approvals,
223− {
224− id: text("id").notNull().primaryKey(),
225− workspaceId: text("workspace_id").notNull(),
226− taskRunId: text("task_run_id").notNull(),
227− callId: text("call_id").notNull(),
228− toolPath: text("tool_path").notNull(),
229− status: text("status").notNull(),
230− inputPreviewJson: text("input_preview_json").notNull(),
231− reason: text("reason"),
232− requestedAt: bigint("requested_at", { mode: "number" }).notNull(),
233− resolvedAt: bigint("resolved_at", { mode: "number" }),
234− },
235− (table) => [
236− index("approvals_workspace_idx").on(table.workspaceId),
237− index("approvals_task_run_idx").on(table.taskRunId),
238− ],
239−);
240−
241−export const taskRunsTable = pgTable(
242− tableNames.taskRuns,
243− {
244− id: text("id").notNull().primaryKey(),
245− workspaceId: text("workspace_id").notNull(),
246− accountId: text("account_id").notNull(),
247− sessionId: text("session_id").notNull(),
248− runtimeId: text("runtime_id").notNull(),
249− codeHash: text("code_hash").notNull(),
250− status: text("status").notNull(),
251− startedAt: bigint("started_at", { mode: "number" }),
252− completedAt: bigint("completed_at", { mode: "number" }),
253− exitCode: bigint("exit_code", { mode: "number" }),
254− error: text("error"),
255− },
256− (table) => [
257− index("task_runs_workspace_idx").on(table.workspaceId),
258− ],
259−);
260−
261−export const storageInstancesTable = pgTable(
262− tableNames.storageInstances,
263− {
264− id: text("id").notNull().primaryKey(),
265− scopeType: text("scope_type").notNull(),
266− durability: text("durability").notNull(),
267− status: text("status").notNull(),
268− provider: text("provider").notNull(),
269− backendKey: text("backend_key").notNull(),
270− organizationId: text("organization_id").notNull(),
271− workspaceId: text("workspace_id"),
272− accountId: text("account_id"),
273− createdByAccountId: text("created_by_account_id"),
274− purpose: text("purpose"),
275− sizeBytes: bigint("size_bytes", { mode: "number" }),
276− fileCount: bigint("file_count", { mode: "number" }),
277− createdAt: bigint("created_at", { mode: "number" }).notNull(),
278− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
279− lastSeenAt: bigint("last_seen_at", { mode: "number" }).notNull(),
280− closedAt: bigint("closed_at", { mode: "number" }),
281− expiresAt: bigint("expires_at", { mode: "number" }),
282− },
283− (table) => [
284− index("storage_instances_org_idx").on(table.organizationId),
285− index("storage_instances_workspace_idx").on(table.workspaceId),
286− ],
287−);
288−
289−export const syncStatesTable = pgTable(
290− tableNames.syncStates,
291− {
292− id: text("id").notNull().primaryKey(),
293− workspaceId: text("workspace_id").notNull(),
294− target: text("target").notNull(),
295− targetUrl: text("target_url").notNull(),
296− linkedSubject: text("linked_subject"),
297− cursor: text("cursor"),
298− lastSyncAt: bigint("last_sync_at", { mode: "number" }),
299− updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
300− },
301− (table) => [
302− index("sync_states_workspace_idx").on(table.workspaceId),
303− ],
304−);
packages/persistence-sql/src/schema.ts+67−66
@@ -1,11 +1,12 @@
11 import {
2+ bigint,
3+ boolean,
24 index,
3− integer,
5+ pgTable,
46 primaryKey,
5− sqliteTable,
67 text,
78 uniqueIndex,
8−} from "drizzle-orm/sqlite-core";
9+} from "drizzle-orm/pg-core";
910
1011 export const tableNames = {
1112 profile: "profile",
@@ -25,26 +26,26 @@ export const tableNames = { · 13 unmodified lines
2526 syncStates: "sync_states",
2627 } as const;
2728
28−export const profileTable = sqliteTable(tableNames.profile, {
29+export const profileTable = pgTable(tableNames.profile, {
2930 id: text("id").notNull().primaryKey(),
3031 defaultWorkspaceId: text("default_workspace_id"),
3132 displayName: text("display_name").notNull(),
3233 runtimeMode: text("runtime_mode").notNull(),
33− createdAt: integer("created_at", { mode: "number" }).notNull(),
34− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
34+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
35+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
3536 });
3637
37−export const organizationsTable = sqliteTable(tableNames.organizations, {
38+export const organizationsTable = pgTable(tableNames.organizations, {
3839 id: text("id").notNull().primaryKey(),
3940 slug: text("slug").notNull(),
4041 name: text("name").notNull(),
4142 status: text("status").notNull(),
4243 createdByAccountId: text("created_by_account_id"),
43− createdAt: integer("created_at", { mode: "number" }).notNull(),
44− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
44+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
45+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
4546 });
4647
47−export const organizationMembershipsTable = sqliteTable(
48+export const organizationMembershipsTable = pgTable(
4849 tableNames.organizationMemberships,
4950 {
5051 id: text("id").notNull().primaryKey(),
@@ -52,11 +53,11 @@ export const organizationMembershipsTable = sqliteTable( · 1 unmodified line
5253 accountId: text("account_id").notNull(),
5354 role: text("role").notNull(),
5455 status: text("status").notNull(),
55− billable: integer("billable", { mode: "boolean" }).notNull(),
56+ billable: boolean("billable").notNull(),
5657 invitedByAccountId: text("invited_by_account_id"),
57− joinedAt: integer("joined_at", { mode: "number" }),
58− createdAt: integer("created_at", { mode: "number" }).notNull(),
59− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
58+ joinedAt: bigint("joined_at", { mode: "number" }),
59+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
60+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
6061 },
6162 (table) => [
6263 index("organization_memberships_org_idx").on(table.organizationId),
@@ -64,22 +65,22 @@ export const organizationMembershipsTable = sqliteTable( · 1 unmodified line
6465 ],
6566 );
6667
67−export const workspacesTable = sqliteTable(
68+export const workspacesTable = pgTable(
6869 tableNames.workspaces,
6970 {
7071 id: text("id").notNull().primaryKey(),
7172 organizationId: text("organization_id").notNull(),
7273 name: text("name").notNull(),
7374 createdByAccountId: text("created_by_account_id"),
74− createdAt: integer("created_at", { mode: "number" }).notNull(),
75− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
75+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
76+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
7677 },
7778 (table) => [
7879 index("workspaces_org_idx").on(table.organizationId),
7980 ],
8081 );
8182
82−export const sourcesTable = sqliteTable(
83+export const sourcesTable = pgTable(
8384 tableNames.sources,
8485 {
8586 workspaceId: text("workspace_id").notNull(),
@@ -88,12 +89,12 @@ export const sourcesTable = sqliteTable( · 2 unmodified lines
8889 kind: text("kind").notNull(),
8990 endpoint: text("endpoint").notNull(),
9091 status: text("status").notNull(),
91− enabled: integer("enabled", { mode: "boolean" }).notNull(),
92+ enabled: boolean("enabled").notNull(),
9293 configJson: text("config_json").notNull(),
9394 sourceHash: text("source_hash"),
9495 lastError: text("last_error"),
95− createdAt: integer("created_at", { mode: "number" }).notNull(),
96− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
96+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
97+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
9798 },
9899 (table) => [
99100 primaryKey({
@@ -103,17 +104,17 @@ export const sourcesTable = sqliteTable( · 3 unmodified lines
103104 ],
104105 );
105106
106−export const toolArtifactsTable = sqliteTable(
107+export const toolArtifactsTable = pgTable(
107108 tableNames.toolArtifacts,
108109 {
109110 id: text("id").notNull(),
110111 workspaceId: text("workspace_id").notNull(),
111112 sourceId: text("source_id").notNull(),
112113 sourceHash: text("source_hash").notNull(),
113− toolCount: integer("tool_count", { mode: "number" }).notNull(),
114+ toolCount: bigint("tool_count", { mode: "number" }).notNull(),
114115 manifestJson: text("manifest_json").notNull(),
115− createdAt: integer("created_at", { mode: "number" }).notNull(),
116− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
116+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
117+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
117118 },
118119 (table) => [
119120 primaryKey({
@@ -123,7 +124,7 @@ export const toolArtifactsTable = sqliteTable( · 3 unmodified lines
123124 ],
124125 );
125126
126−export const authConnectionsTable = sqliteTable(
127+export const authConnectionsTable = pgTable(
127128 tableNames.authConnections,
128129 {
129130 id: text("id").notNull().primaryKey(),
@@ -139,9 +140,9 @@ export const authConnectionsTable = sqliteTable( · 9 unmodified lines
139140 metadataJson: text("metadata_json"),
140141 additionalHeadersJson: text("additional_headers_json"),
141142 createdByAccountId: text("created_by_account_id"),
142− createdAt: integer("created_at", { mode: "number" }).notNull(),
143− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
144− lastUsedAt: integer("last_used_at", { mode: "number" }),
143+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
144+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
145+ lastUsedAt: bigint("last_used_at", { mode: "number" }),
145146 },
146147 (table) => [
147148 index("auth_connections_org_idx").on(table.organizationId),
@@ -150,7 +151,7 @@ export const authConnectionsTable = sqliteTable( · 2 unmodified lines
150151 ],
151152 );
152153
153−export const sourceAuthBindingsTable = sqliteTable(
154+export const sourceAuthBindingsTable = pgTable(
154155 tableNames.sourceAuthBindings,
155156 {
156157 id: text("id").notNull().primaryKey(),
@@ -161,9 +162,9 @@ export const sourceAuthBindingsTable = sqliteTable( · 4 unmodified lines
161162 accountId: text("account_id"),
162163 scopeType: text("scope_type").notNull(),
163164 selector: text("selector"),
164− enabled: integer("enabled", { mode: "boolean" }).notNull(),
165− createdAt: integer("created_at", { mode: "number" }).notNull(),
166− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
165+ enabled: boolean("enabled").notNull(),
166+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
167+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
167168 },
168169 (table) => [
169170 index("source_auth_bindings_source_idx").on(table.sourceId),
@@ -174,22 +175,22 @@ export const sourceAuthBindingsTable = sqliteTable( · 4 unmodified lines
174175 ],
175176 );
176177
177−export const authMaterialsTable = sqliteTable(
178+export const authMaterialsTable = pgTable(
178179 tableNames.authMaterials,
179180 {
180181 id: text("id").notNull().primaryKey(),
181182 connectionId: text("connection_id").notNull(),
182183 ciphertext: text("ciphertext").notNull(),
183184 keyVersion: text("key_version").notNull(),
184− createdAt: integer("created_at", { mode: "number" }).notNull(),
185− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
185+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
186+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
186187 },
187188 (table) => [
188189 index("auth_materials_connection_idx").on(table.connectionId),
189190 ],
190191 );
191192
192−export const oauthStatesTable = sqliteTable(
193+export const oauthStatesTable = pgTable(
193194 tableNames.oauthStates,
194195 {
195196 id: text("id").notNull().primaryKey(),
@@ -197,43 +198,43 @@ export const oauthStatesTable = sqliteTable( · 1 unmodified line
197198 accessTokenCiphertext: text("access_token_ciphertext").notNull(),
198199 refreshTokenCiphertext: text("refresh_token_ciphertext"),
199200 keyVersion: text("key_version").notNull(),
200− expiresAt: integer("expires_at", { mode: "number" }),
201+ expiresAt: bigint("expires_at", { mode: "number" }),
201202 scope: text("scope"),
202203 tokenType: text("token_type"),
203204 issuer: text("issuer"),
204205 refreshConfigJson: text("refresh_config_json"),
205− tokenVersion: integer("token_version", { mode: "number" }).notNull(),
206+ tokenVersion: bigint("token_version", { mode: "number" }).notNull(),
206207 leaseHolder: text("lease_holder"),
207− leaseExpiresAt: integer("lease_expires_at", { mode: "number" }),
208− leaseFence: integer("lease_fence", { mode: "number" }).notNull(),
209− lastRefreshAt: integer("last_refresh_at", { mode: "number" }),
208+ leaseExpiresAt: bigint("lease_expires_at", { mode: "number" }),
209+ leaseFence: bigint("lease_fence", { mode: "number" }).notNull(),
210+ lastRefreshAt: bigint("last_refresh_at", { mode: "number" }),
210211 lastRefreshErrorClass: text("last_refresh_error_class"),
211212 lastRefreshError: text("last_refresh_error"),
212− reauthRequiredAt: integer("reauth_required_at", { mode: "number" }),
213− createdAt: integer("created_at", { mode: "number" }).notNull(),
214− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
213+ reauthRequiredAt: bigint("reauth_required_at", { mode: "number" }),
214+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
215+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
215216 },
216217 (table) => [
217218 index("oauth_states_connection_idx").on(table.connectionId),
218219 ],
219220 );
220221
221−export const policiesTable = sqliteTable(
222+export const policiesTable = pgTable(
222223 tableNames.policies,
223224 {
224225 id: text("id").notNull().primaryKey(),
225226 workspaceId: text("workspace_id").notNull(),
226227 toolPathPattern: text("tool_path_pattern").notNull(),
227228 decision: text("decision").notNull(),
228− createdAt: integer("created_at", { mode: "number" }).notNull(),
229− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
229+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
230+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
230231 },
231232 (table) => [
232233 index("policies_workspace_idx").on(table.workspaceId),
233234 ],
234235 );
235236
236−export const approvalsTable = sqliteTable(
237+export const approvalsTable = pgTable(
237238 tableNames.approvals,
238239 {
239240 id: text("id").notNull().primaryKey(),
@@ -244,8 +245,8 @@ export const approvalsTable = sqliteTable( · 4 unmodified lines
244245 status: text("status").notNull(),
245246 inputPreviewJson: text("input_preview_json").notNull(),
246247 reason: text("reason"),
247− requestedAt: integer("requested_at", { mode: "number" }).notNull(),
248− resolvedAt: integer("resolved_at", { mode: "number" }),
248+ requestedAt: bigint("requested_at", { mode: "number" }).notNull(),
249+ resolvedAt: bigint("resolved_at", { mode: "number" }),
249250 },
250251 (table) => [
251252 index("approvals_workspace_idx").on(table.workspaceId),
@@ -253,7 +254,7 @@ export const approvalsTable = sqliteTable( · 1 unmodified line
253254 ],
254255 );
255256
256−export const taskRunsTable = sqliteTable(
257+export const taskRunsTable = pgTable(
257258 tableNames.taskRuns,
258259 {
259260 id: text("id").notNull().primaryKey(),
@@ -263,9 +264,9 @@ export const taskRunsTable = sqliteTable( · 3 unmodified lines
263264 runtimeId: text("runtime_id").notNull(),
264265 codeHash: text("code_hash").notNull(),
265266 status: text("status").notNull(),
266− startedAt: integer("started_at", { mode: "number" }),
267− completedAt: integer("completed_at", { mode: "number" }),
268− exitCode: integer("exit_code", { mode: "number" }),
267+ startedAt: bigint("started_at", { mode: "number" }),
268+ completedAt: bigint("completed_at", { mode: "number" }),
269+ exitCode: bigint("exit_code", { mode: "number" }),
269270 error: text("error"),
270271 },
271272 (table) => [
@@ -273,7 +274,7 @@ export const taskRunsTable = sqliteTable( · 1 unmodified line
273274 ],
274275 );
275276
276−export const storageInstancesTable = sqliteTable(
277+export const storageInstancesTable = pgTable(
277278 tableNames.storageInstances,
278279 {
279280 id: text("id").notNull().primaryKey(),
@@ -287,13 +288,13 @@ export const storageInstancesTable = sqliteTable( · 7 unmodified lines
287288 accountId: text("account_id"),
288289 createdByAccountId: text("created_by_account_id"),
289290 purpose: text("purpose"),
290− sizeBytes: integer("size_bytes", { mode: "number" }),
291− fileCount: integer("file_count", { mode: "number" }),
292− createdAt: integer("created_at", { mode: "number" }).notNull(),
293− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
294− lastSeenAt: integer("last_seen_at", { mode: "number" }).notNull(),
295− closedAt: integer("closed_at", { mode: "number" }),
296− expiresAt: integer("expires_at", { mode: "number" }),
291+ sizeBytes: bigint("size_bytes", { mode: "number" }),
292+ fileCount: bigint("file_count", { mode: "number" }),
293+ createdAt: bigint("created_at", { mode: "number" }).notNull(),
294+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
295+ lastSeenAt: bigint("last_seen_at", { mode: "number" }).notNull(),
296+ closedAt: bigint("closed_at", { mode: "number" }),
297+ expiresAt: bigint("expires_at", { mode: "number" }),
297298 },
298299 (table) => [
299300 index("storage_instances_org_idx").on(table.organizationId),
@@ -301,7 +302,7 @@ export const storageInstancesTable = sqliteTable( · 1 unmodified line
301302 ],
302303 );
303304
304−export const syncStatesTable = sqliteTable(
305+export const syncStatesTable = pgTable(
305306 tableNames.syncStates,
306307 {
307308 id: text("id").notNull().primaryKey(),
@@ -310,8 +311,8 @@ export const syncStatesTable = sqliteTable( · 2 unmodified lines
310311 targetUrl: text("target_url").notNull(),
311312 linkedSubject: text("linked_subject"),
312313 cursor: text("cursor"),
313− lastSyncAt: integer("last_sync_at", { mode: "number" }),
314− updatedAt: integer("updated_at", { mode: "number" }).notNull(),
314+ lastSyncAt: bigint("last_sync_at", { mode: "number" }),
315+ updatedAt: bigint("updated_at", { mode: "number" }).notNull(),
315316 },
316317 (table) => [
317318 index("sync_states_workspace_idx").on(table.workspaceId),
packages/persistence-sql/src/sql-internals.ts+306−0
@@ -0,0 +1,306 @@
1+import { PGlite } from "@electric-sql/pglite";
2+import { drizzle as drizzlePgProxy } from "drizzle-orm/pg-proxy";
3+import { migrate as migratePgProxy } from "drizzle-orm/pg-proxy/migrator";
4+import { existsSync } from "node:fs";
5+import { mkdir } from "node:fs/promises";
6+import * as path from "node:path";
7+import { fileURLToPath } from "node:url";
8+import postgres, { type Sql } from "postgres";
9+
10+import {
11+ approvalsTable,
12+ authConnectionsTable,
13+ authMaterialsTable,
14+ oauthStatesTable,
15+ organizationMembershipsTable,
16+ organizationsTable,
17+ policiesTable,
18+ profileTable,
19+ sourceAuthBindingsTable,
20+ sourcesTable,
21+ storageInstancesTable,
22+ syncStatesTable,
23+ taskRunsTable,
24+ toolArtifactsTable,
25+ workspacesTable,
26+} from "./schema";
27+
28+export type SqlBackend = "pglite" | "postgres";
29+type SqlRow = Record<string, unknown>;
30+
31+export type SqlAdapter = {
32+ readonly backend: SqlBackend;
33+ query: <TRow extends SqlRow = SqlRow>(
34+ statement: string,
35+ args?: ReadonlyArray<unknown>,
36+ ) => Promise<Array<TRow>>;
37+ execute: (statement: string, args?: ReadonlyArray<unknown>) => Promise<void>;
38+ transaction: <A>(run: (transaction: SqlAdapter) => Promise<A>) => Promise<A>;
39+ close: () => Promise<void>;
40+};
41+
42+const withPostgresPlaceholders = (statement: string): string => {
43+ let index = 0;
44+ return statement.replace(/\?/g, () => {
45+ index += 1;
46+ return `$${index}`;
47+ });
48+};
49+
50+const toPostgresStatement = (statement: string): string => withPostgresPlaceholders(statement);
51+
52+const makePGliteTransaction = (
53+ execute: (statement: string, args?: ReadonlyArray<unknown>) => Promise<void>,
54+ query: <TRow extends SqlRow = SqlRow>(
55+ statement: string,
56+ args?: ReadonlyArray<unknown>,
57+ ) => Promise<Array<TRow>>,
58+): SqlAdapter["transaction"] =>
59+ async <A>(run: (transactionAdapter: SqlAdapter) => Promise<A>): Promise<A> => {
60+ await execute("BEGIN");
61+
62+ try {
63+ const adapter: SqlAdapter = {
64+ backend: "pglite",
65+ query,
66+ execute,
67+ transaction: async (nestedRun) => nestedRun(adapter),
68+ close: async () => {},
69+ };
70+
71+ const result = await run(adapter);
72+ await execute("COMMIT");
73+ return result;
74+ } catch (error) {
75+ try {
76+ await execute("ROLLBACK");
77+ } catch {
78+ // ignore rollback failure after original error
79+ }
80+
81+ throw error;
82+ }
83+ };
84+
85+export const createPGliteAdapter = async (localDataDir: string): Promise<SqlAdapter> => {
86+ const resolvedDataDir = path.resolve(localDataDir);
87+ await mkdir(path.dirname(resolvedDataDir), { recursive: true });
88+
89+ const db = new PGlite(resolvedDataDir);
90+
91+ const query = async <TRow extends SqlRow = SqlRow>(
92+ statement: string,
93+ args: ReadonlyArray<unknown> = [],
94+ ): Promise<Array<TRow>> => {
95+ const result = await db.query(toPostgresStatement(statement), [...args]);
96+ return result.rows as Array<TRow>;
97+ };
98+
99+ const execute = async (
100+ statement: string,
101+ args: ReadonlyArray<unknown> = [],
102+ ): Promise<void> => {
103+ await db.query(toPostgresStatement(statement), [...args]);
104+ };
105+
106+ return {
107+ backend: "pglite",
108+ query,
109+ execute,
110+ transaction: makePGliteTransaction(execute, query),
111+ close: async () => {
112+ await db.close();
113+ },
114+ };
115+};
116+
117+export const createPostgresAdapter = async (
118+ databaseUrl: string,
119+ applicationName: string | undefined,
120+): Promise<SqlAdapter> => {
121+ const client = postgres(databaseUrl, {
122+ prepare: false,
123+ max: 10,
124+ ...(applicationName ? { connection: { application_name: applicationName } } : {}),
125+ });
126+
127+ type UnsafeRunner = {
128+ unsafe: Sql["unsafe"];
129+ };
130+
131+ const toPostgresParams = (
132+ args: ReadonlyArray<unknown>,
133+ ): Array<postgres.ParameterOrJSON<never>> =>
134+ args as unknown as Array<postgres.ParameterOrJSON<never>>;
135+
136+ const queryWith = async <TRow extends SqlRow = SqlRow>(
137+ runner: UnsafeRunner,
138+ statement: string,
139+ args: ReadonlyArray<unknown> = [],
140+ ): Promise<Array<TRow>> =>
141+ (await runner.unsafe(
142+ toPostgresStatement(statement),
143+ toPostgresParams(args),
144+ )) as unknown as Array<TRow>;
145+
146+ const executeWith = async (
147+ runner: UnsafeRunner,
148+ statement: string,
149+ args: ReadonlyArray<unknown> = [],
150+ ): Promise<void> => {
151+ await runner.unsafe(
152+ toPostgresStatement(statement),
153+ toPostgresParams(args),
154+ );
155+ };
156+
157+ const adapter: SqlAdapter = {
158+ backend: "postgres",
159+ query: (statement, args = []) => queryWith(client, statement, args),
160+ execute: (statement, args = []) => executeWith(client, statement, args),
161+ transaction: async <A>(run: (transaction: SqlAdapter) => Promise<A>) => {
162+ const result = await client.begin(async (transactionClient) => {
163+ const runner: UnsafeRunner = transactionClient;
164+ const transactionAdapter: SqlAdapter = {
165+ backend: "postgres",
166+ query: (statement, args = []) => queryWith(runner, statement, args),
167+ execute: (statement, args = []) => executeWith(runner, statement, args),
168+ transaction: async (nestedRun) => nestedRun(transactionAdapter),
169+ close: async () => {},
170+ };
171+
172+ return run(transactionAdapter);
173+ });
174+
175+ return result as A;
176+ },
177+ close: async () => {
178+ await client.end({ timeout: 5 });
179+ },
180+ };
181+
182+ return adapter;
183+};
184+
185+const resolveDrizzleMigrationsFolder = (): string => {
186+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
187+ const packageRoot = path.resolve(moduleDir, "..");
188+ const cwd = process.cwd();
189+ const candidates = [
190+ path.resolve(packageRoot, "drizzle"),
191+ path.resolve(cwd, "packages/persistence-sql/drizzle"),
192+ path.resolve(cwd, "../packages/persistence-sql/drizzle"),
193+ path.resolve(cwd, "../../packages/persistence-sql/drizzle"),
194+ ];
195+
196+ for (const candidate of candidates) {
197+ if (existsSync(path.join(candidate, "meta", "_journal.json"))) {
198+ return candidate;
199+ }
200+ }
201+
202+ throw new Error("Unable to resolve drizzle migrations folder");
203+};
204+
205+const runMigrationQueries = async (
206+ adapter: SqlAdapter,
207+ queries: ReadonlyArray<string>,
208+): Promise<void> => {
209+ for (const query of queries) {
210+ const statement = query.trim();
211+ if (statement.length === 0) {
212+ continue;
213+ }
214+
215+ await adapter.execute(statement);
216+ }
217+};
218+
219+const toProxyRow = (row: unknown): unknown => {
220+ if (Array.isArray(row) || row === null || row === undefined) {
221+ return row;
222+ }
223+
224+ if (typeof row === "object") {
225+ return Object.values(row as Record<string, unknown>);
226+ }
227+
228+ return row;
229+};
230+
231+const normalizeProxyRows = (
232+ method: "execute" | "all" | "values" | "get",
233+ rows: ReadonlyArray<unknown>,
234+): Array<unknown> => {
235+ if (method === "get") {
236+ const first = rows[0];
237+ return first === undefined ? [] : [toProxyRow(first)];
238+ }
239+
240+ return rows.map(toProxyRow);
241+};
242+
243+const drizzleSchema = {
244+ profileTable,
245+ organizationsTable,
246+ organizationMembershipsTable,
247+ workspacesTable,
248+ sourcesTable,
249+ toolArtifactsTable,
250+ authConnectionsTable,
251+ sourceAuthBindingsTable,
252+ authMaterialsTable,
253+ oauthStatesTable,
254+ policiesTable,
255+ approvalsTable,
256+ taskRunsTable,
257+ storageInstancesTable,
258+ syncStatesTable,
259+};
260+
261+type DrizzleSchema = typeof drizzleSchema;
262+type PostgresDrizzleDb = ReturnType<typeof drizzlePgProxy<DrizzleSchema>>;
263+
264+export type DrizzleDb = PostgresDrizzleDb;
265+export type DrizzleTables = DrizzleSchema;
266+
267+export type DrizzleContext = {
268+ db: DrizzleDb;
269+ tables: DrizzleTables;
270+};
271+
272+const createPostgresProxyDb = (adapter: SqlAdapter): PostgresDrizzleDb =>
273+ drizzlePgProxy(
274+ async (statement, params, method) => {
275+ if (method === "execute") {
276+ await adapter.execute(statement, params);
277+ return { rows: [] };
278+ }
279+
280+ const rows = await adapter.query(statement, params);
281+ return {
282+ rows: normalizeProxyRows(method, rows),
283+ };
284+ },
285+ {
286+ schema: drizzleSchema,
287+ },
288+ );
289+
290+export const createDrizzleContext = (adapter: SqlAdapter): DrizzleContext => ({
291+ db: createPostgresProxyDb(adapter),
292+ tables: drizzleSchema,
293+});
294+
295+export const runMigrations = async (adapter: SqlAdapter): Promise<void> => {
296+ const migrationDb = createPostgresProxyDb(adapter);
297+ const migrationsFolder = resolveDrizzleMigrationsFolder();
298+
299+ await migratePgProxy(
300+ migrationDb,
301+ async (queries) => runMigrationQueries(adapter, queries),
302+ {
303+ migrationsFolder,
304+ },
305+ );
306+};