Christmas cookie ranking site
at main 2.1 kB view raw
1import pg, { type PoolClient, type QueryResult, type QueryResultRow } from "pg"; 2import sql, { type SQLQuery } from "pg-sql2"; 3 4export class Database { 5 static async connect(pool: pg.Pool) { 6 return new Database(await pool.connect()); 7 } 8 9 client: PoolClient; 10 11 constructor(client: PoolClient) { 12 this.client = client; 13 } 14 15 query(query: SQLQuery): Promise<QueryResult> { 16 const { text, values } = sql.compile(query); 17 return this.client.query(text, values); 18 } 19 20 async one<T extends QueryResultRow>(query: SQLQuery): Promise<T | null> { 21 const result = await this.query(query); 22 if (result.rowCount === null) { 23 throw new TypeError("Query does not return rows."); 24 } 25 if (result.rowCount > 1) { 26 throw new TypeError("Query returned more than one row."); 27 } 28 return (result.rows[0] ?? null) as T | null; 29 } 30 31 async many<T extends QueryResultRow>(query: SQLQuery): Promise<T[]> { 32 const result = await this.query(query); 33 return result.rows as T[]; 34 } 35 36 async transaction<T>(cb: () => Promise<T>): Promise<T> { 37 await this.client.query("BEGIN"); 38 try { 39 const result = await cb(); 40 await this.client.query("COMMIT"); 41 return result; 42 } catch (err) { 43 await this.client.query("ROLLBACK"); 44 throw err; 45 } 46 } 47 48 release() { 49 this.client.release(); 50 } 51} 52 53export interface Cookie { 54 id: string; 55 name: string; 56 description: string; 57 year: number; 58 image_url: string | null; 59 ordering: number; 60} 61 62export interface Account { 63 id: string; 64 created_at: Date; 65} 66 67export interface Session { 68 id: string; 69 account_id: string; 70 created_at: Date; 71 expires_at: Date; 72} 73 74export interface Review { 75 id: number; 76 account_id: string; 77 cookie_id: string; 78 year: number; 79 comment: string; 80 created_at: Date; 81} 82 83export interface Ranking { 84 id: number; 85 account_id: string; 86 cookie_id: string; 87 year: number; 88 ranking: number; 89 created_at: Date; 90} 91 92export interface Comment { 93 id: number; 94 account_id: string; 95 review_id: string; 96 comment: string; 97 created_at: Date; 98}