← back to Handbag Auth Nextjs
src/lib/db.ts
65 lines
// Database Connection Singleton
// Prevents SQL injection, connection leaks, and improves performance
import Database from 'better-sqlite3'
import path from 'path'
let dbInstance: Database.Database | null = null
/**
* Get singleton database connection
* Reuses connection across requests for better performance
*/
export function getDb(): Database.Database {
if (!dbInstance) {
// Use environment variable or fallback to project path
const dbPath = process.env.DATABASE_PATH ||
path.join(process.cwd(), 'data', 'handbags.db')
try {
dbInstance = new Database(dbPath, {
readonly: true,
fileMustExist: true
})
// Optimize for performance
dbInstance.pragma('journal_mode = WAL')
dbInstance.pragma('synchronous = NORMAL')
console.log(`[DB] Connected to database: ${dbPath}`)
} catch (error) {
console.error('[DB] Failed to connect to database:', error)
throw new Error('Database connection failed')
}
}
return dbInstance
}
/**
* Close database connection (call on app shutdown)
*/
export function closeDb(): void {
if (dbInstance) {
dbInstance.close()
dbInstance = null
console.log('[DB] Database connection closed')
}
}
/**
* Validate brand filter to prevent SQL injection
*/
export function validateBrandFilter(brand: string | null): string | null {
if (!brand || brand === 'all') return null
const validBrands = ['hermes', 'chanel', 'lv', 'dior', 'prada', 'fendi']
const normalized = brand.toLowerCase().trim()
if (!validBrands.includes(normalized)) {
throw new Error(`Invalid brand filter: ${brand}`)
}
return normalized
}