106 lines
2.6 KiB
TypeScript
106 lines
2.6 KiB
TypeScript
import { Pool } from 'pg';
|
|
import { env } from '$env/dynamic/private';
|
|
|
|
// Get DATABASE_URL with fallback
|
|
const getDatabaseUrl = () => {
|
|
return (
|
|
env.DATABASE_URL ||
|
|
process.env.DATABASE_URL ||
|
|
'postgresql://postgres:password@localhost:5432/egentrening'
|
|
);
|
|
};
|
|
|
|
// Lazy pool creation - only create when actually needed
|
|
let pool: Pool | null = null;
|
|
|
|
const getPool = () => {
|
|
if (!pool) {
|
|
pool = new Pool({
|
|
connectionString: getDatabaseUrl(),
|
|
ssl: process.env.NODE_ENV === 'production' ? { rejectUnauthorized: false } : false
|
|
});
|
|
}
|
|
return pool;
|
|
};
|
|
|
|
// Simple database client
|
|
export const db = {
|
|
// Execute a query
|
|
async query(text: string, params?: any[]) {
|
|
try {
|
|
const poolInstance = getPool();
|
|
const client = await poolInstance.connect();
|
|
try {
|
|
const result = await client.query(text, params);
|
|
return result;
|
|
} finally {
|
|
client.release();
|
|
}
|
|
} catch (error) {
|
|
console.error('Database query failed:', error);
|
|
throw error;
|
|
}
|
|
},
|
|
|
|
// Test connection
|
|
async testConnection() {
|
|
try {
|
|
const result = await this.query('SELECT NOW() as current_time');
|
|
console.log('Database connected successfully:', result.rows[0]);
|
|
return true;
|
|
} catch (error) {
|
|
console.error('Database connection failed:', error);
|
|
return false;
|
|
}
|
|
},
|
|
|
|
// Create tables for tracking daily exercises
|
|
async createTables() {
|
|
// Create exercises table with all activities in one table
|
|
await this.query(`
|
|
CREATE TABLE IF NOT EXISTS daily_exercises (
|
|
id BIGINT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
|
|
date DATE NOT NULL UNIQUE,
|
|
pushups INTEGER DEFAULT 0,
|
|
situps INTEGER DEFAULT 0,
|
|
plank_time_seconds INTEGER DEFAULT 0,
|
|
run_distance_km DECIMAL(5,2) DEFAULT 0.0,
|
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
)
|
|
`);
|
|
|
|
// Create index for faster date lookups
|
|
await this.query(`
|
|
CREATE INDEX IF NOT EXISTS idx_daily_exercises_date
|
|
ON daily_exercises(date)
|
|
`);
|
|
|
|
// Create trigger to update updated_at timestamp
|
|
await this.query(`
|
|
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
|
RETURNS TRIGGER AS $$
|
|
BEGIN
|
|
NEW.updated_at = CURRENT_TIMESTAMP;
|
|
RETURN NEW;
|
|
END;
|
|
$$ language 'plpgsql'
|
|
`);
|
|
|
|
await this.query(`
|
|
DROP TRIGGER IF EXISTS update_daily_exercises_updated_at ON daily_exercises;
|
|
CREATE TRIGGER update_daily_exercises_updated_at
|
|
BEFORE UPDATE ON daily_exercises
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION update_updated_at_column()
|
|
`);
|
|
},
|
|
|
|
// Close all connections
|
|
async close() {
|
|
if (pool) {
|
|
await pool.end();
|
|
pool = null;
|
|
}
|
|
}
|
|
};
|