- Add dbGet/dbAll helper functions for database-agnostic queries - Add toDbBool/convertBooleansForDb for boolean type conversion - Add toDbDate/getNow for timestamp type handling - Add generateId that returns UUID for Postgres, nanoid for SQLite - Update all routes to use compatibility helpers - Add normalizeEvent to return clean number types from Postgres decimal - Add formatPrice utility for consistent price display - Add legal pages admin interface with RichTextEditor - Update carousel images - Add drizzle migration files for PostgreSQL
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import 'dotenv/config';
|
|
import { drizzle as drizzleSqlite } from 'drizzle-orm/better-sqlite3';
|
|
import { drizzle as drizzlePg } from 'drizzle-orm/node-postgres';
|
|
import Database from 'better-sqlite3';
|
|
import pg from 'pg';
|
|
import * as schema from './schema.js';
|
|
import { existsSync, mkdirSync } from 'fs';
|
|
import { dirname } from 'path';
|
|
|
|
const dbType = process.env.DB_TYPE || 'sqlite';
|
|
|
|
let db: ReturnType<typeof drizzleSqlite> | ReturnType<typeof drizzlePg>;
|
|
|
|
if (dbType === 'postgres') {
|
|
const pool = new pg.Pool({
|
|
connectionString: process.env.DATABASE_URL || 'postgresql://localhost:5432/spanglish',
|
|
});
|
|
db = drizzlePg(pool, { schema });
|
|
} else {
|
|
const dbPath = process.env.DATABASE_URL || './data/spanglish.db';
|
|
|
|
// Ensure data directory exists
|
|
const dir = dirname(dbPath);
|
|
if (!existsSync(dir)) {
|
|
mkdirSync(dir, { recursive: true });
|
|
}
|
|
|
|
const sqlite = new Database(dbPath);
|
|
sqlite.pragma('journal_mode = WAL');
|
|
db = drizzleSqlite(sqlite, { schema });
|
|
}
|
|
|
|
// ==================== Database Compatibility Helpers ====================
|
|
// These functions abstract the differences between SQLite and PostgreSQL Drizzle drivers:
|
|
// - SQLite uses .get() for single result, .all() for multiple
|
|
// - PostgreSQL returns arrays directly (no .get()/.all() methods)
|
|
|
|
/**
|
|
* Get a single result from a query (works with both SQLite and PostgreSQL)
|
|
* @param query - A Drizzle query builder (e.g., db.select().from(table).where(...))
|
|
* @returns The first result or null
|
|
*/
|
|
export async function dbGet<T>(query: any): Promise<T | null> {
|
|
if (dbType === 'postgres') {
|
|
const results = await query;
|
|
return results[0] || null;
|
|
}
|
|
// SQLite - use .get()
|
|
return query.get() || null;
|
|
}
|
|
|
|
/**
|
|
* Get all results from a query (works with both SQLite and PostgreSQL)
|
|
* @param query - A Drizzle query builder (e.g., db.select().from(table).where(...))
|
|
* @returns Array of results
|
|
*/
|
|
export async function dbAll<T>(query: any): Promise<T[]> {
|
|
if (dbType === 'postgres') {
|
|
return await query;
|
|
}
|
|
// SQLite - use .all()
|
|
return query.all();
|
|
}
|
|
|
|
/**
|
|
* Check if using PostgreSQL
|
|
*/
|
|
export function isPostgres(): boolean {
|
|
return dbType === 'postgres';
|
|
}
|
|
|
|
/**
|
|
* Check if using SQLite
|
|
*/
|
|
export function isSqlite(): boolean {
|
|
return dbType === 'sqlite';
|
|
}
|
|
|
|
export { db, dbType };
|
|
export * from './schema.js';
|