🚩 Private development - version retention only ✅ Complete web dashboard (React + TypeScript + TailwindCSS) ✅ Production-ready server backend (Go + Gin + PostgreSQL) ✅ Linux agent with APT + Docker scanning + local CLI tools ✅ JWT authentication and REST API ✅ Update discovery and approval workflow 🚧 Status: Alpha software - active development 📦 Purpose: Version retention during development ⚠️ Not for public use or deployment
77 lines
1.7 KiB
Go
77 lines
1.7 KiB
Go
package database
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"sort"
|
|
"strings"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
_ "github.com/lib/pq"
|
|
)
|
|
|
|
// DB wraps the database connection
|
|
type DB struct {
|
|
*sqlx.DB
|
|
}
|
|
|
|
// Connect establishes a connection to the PostgreSQL database
|
|
func Connect(databaseURL string) (*DB, error) {
|
|
db, err := sqlx.Connect("postgres", databaseURL)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to connect to database: %w", err)
|
|
}
|
|
|
|
// Configure connection pool
|
|
db.SetMaxOpenConns(25)
|
|
db.SetMaxIdleConns(5)
|
|
|
|
// Test the connection
|
|
if err := db.Ping(); err != nil {
|
|
return nil, fmt.Errorf("failed to ping database: %w", err)
|
|
}
|
|
|
|
return &DB{db}, nil
|
|
}
|
|
|
|
// Migrate runs database migrations
|
|
func (db *DB) Migrate(migrationsPath string) error {
|
|
// Read migration files
|
|
files, err := os.ReadDir(migrationsPath)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read migrations directory: %w", err)
|
|
}
|
|
|
|
// Filter and sort .up.sql files
|
|
var migrationFiles []string
|
|
for _, file := range files {
|
|
if strings.HasSuffix(file.Name(), ".up.sql") {
|
|
migrationFiles = append(migrationFiles, file.Name())
|
|
}
|
|
}
|
|
sort.Strings(migrationFiles)
|
|
|
|
// Execute migrations
|
|
for _, filename := range migrationFiles {
|
|
path := filepath.Join(migrationsPath, filename)
|
|
content, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to read migration %s: %w", filename, err)
|
|
}
|
|
|
|
if _, err := db.Exec(string(content)); err != nil {
|
|
return fmt.Errorf("failed to execute migration %s: %w", filename, err)
|
|
}
|
|
|
|
fmt.Printf("✓ Executed migration: %s\n", filename)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Close closes the database connection
|
|
func (db *DB) Close() error {
|
|
return db.DB.Close()
|
|
}
|