real db migrations

This commit is contained in:
JurajKubrican
2025-08-22 18:27:43 +02:00
parent 74669f15f7
commit 0323212d9d
6 changed files with 95 additions and 3 deletions

4
go.mod
View File

@@ -15,7 +15,10 @@ require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/golang-migrate/migrate/v4 v4.18.3 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mileusna/useragent v1.3.5 // indirect
@@ -27,6 +30,7 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasttemplate v1.2.2 // indirect
go.uber.org/atomic v1.11.0 // indirect
golang.org/x/crypto v0.40.0 // indirect
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
golang.org/x/sys v0.34.0 // indirect

9
go.sum
View File

@@ -6,12 +6,19 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/golang-migrate/migrate/v4 v4.18.3 h1:EYGkoOsvgHHfm5U/naS1RP/6PL/Xv3S4B/swMiAmDLs=
github.com/golang-migrate/migrate/v4 v4.18.3/go.mod h1:99BKpIi6ruaaXRM1A77eqZ+FWPQ3cfRa+ZVy5bmWMaY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
@@ -50,6 +57,8 @@ github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6Kllzaw
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
golang.org/x/crypto v0.40.0 h1:r4x+VvoG5Fm+eJcxMaY8CQM7Lb0l1lsmjGBQ6s8BfKM=

View File

@@ -0,0 +1,4 @@
DROP INDEX IF EXISTS idx_user_visits_path;
DROP INDEX IF EXISTS idx_user_visits_fingerprint;
DROP INDEX IF EXISTS idx_user_visits_timestamp;
DROP TABLE IF EXISTS user_visits;

View File

@@ -0,0 +1,15 @@
CREATE TABLE IF NOT EXISTS user_visits (
id INTEGER PRIMARY KEY AUTOINCREMENT,
ip TEXT NOT NULL,
path TEXT NOT NULL,
method TEXT NOT NULL,
fingerprint TEXT,
user_agent TEXT,
referer TEXT,
accept_language TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE INDEX IF NOT EXISTS idx_user_visits_timestamp ON user_visits(timestamp);
CREATE INDEX IF NOT EXISTS idx_user_visits_fingerprint ON user_visits(fingerprint);
CREATE INDEX IF NOT EXISTS idx_user_visits_path ON user_visits(path);

52
src/migrations/manager.go Normal file
View File

@@ -0,0 +1,52 @@
package migrations
import (
"database/sql"
"fmt"
"github.com/golang-migrate/migrate/v4"
"github.com/golang-migrate/migrate/v4/database/sqlite"
_ "github.com/golang-migrate/migrate/v4/source/file"
)
type MigrationManager struct {
databases map[string]*sql.DB
}
func NewMigrationManager() *MigrationManager {
return &MigrationManager{
databases: make(map[string]*sql.DB),
}
}
// RegisterDatabase registers a database connection for migrations
func (mm *MigrationManager) RegisterDatabase(name string, db *sql.DB) {
mm.databases[name] = db
}
// RunMigrations runs migrations for a specific database
func (mm *MigrationManager) RunMigrations(dbName string) error {
db, exists := mm.databases[dbName]
if !exists {
return fmt.Errorf("database %s not registered", dbName)
}
driver, err := sqlite.WithInstance(db, &sqlite.Config{})
if err != nil {
return fmt.Errorf("failed to create database driver: %w", err)
}
migrationPath := fmt.Sprintf("file://migrations/%s", dbName)
m, err := migrate.NewWithDatabaseInstance(migrationPath, "sqlite", driver)
if err != nil {
return fmt.Errorf("failed to create migration instance: %w", err)
}
// Run migrations
if err := m.Up(); err != nil && err != migrate.ErrNoChange {
return fmt.Errorf("failed to run migrations: %w", err)
}
fmt.Printf("Migrations completed successfully for database: %s\n", dbName)
return nil
}

View File

@@ -6,6 +6,7 @@ import (
"time"
"github.com/labstack/echo/v4"
"knet.sk/src/migrations"
_ "modernc.org/sqlite"
)
@@ -43,11 +44,18 @@ func StartTrackingService() *TrackingService {
db.SetMaxIdleConns(1)
trackingService = &TrackingService{db: db}
err = trackingService.initDB()
if err != nil {
// Run migrations instead of manual table creation
migrationManager := migrations.NewMigrationManager()
migrationManager.RegisterDatabase("tracking", db)
if err := migrationManager.RunMigrations("tracking"); err != nil {
println("Warning: Migration failed:", err.Error())
// Fallback to manual table creation for backward compatibility
if err := trackingService.initDB(); err != nil {
panic(err)
}
}
}
return trackingService
}