You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
6.1 KiB
162 lines
6.1 KiB
import pg from "pg";
|
|
|
|
// Create a connection pool instead of individual connections
|
|
const pool = new pg.Pool({
|
|
user: process.env.POSTGRES_USER,
|
|
password: process.env.POSTGRES_PASSWORD,
|
|
host: process.env.POSTGRES_HOST,
|
|
database: process.env.POSTGRES_DB,
|
|
port: 5432,
|
|
max: 30, // Increased maximum number of connections in the pool
|
|
idleTimeoutMillis: 30000, // Close idle connections after 30 seconds
|
|
connectionTimeoutMillis: 10000, // Increased timeout to 10 seconds
|
|
acquireTimeoutMillis: 10000, // Wait up to 10 seconds for a connection
|
|
});
|
|
|
|
export async function getClient() {
|
|
// Use pool.connect() instead of creating new clients
|
|
return await pool.connect();
|
|
}
|
|
|
|
// Graceful shutdown
|
|
process.on('SIGINT', () => {
|
|
pool.end(() => {
|
|
console.log('Pool has ended');
|
|
process.exit(0);
|
|
});
|
|
});
|
|
|
|
export async function initDb() {
|
|
|
|
const client = await getClient();
|
|
|
|
try {
|
|
let query = `CREATE TABLE IF NOT EXISTS users (
|
|
id SERIAL PRIMARY KEY,
|
|
email VARCHAR(255),
|
|
username VARCHAR(255) NOT NULL,
|
|
password VARCHAR(255),
|
|
picture VARCHAR(255),
|
|
is_verified BOOLEAN NOT NULL DEFAULT FALSE,
|
|
github_id VARCHAR(255) UNIQUE,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS channels (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
description TEXT NOT NULL,
|
|
owner INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
|
|
)`
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS videos (
|
|
id SERIAL PRIMARY KEY,
|
|
title VARCHAR(255) NOT NULL,
|
|
thumbnail VARCHAR(255) NOT NULL,
|
|
description TEXT NOT NULL,
|
|
channel INTEGER NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
visibility VARCHAR(50) NOT NULL DEFAULT 'public',
|
|
file VARCHAR(255) NOT NULL,
|
|
slug VARCHAR(255) NOT NULL,
|
|
format VARCHAR(50) NOT NULL,
|
|
release_date TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS comments
|
|
(
|
|
id SERIAL PRIMARY KEY,
|
|
content TEXT NOT NULL,
|
|
author INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
)`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS likes (
|
|
id SERIAL PRIMARY KEY,
|
|
owner INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
);`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS playlists (
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
owner INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
|
|
)`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS playlist_elements (
|
|
id SERIAL PRIMARY KEY,
|
|
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
|
|
playlist INTEGER NOT NULL REFERENCES playlists(id) ON DELETE CASCADE
|
|
)`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS subscriptions (
|
|
id SERIAL PRIMARY KEY,
|
|
channel INTEGER NOT NULL REFERENCES channels(id) ON DELETE CASCADE,
|
|
owner INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
|
|
)`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS tags(
|
|
id SERIAL PRIMARY KEY,
|
|
name VARCHAR(255) NOT NULL,
|
|
usage_count INTEGER NOT NULL DEFAULT 0
|
|
)`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS video_tags (
|
|
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
|
|
tag INTEGER NOT NULL REFERENCES tags(id) ON DELETE CASCADE
|
|
)`
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS history (
|
|
id SERIAL PRIMARY KEY,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
video INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
|
|
viewed_at TIMESTAMP NOT NULL DEFAULT NOW()
|
|
)`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS email_verification (
|
|
id SERIAL PRIMARY KEY,
|
|
email VARCHAR(255) NOT NULL,
|
|
token VARCHAR(255) NOT NULL,
|
|
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
expires_at TIMESTAMP NOT NULL
|
|
)`;
|
|
await client.query(query);
|
|
|
|
query = `CREATE TABLE IF NOT EXISTS video_authorized_users (
|
|
id SERIAL PRIMARY KEY,
|
|
video_id INTEGER NOT NULL REFERENCES videos(id) ON DELETE CASCADE,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE
|
|
)`;
|
|
await client.query(query);
|
|
|
|
// Add GitHub OAuth columns if they don't exist
|
|
try {
|
|
await client.query(`ALTER TABLE users ADD COLUMN IF NOT EXISTS github_id VARCHAR(255) UNIQUE`);
|
|
await client.query(`ALTER TABLE users ADD COLUMN IF NOT EXISTS created_at TIMESTAMP DEFAULT NOW()`);
|
|
await client.query(`ALTER TABLE users ADD COLUMN IF NOT EXISTS updated_at TIMESTAMP DEFAULT NOW()`);
|
|
await client.query(`ALTER TABLE users ALTER COLUMN email DROP NOT NULL`);
|
|
await client.query(`ALTER TABLE users ALTER COLUMN password DROP NOT NULL`);
|
|
} catch (e) {
|
|
console.log("OAuth columns already exist or error adding them:", e.message);
|
|
}
|
|
|
|
} catch (e) {
|
|
console.error("Error initializing database:", e);
|
|
} finally {
|
|
client.release();
|
|
}
|
|
|
|
}
|