Files
uzdb/internal/database/sqlite.go
loveuer 9874561410 refactor: Flatten directory structure
Move project files from uzdb/ subdirectory to root directory for cleaner project structure.

Changes:
- Move frontend/ to root
- Move internal/ to root
- Move build/ to root
- Move all config files (go.mod, wails.json, etc.) to root
- Remove redundant uzdb/ subdirectory nesting

Project structure is now:
├── frontend/        # React application
├── internal/        # Go backend
├── build/           # Wails build assets
├── doc/             # Design documentation
├── main.go          # Entry point
└── ...

🤖 Generated with Qoder
2026-04-04 07:14:00 -07:00

129 lines
2.8 KiB
Go

package database
import (
"fmt"
"os"
"path/filepath"
"sync"
"time"
"go.uber.org/zap"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
"gorm.io/gorm/logger"
"uzdb/internal/config"
"uzdb/internal/models"
)
var (
sqliteDB *gorm.DB
sqliteMu sync.RWMutex
)
// InitSQLite initializes the SQLite database for application data
func InitSQLite(dbPath string, cfg *config.DatabaseConfig) (*gorm.DB, error) {
sqliteMu.Lock()
defer sqliteMu.Unlock()
// Ensure directory exists
dir := filepath.Dir(dbPath)
if err := os.MkdirAll(dir, 0755); err != nil {
return nil, fmt.Errorf("failed to create database directory: %w", err)
}
// Configure GORM logger
var gormLogger logger.Interface
if config.Get().IsDevelopment() {
gormLogger = logger.Default.LogMode(logger.Info)
} else {
gormLogger = logger.Default.LogMode(logger.Silent)
}
// Open SQLite connection
db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{
Logger: gormLogger,
})
if err != nil {
return nil, fmt.Errorf("failed to open SQLite database: %w", err)
}
// Set connection pool settings
sqlDB, err := db.DB()
if err != nil {
return nil, fmt.Errorf("failed to get underlying DB: %w", err)
}
sqlDB.SetMaxOpenConns(cfg.MaxOpenConns)
sqlDB.SetMaxIdleConns(cfg.MaxIdleConns)
sqlDB.SetConnMaxLifetime(time.Duration(cfg.MaxLifetime) * time.Minute)
// Enable WAL mode for better concurrency
if err := db.Exec("PRAGMA journal_mode=WAL").Error; err != nil {
config.GetLogger().Warn("failed to enable WAL mode", zap.Error(err))
}
// Run migrations
if err := runMigrations(db); err != nil {
return nil, fmt.Errorf("migration failed: %w", err)
}
sqliteDB = db
config.GetLogger().Info("SQLite database initialized",
zap.String("path", dbPath),
zap.Int("max_open_conns", cfg.MaxOpenConns),
zap.Int("max_idle_conns", cfg.MaxIdleConns),
)
return db, nil
}
// runMigrations runs database migrations
func runMigrations(db *gorm.DB) error {
migrations := []interface{}{
&models.UserConnection{},
&models.QueryHistory{},
&models.SavedQuery{},
}
for _, model := range migrations {
if err := db.AutoMigrate(model); err != nil {
return fmt.Errorf("failed to migrate %T: %w", model, err)
}
}
config.GetLogger().Info("database migrations completed")
return nil
}
// GetSQLiteDB returns the SQLite database instance
func GetSQLiteDB() *gorm.DB {
sqliteMu.RLock()
defer sqliteMu.RUnlock()
return sqliteDB
}
// CloseSQLite closes the SQLite database connection
func CloseSQLite() error {
sqliteMu.Lock()
defer sqliteMu.Unlock()
if sqliteDB == nil {
return nil
}
sqlDB, err := sqliteDB.DB()
if err != nil {
return err
}
if err := sqlDB.Close(); err != nil {
return fmt.Errorf("failed to close SQLite database: %w", err)
}
sqliteDB = nil
config.GetLogger().Info("SQLite database closed")
return nil
}