add new db constraints and foreignKey mode

This commit is contained in:
Alex
2025-03-24 17:45:55 +01:00
parent 28dfe7ecde
commit 5d55f5a8d9

View File

@@ -6,6 +6,8 @@ import (
"GoMembership/pkg/logger" "GoMembership/pkg/logger"
"crypto/rand" "crypto/rand"
"encoding/base64" "encoding/base64"
"errors"
"fmt"
"time" "time"
"github.com/alexedwards/argon2id" "github.com/alexedwards/argon2id"
@@ -15,27 +17,55 @@ import (
var DB *gorm.DB var DB *gorm.DB
func Open(dbPath string, adminMail string) (*gorm.DB, error) { func Open(dbPath string, adminMail string, debug bool) (*gorm.DB, error) {
// Add foreign key support and WAL journal mode to DSN
dsn := fmt.Sprintf("%s?_foreign_keys=1&_journal_mode=WAL", dbPath)
db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{}) db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{
// Enable PrepareStmt for better performance
PrepareStmt: true,
})
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("failed to connect database: %w", err)
} }
// Verify foreign key support is enabled
var foreignKeyEnabled int
if err := db.Raw("PRAGMA foreign_keys").Scan(&foreignKeyEnabled).Error; err != nil {
return nil, fmt.Errorf("foreign key check failed: %w", err)
}
if foreignKeyEnabled != 1 {
return nil, errors.New("SQLite foreign key constraints not enabled")
}
if debug {
db = db.Debug()
}
// Configure connection pool
sqlDB, err := db.DB()
if err != nil {
return nil, fmt.Errorf("failed to get DB instance: %w", err)
}
sqlDB.SetMaxOpenConns(1) // Required for SQLite in production
sqlDB.SetMaxIdleConns(1)
sqlDB.SetConnMaxLifetime(time.Hour)
if err := db.AutoMigrate( if err := db.AutoMigrate(
&models.User{}, &models.User{},
&models.SubscriptionModel{}, &models.SubscriptionModel{},
&models.Membership{}, &models.Membership{},
&models.Consent{}, &models.Consent{},
&models.Verification{}, &models.Verification{},
&models.BankAccount{},
&models.Licence{}, &models.Licence{},
&models.Category{}, &models.Category{},
&models.Insurance{},
&models.Car{}, &models.Car{},
&models.Location{}, &models.Location{},
&models.Damage{}, &models.Damage{},
&models.BankAccount{}); err != nil { &models.Insurance{},
logger.Error.Fatalf("Couldn't create database: %v", err) ); err != nil {
return nil, err return nil, fmt.Errorf("failed to migrate database: %w", err)
} }
logger.Info.Print("Opened DB") logger.Info.Print("Opened DB")
@@ -78,14 +108,11 @@ func Open(dbPath string, adminMail string) (*gorm.DB, error) {
return nil, err return nil, err
} }
admin, err := createAdmin(adminMail, createdModel.ID) admin, err := createAdmin(adminMail)
if err != nil { if err != nil {
return nil, err return nil, err
} }
result := db.Session(&gorm.Session{FullSaveAssociations: true}).Create(&admin) admin.Create(db)
if result.Error != nil {
return nil, result.Error
}
} }
return db, nil return db, nil
@@ -125,7 +152,7 @@ func createLicenceCategories() []models.Category {
// TODO: Landing page to create an admin // TODO: Landing page to create an admin
func createAdmin(userMail string, subscriptionModelID uint) (*models.User, error) { func createAdmin(userMail string) (*models.User, error) {
passwordBytes := make([]byte, 12) passwordBytes := make([]byte, 12)
_, err := rand.Read(passwordBytes) _, err := rand.Read(passwordBytes)
if err != nil { if err != nil {
@@ -146,26 +173,24 @@ func createAdmin(userMail string, subscriptionModelID uint) (*models.User, error
logger.Error.Print("==============================================================") logger.Error.Print("==============================================================")
return &models.User{ return &models.User{
FirstName: "ad", FirstName: "Ad",
LastName: "min", LastName: "Min",
DateOfBirth: time.Now().AddDate(-20, 0, 0), DateOfBirth: time.Now().AddDate(-20, 0, 0),
Password: hash, Password: hash,
Address: "Downhill 4", Company: "",
ZipCode: "99999", Address: "",
City: "TechTown", ZipCode: "",
Phone: "0123455678", City: "",
Phone: "",
Notes: "",
Email: userMail, Email: userMail,
Status: constants.ActiveStatus, Status: constants.ActiveStatus,
RoleID: constants.Roles.Admin, RoleID: constants.Roles.Admin,
Membership: models.Membership{ Consents: nil,
Status: constants.DisabledStatus, Verifications: nil,
StartDate: time.Now(), Membership: nil,
SubscriptionModelID: subscriptionModelID, BankAccount: nil,
}, Licence: nil,
BankAccount: models.BankAccount{},
Licence: &models.Licence{
Status: constants.UnverifiedStatus,
},
}, nil }, nil
//"DE49700500000008447644", //fake //"DE49700500000008447644", //fake
} }