Initial commit: Homelab API
This commit is contained in:
102
internal/repository/db.go
Normal file
102
internal/repository/db.go
Normal file
@@ -0,0 +1,102 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
func NewDB(databaseURL string) (*sqlx.DB, error) {
|
||||
db, err := sqlx.Connect("postgres", databaseURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
db.SetMaxOpenConns(25)
|
||||
db.SetMaxIdleConns(5)
|
||||
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func RunMigrations(db *sqlx.DB) error {
|
||||
migrations := []string{
|
||||
`CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
username VARCHAR(100) NOT NULL,
|
||||
password_hash VARCHAR(255) NOT NULL,
|
||||
email_verified BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
`CREATE TABLE IF NOT EXISTS habits (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
description TEXT DEFAULT '''',
|
||||
color VARCHAR(20) DEFAULT '#6366f1',
|
||||
icon VARCHAR(50) DEFAULT 'check',
|
||||
frequency VARCHAR(20) DEFAULT 'daily',
|
||||
target_days INTEGER[] DEFAULT '{1,2,3,4,5,6,0}',
|
||||
target_count INTEGER DEFAULT 1,
|
||||
is_archived BOOLEAN DEFAULT FALSE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
`CREATE TABLE IF NOT EXISTS habit_logs (
|
||||
id SERIAL PRIMARY KEY,
|
||||
habit_id INTEGER REFERENCES habits(id) ON DELETE CASCADE,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||||
date DATE NOT NULL,
|
||||
count INTEGER DEFAULT 1,
|
||||
note TEXT DEFAULT '''',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(habit_id, date)
|
||||
)`,
|
||||
`CREATE TABLE IF NOT EXISTS email_tokens (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||||
token VARCHAR(255) UNIQUE NOT NULL,
|
||||
type VARCHAR(20) NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
used_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
`CREATE TABLE IF NOT EXISTS tasks (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
description TEXT DEFAULT '''',
|
||||
icon VARCHAR(10) DEFAULT '📋',
|
||||
color VARCHAR(7) DEFAULT '#6B7280',
|
||||
due_date DATE,
|
||||
priority INTEGER DEFAULT 0,
|
||||
completed_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_habits_user_id ON habits(user_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_habit_logs_habit_id ON habit_logs(habit_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_habit_logs_date ON habit_logs(date)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_habit_logs_user_date ON habit_logs(user_id, date)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_tokens_token ON email_tokens(token)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_email_tokens_user_id ON email_tokens(user_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_tasks_user_id ON tasks(user_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_tasks_due_date ON tasks(due_date)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_tasks_completed ON tasks(user_id, completed_at)`,
|
||||
// Migration: add email_verified column if not exists
|
||||
`DO $$
|
||||
BEGIN
|
||||
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name='users' AND column_name='email_verified') THEN
|
||||
ALTER TABLE users ADD COLUMN email_verified BOOLEAN DEFAULT FALSE;
|
||||
END IF;
|
||||
END $$;`,
|
||||
}
|
||||
|
||||
for _, migration := range migrations {
|
||||
if _, err := db.Exec(migration); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user