This commit is contained in:
90
internal/infrastructure/database/postgres/connection.go
Normal file
90
internal/infrastructure/database/postgres/connection.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"counter/internal/infrastructure/config"
|
||||
"counter/internal/infrastructure/logging"
|
||||
|
||||
_ "github.com/lib/pq"
|
||||
)
|
||||
|
||||
// Connection manages the database connection
|
||||
type Connection struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
// NewConnection creates a new database connection
|
||||
func NewConnection(cfg *config.Config, logger logging.Logger) (*Connection, error) {
|
||||
db, err := sql.Open("postgres", cfg.DatabaseURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open database: %w", err)
|
||||
}
|
||||
|
||||
// Test the connection
|
||||
if err = db.Ping(); err != nil {
|
||||
return nil, fmt.Errorf("failed to ping database: %w", err)
|
||||
}
|
||||
|
||||
logger.Info("✅ Database connection established successfully")
|
||||
|
||||
conn := &Connection{db: db}
|
||||
|
||||
// Create tables
|
||||
if err := conn.CreateTables(); err != nil {
|
||||
return nil, fmt.Errorf("failed to create tables: %w", err)
|
||||
}
|
||||
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
// GetDB returns the database connection
|
||||
func (c *Connection) GetDB() *sql.DB {
|
||||
return c.db
|
||||
}
|
||||
|
||||
// Close closes the database connection
|
||||
func (c *Connection) Close() error {
|
||||
return c.db.Close()
|
||||
}
|
||||
|
||||
// CreateTables creates the necessary database tables
|
||||
func (c *Connection) CreateTables() error {
|
||||
queries := []string{
|
||||
`CREATE TABLE IF NOT EXISTS users (
|
||||
id SERIAL PRIMARY KEY,
|
||||
username VARCHAR(50) UNIQUE NOT NULL,
|
||||
email VARCHAR(255) UNIQUE NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
`CREATE TABLE IF NOT EXISTS counters (
|
||||
id SERIAL PRIMARY KEY,
|
||||
user_id INTEGER REFERENCES users(id) ON DELETE CASCADE,
|
||||
name VARCHAR(100) NOT NULL,
|
||||
description TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
`CREATE TABLE IF NOT EXISTS counter_entries (
|
||||
id SERIAL PRIMARY KEY,
|
||||
counter_id INTEGER REFERENCES counters(id) ON DELETE CASCADE,
|
||||
value INTEGER NOT NULL,
|
||||
date DATE NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_counters_user_id ON counters(user_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_counter_entries_counter_id ON counter_entries(counter_id)`,
|
||||
`CREATE INDEX IF NOT EXISTS idx_counter_entries_date ON counter_entries(date)`,
|
||||
}
|
||||
|
||||
for _, query := range queries {
|
||||
if _, err := c.db.Exec(query); err != nil {
|
||||
return fmt.Errorf("failed to execute query: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user