Skip to content

Commit ac86d4a

Browse files
committed
fix: lazy init db pool + add init.sql schema
1 parent 9468586 commit ac86d4a

2 files changed

Lines changed: 86 additions & 8 deletions

File tree

init.sql

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
CREATE TABLE IF NOT EXISTS users (
2+
id TEXT PRIMARY KEY,
3+
email TEXT NOT NULL,
4+
email_hash TEXT UNIQUE NOT NULL,
5+
password_hash TEXT NOT NULL,
6+
username TEXT,
7+
avatar_url TEXT,
8+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
9+
);
10+
11+
CREATE UNIQUE INDEX IF NOT EXISTS users_email_hash_uidx ON users (email_hash) WHERE email_hash IS NOT NULL;
12+
13+
CREATE TABLE IF NOT EXISTS redirects (
14+
id TEXT PRIMARY KEY,
15+
url TEXT NOT NULL,
16+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
17+
clicks INTEGER DEFAULT 0,
18+
user_id TEXT REFERENCES users(id),
19+
version TEXT DEFAULT 'dash',
20+
expires_at TIMESTAMP,
21+
countdown_seconds INTEGER DEFAULT 5
22+
);
23+
24+
CREATE INDEX IF NOT EXISTS redirects_user_id_idx ON redirects (user_id);
25+
26+
CREATE TABLE IF NOT EXISTS redirect_click_events (
27+
id BIGSERIAL PRIMARY KEY,
28+
redirect_id TEXT NOT NULL REFERENCES redirects(id) ON DELETE CASCADE,
29+
clicked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
30+
referrer_host TEXT,
31+
source_type TEXT,
32+
country_code TEXT,
33+
user_agent TEXT,
34+
ip_address TEXT,
35+
language TEXT,
36+
device_type TEXT,
37+
os_name TEXT,
38+
browser_name TEXT,
39+
city TEXT,
40+
region TEXT,
41+
timezone TEXT,
42+
screen_resolution TEXT,
43+
viewport_size TEXT,
44+
interpage_time_ms INTEGER,
45+
connection_type TEXT,
46+
color_scheme TEXT,
47+
device_memory REAL,
48+
hardware_concurrency INTEGER,
49+
is_bot BOOLEAN DEFAULT FALSE,
50+
referrer_url TEXT,
51+
asn TEXT
52+
);
53+
54+
CREATE INDEX IF NOT EXISTS redirect_click_events_redirect_id_idx ON redirect_click_events (redirect_id);
55+
CREATE INDEX IF NOT EXISTS redirect_click_events_clicked_at_idx ON redirect_click_events (clicked_at);
56+
CREATE INDEX IF NOT EXISTS redirect_click_events_source_type_idx ON redirect_click_events (source_type);
57+
CREATE INDEX IF NOT EXISTS redirect_click_events_referrer_host_idx ON redirect_click_events (referrer_host);
58+
CREATE INDEX IF NOT EXISTS redirect_click_events_device_type_idx ON redirect_click_events (device_type);
59+
CREATE INDEX IF NOT EXISTS redirect_click_events_browser_name_idx ON redirect_click_events (browser_name);
60+
61+
CREATE TABLE IF NOT EXISTS redirect_wait_events (
62+
id BIGSERIAL PRIMARY KEY,
63+
redirect_id TEXT NOT NULL REFERENCES redirects(id) ON DELETE CASCADE,
64+
event_token TEXT NOT NULL UNIQUE,
65+
status TEXT NOT NULL DEFAULT 'pending',
66+
started_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
67+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
68+
);
69+
70+
CREATE UNIQUE INDEX IF NOT EXISTS redirect_wait_events_event_token_uidx ON redirect_wait_events (event_token);
71+
CREATE INDEX IF NOT EXISTS redirect_wait_events_redirect_id_idx ON redirect_wait_events (redirect_id);
72+
CREATE INDEX IF NOT EXISTS redirect_wait_events_status_idx ON redirect_wait_events (status);

lib/db.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
import { Pool } from 'pg';
22

3-
const rawUrl = process.env.POSTGRES_URL ?? '';
4-
const url = new URL(rawUrl);
5-
url.searchParams.delete('sslmode');
3+
let pool: Pool | null = null;
64

7-
const pool = new Pool({
8-
connectionString: url.toString(),
9-
ssl: { rejectUnauthorized: false },
10-
});
5+
function getPool(): Pool {
6+
if (!pool) {
7+
const rawUrl = process.env.POSTGRES_URL ?? '';
8+
const url = new URL(rawUrl);
9+
url.searchParams.delete('sslmode');
10+
pool = new Pool({
11+
connectionString: url.toString(),
12+
ssl: { rejectUnauthorized: false },
13+
});
14+
}
15+
return pool;
16+
}
1117

1218
function sql(strings: TemplateStringsArray, ...values: unknown[]) {
1319
let text = '';
@@ -19,7 +25,7 @@ function sql(strings: TemplateStringsArray, ...values: unknown[]) {
1925
text += `$${params.length}`;
2026
}
2127
});
22-
return pool.query(text, params);
28+
return getPool().query(text, params);
2329
}
2430

2531
export { sql };

0 commit comments

Comments
 (0)