Files
Portfolio-Engine/internal/database/main.go
2026-03-25 15:36:05 +01:00

101 lines
3.1 KiB
Go

package database
import (
"database/sql"
"fmt"
"log"
_ "github.com/mattn/go-sqlite3"
)
func InitDB(db *sql.DB) {
schema := `
CREATE TABLE IF NOT EXISTS currencies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
code TEXT NOT NULL UNIQUE,
name TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS companies (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
shares_outstanding INTEGER NOT NULL,
price REAL NOT NULL,
currency_id INTEGER NOT NULL,
FOREIGN KEY (currency_id) REFERENCES currencies(id)
);
CREATE TABLE IF NOT EXISTS periods (
id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT NOT NULL CHECK(type IN ('Q', 'H', 'Y')),
year INTEGER NOT NULL,
idx INTEGER NOT NULL,
start_date TEXT NOT NULL,
end_date TEXT NOT NULL,
UNIQUE(type, year, idx)
);
CREATE TABLE IF NOT EXISTS category (
id INTEGER PRIMARY KEY AUTOINCREMENT,
company_id INTEGER NOT NULL,
parent_id INTEGER,
name TEXT NOT NULL,
FOREIGN KEY (company_id) REFERENCES companies(id),
FOREIGN KEY (parent_id) REFERENCES category(id),
UNIQUE(company_id, name)
);
CREATE TABLE IF NOT EXISTS revenue_entries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
company_id INTEGER NOT NULL,
currency_id INTEGER NOT NULL,
category_id INTEGER NOT NULL,
period_id INTEGER NOT NULL,
value REAL NOT NULL,
FOREIGN KEY (company_id) REFERENCES companies(id),
FOREIGN KEY (currency_id) REFERENCES currencies(id),
FOREIGN KEY (category_id) REFERENCES category(id),
FOREIGN KEY (period_id) REFERENCES periods(id),
UNIQUE(company_id, category_id, period_id)
);`
if _, err := db.Exec(schema); err != nil {
log.Fatal("Failed to create tables:", err)
}
fmt.Println("Tables ready")
}
func MigrateAddUniqueToRevenueEntries(db *sql.DB) error {
steps := []string{
// 1. copy existing data into a temp table with the new constraint
`CREATE TABLE IF NOT EXISTS revenue_entries_new (
id INTEGER PRIMARY KEY AUTOINCREMENT,
company_id INTEGER NOT NULL,
currency_id INTEGER NOT NULL,
category_id INTEGER NOT NULL,
period_id INTEGER NOT NULL,
value REAL NOT NULL,
FOREIGN KEY (company_id) REFERENCES companies(id),
FOREIGN KEY (currency_id) REFERENCES currencies(id),
FOREIGN KEY (category_id) REFERENCES category(id),
FOREIGN KEY (period_id) REFERENCES periods(id),
UNIQUE(company_id, category_id, period_id)
)`,
// 2. copy data over
`INSERT OR IGNORE INTO revenue_entries_new
SELECT id, company_id, currency_id, category_id, period_id, value
FROM revenue_entries`,
// 3. drop old table
`DROP TABLE revenue_entries`,
// 4. rename new table
`ALTER TABLE revenue_entries_new RENAME TO revenue_entries`,
}
for _, step := range steps {
if _, err := db.Exec(step); err != nil {
return fmt.Errorf("migration failed: %w", err)
}
}
return nil
}