import { Database } from 'bun:sqlite'; export function dynamicInsert(db: Database, table: string, item: T) { const keys = Object.keys(item); const values = keys.map((k) => item[k]); const stmt = db.prepare(`INSERT INTO ${table} (${keys.join(', ')}) VALUES (${keys.map((k) => '?').join(', ')})`); return stmt.run(...values).lastInsertRowid; } export function dynamicUpdate(db: Database, table: string, item: T, key: string, keyValue: any) { const keys = Object.keys(item); const values = keys.map((k) => item[k]); const stmt = db.prepare(`UPDATE ${table} SET ${keys.map((k) => `${k} = ?`).join(', ')} WHERE ${key} = ?`); return stmt.run(...values, keyValue).changes; } export interface QueryOptions { skip?: number; limit?: number; orderBy?: Partial>; } type Where = Partial> & { or?: Partial> }; export function select(db: Database, table: string, options?: QueryOptions, select: string = '*', where?: Where): T[] { let query = `SELECT ${select} FROM ${table}\n`; const values = []; if (where) { const orConditions: string[] = []; if (where.or) { where.or && Object.keys(where.or).forEach((k) => { values.push(where.or[k]); orConditions.push(`${k} = ?`); }); delete where.or; } const andConditions: string[] = []; Object.keys(where).forEach((k) => { values.push(where[k]); andConditions.push(`${k} = ?`); }); if (orConditions.length > 0 || andConditions.length > 0) { query += 'WHERE '; const conditions: string[] = []; if (orConditions.length > 0) { conditions.push(`(${orConditions.join(' OR ')})`); } if (andConditions.length > 0) { conditions.push(andConditions.join(' AND ')); } query += conditions.join(' AND '); } } if (options?.orderBy) { query += `ORDER BY ${Object.keys(options.orderBy) .map((k) => { return `${k} ${options.orderBy[k]}`; }) .join(', ')}\n`; } if (options?.limit !== undefined) { values.push(options.limit); query += `LIMIT ?`; if (options?.skip) { values.push(options.skip); query += ` OFFSET ?`; } } return db.prepare(query).all(...values) as T[]; } export function remove(db: Database, table: string, where?: Where) { let query = `DELETE FROM ${table}`; const values = []; if (where) { const orConditions: string[] = []; if (where.or) { where.or && Object.keys(where.or).forEach((k) => { values.push(where.or[k]); orConditions.push(`${k} = ?`); }); delete where.or; } const andConditions: string[] = []; Object.keys(where).forEach((k) => { values.push(where[k]); andConditions.push(`${k} = ?`); }); if (orConditions.length > 0 || andConditions.length > 0) { query += ' WHERE '; const conditions: string[] = []; if (orConditions.length > 0) { conditions.push(`(${orConditions.join(' OR ')})`); } if (andConditions.length > 0) { conditions.push(andConditions.join(' AND ')); } query += conditions.join(' AND '); } } return db.prepare(query).run(...values).changes; }