add new db constraints and foreignKey mode
This commit is contained in:
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user