| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- package initialize
- import (
- "fmt"
- "os"
- "path/filepath"
- "github.com/glebarez/sqlite"
- "go.uber.org/zap"
- "gorm.io/gorm"
- "wails-app/internal/config"
- "wails-app/internal/global"
- "wails-app/internal/initialize/internal"
- )
- // GormSqlite 初始化Sqlite数据库
- func GormSqlite() *gorm.DB {
- s := global.GVA_CONFIG.Sqlite
- if s.Dbname == "" {
- return nil
- }
- // Resolve path: empty = %APPDATA%/smart-parking/
- if s.Path == "" {
- if appData := os.Getenv("APPDATA"); appData != "" {
- s.Path = appData
- } else {
- // Fallback: exe directory
- if exePath, err := os.Executable(); err == nil {
- s.Path = filepath.Dir(exePath)
- }
- }
- s.Path = filepath.Join(s.Path, "smart-parking")
- }
- // Ensure directory exists
- if err := os.MkdirAll(s.Path, 0755); err != nil {
- panic(fmt.Errorf("failed to create SQLite db directory %s: %w", s.Path, err))
- }
- dsn := filepath.Join(s.Path, s.Dbname+".db")
- fmt.Printf("SQLite database: %s\n", dsn)
- if global.GVA_LOG != nil {
- global.GVA_LOG.Info("SQLite 数据库路径", zap.String("dsn", dsn))
- }
- if db, err := gorm.Open(sqlite.Open(dsn), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
- panic(err)
- } else {
- configureSQLite(db, s)
- return db
- }
- }
- // GormSqliteByConfig 初始化Sqlite数据库用过传入配置
- func GormSqliteByConfig(s config.Sqlite) *gorm.DB {
- if s.Dbname == "" {
- return nil
- }
- if db, err := gorm.Open(sqlite.Open(s.Dsn()), internal.Gorm.Config(s.Prefix, s.Singular)); err != nil {
- panic(err)
- } else {
- configureSQLite(db, s)
- return db
- }
- }
- // configureSQLite limits concurrent connections and enables SQLite settings
- // that avoid long writer starvation when device events and API requests share
- // the same database file.
- func configureSQLite(db *gorm.DB, s config.Sqlite) {
- sqlDB, err := db.DB()
- if err != nil {
- panic(err)
- }
- maxIdle := s.MaxIdleConns
- if maxIdle <= 0 {
- maxIdle = 1
- }
- maxOpen := s.MaxOpenConns
- if maxOpen <= 0 {
- maxOpen = 4
- }
- if maxOpen < maxIdle {
- maxOpen = maxIdle
- }
- sqlDB.SetMaxIdleConns(maxIdle)
- sqlDB.SetMaxOpenConns(maxOpen)
- // WAL allows readers to continue while a writer commits. busy_timeout
- // prevents transient lock contention from immediately failing a request.
- for _, pragma := range []string{
- "PRAGMA busy_timeout = 5000",
- "PRAGMA journal_mode = WAL",
- "PRAGMA synchronous = NORMAL",
- } {
- if err := sqlDB.Ping(); err != nil {
- if global.GVA_LOG != nil {
- global.GVA_LOG.Warn("SQLite 连接检查失败", zap.Error(err))
- }
- return
- }
- if _, err := sqlDB.Exec(pragma); err != nil && global.GVA_LOG != nil {
- global.GVA_LOG.Warn("SQLite PRAGMA 设置失败", zap.String("pragma", pragma), zap.Error(err))
- }
- }
- }
|