Skip to content

Commit 6ced583

Browse files
committed
Try pg Pool
1 parent ab39fa9 commit 6ced583

File tree

4 files changed

+59
-19
lines changed

4 files changed

+59
-19
lines changed

bun.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

lib/utils/useDatabase.ts

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
import { attachDatabasePool } from "@vercel/functions";
12
import { sql } from "drizzle-orm";
23
import { drizzle } from "drizzle-orm/node-postgres";
34
import { err, ok, type Result } from "neverthrow";
5+
import { Pool } from "pg";
46
import type { Database } from "@/drizzle/types";
57
import * as schema from "../../drizzle/schema";
68
import { getOwner } from "./useOwner";
79

8-
const dbInstances = new Map<string, Database>();
10+
const poolInstances = new Map<string, Pool>();
911

1012
export function getDatabaseName(ownerId: string): Result<string, string> {
1113
if (!ownerId.startsWith("org_") && !ownerId.startsWith("user_")) {
@@ -31,19 +33,22 @@ export async function getDatabaseForOwner(ownerId: string): Promise<Database> {
3133
},
3234
);
3335

34-
const sslMode = process.env.DATABASE_SSL === "true" ? "?sslmode=require" : "";
35-
const connectionString = `${process.env.DATABASE_URL}/${databaseName}${sslMode}`;
36-
37-
if (!dbInstances.has(ownerId)) {
38-
dbInstances.set(
39-
ownerId,
40-
drizzle(connectionString, {
41-
schema,
42-
}),
43-
);
36+
if (!poolInstances.has(ownerId)) {
37+
const sslMode = process.env.DATABASE_SSL === "true" ? "?sslmode=require" : "";
38+
const connectionString = `${process.env.DATABASE_URL}/${databaseName}${sslMode}`;
39+
40+
const pool = new Pool({
41+
connectionString,
42+
min: 1,
43+
idleTimeoutMillis: 5000,
44+
connectionTimeoutMillis: 5000,
45+
});
46+
47+
attachDatabasePool(pool);
48+
poolInstances.set(ownerId, pool);
4449
}
4550

46-
return dbInstances.get(ownerId)!;
51+
return drizzle(poolInstances.get(ownerId)!, { schema });
4752
}
4853

4954
export async function deleteDatabase(ownerId: string) {
@@ -54,22 +59,32 @@ export async function deleteDatabase(ownerId: string) {
5459
},
5560
);
5661

57-
const sslMode = process.env.DATABASE_SSL === "true" ? "?sslmode=require" : "";
62+
const pool = poolInstances.get(ownerId);
63+
if (pool) {
64+
await pool.end();
65+
poolInstances.delete(ownerId);
66+
}
5867

59-
const ownerDb = drizzle(`${process.env.DATABASE_URL}/manage${sslMode}`, {
60-
schema,
68+
const sslMode = process.env.DATABASE_SSL === "true" ? "?sslmode=require" : "";
69+
const managePool = new Pool({
70+
connectionString: `${process.env.DATABASE_URL}/manage${sslMode}`,
71+
min: 1,
72+
idleTimeoutMillis: 5000,
73+
connectionTimeoutMillis: 5000,
6174
});
6275

63-
// Terminate all connections to the database before dropping
76+
const ownerDb = drizzle(managePool, { schema });
77+
6478
await ownerDb.execute(sql`
6579
SELECT pg_terminate_backend(pid)
6680
FROM pg_stat_activity
6781
WHERE datname = ${databaseName}
6882
AND pid <> pg_backend_pid()
6983
`);
7084

71-
// Drop the database with FORCE option (PostgreSQL 13+)
7285
await ownerDb.execute(
7386
sql`DROP DATABASE ${sql.identifier(databaseName)} WITH (FORCE)`,
7487
);
88+
89+
await managePool.end();
7590
}

ops/useOps.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
1+
import { attachDatabasePool } from "@vercel/functions";
12
import type { UserJSON } from "@clerk/nextjs/server";
23
import { drizzle } from "drizzle-orm/node-postgres";
4+
import { Pool } from "pg";
35
import * as schema from "./drizzle/schema";
46
import type { OpsDatabase } from "./drizzle/types";
57

8+
let opsPool: Pool | null = null;
9+
let opsDb: OpsDatabase | null = null;
10+
611
export async function getOpsDatabase(): Promise<OpsDatabase> {
7-
const sslMode = process.env.DATABASE_SSL === "true" ? "?sslmode=require" : "";
8-
return drizzle(`${process.env.DATABASE_URL}/manage${sslMode}`, { schema });
12+
if (!opsDb) {
13+
const sslMode = process.env.DATABASE_SSL === "true" ? "?sslmode=require" : "";
14+
const connectionString = `${process.env.DATABASE_URL}/manage${sslMode}`;
15+
16+
opsPool = new Pool({
17+
connectionString,
18+
min: 1,
19+
idleTimeoutMillis: 5000,
20+
connectionTimeoutMillis: 5000,
21+
});
22+
23+
attachDatabasePool(opsPool);
24+
opsDb = drizzle(opsPool, { schema });
25+
}
26+
27+
return opsDb;
928
}
1029

1130
export async function addUserToOpsDb(userData: UserJSON) {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"@upstash/redis": "^1.35.3",
5353
"@upstash/search": "^0.1.5",
5454
"@upstash/workflow": "^0.2.16",
55+
"@vercel/functions": "^3.1.4",
5556
"autoprefixer": "10.4.14",
5657
"caniuse-lite": "^1.0.30001737",
5758
"class-variance-authority": "^0.7.1",

0 commit comments

Comments
 (0)