103 lines
2.3 KiB
Go
103 lines
2.3 KiB
Go
package database
|
||
|
||
import (
|
||
"database/sql"
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
"sync"
|
||
|
||
"ssq-desk/internal/storage/models"
|
||
|
||
"gorm.io/driver/sqlite"
|
||
"gorm.io/gorm"
|
||
_ "modernc.org/sqlite" // 使用纯 Go 的 SQLite 驱动(不需要 CGO)
|
||
)
|
||
|
||
var (
|
||
sqliteDB *gorm.DB
|
||
sqliteOnce sync.Once
|
||
)
|
||
|
||
// InitSQLite 初始化 SQLite 连接
|
||
func InitSQLite() (*gorm.DB, error) {
|
||
var err error
|
||
sqliteOnce.Do(func() {
|
||
// 获取应用数据目录
|
||
homeDir, err2 := os.UserHomeDir()
|
||
if err2 != nil {
|
||
err = fmt.Errorf("获取用户目录失败: %v", err2)
|
||
return
|
||
}
|
||
|
||
// 创建数据目录
|
||
dataDir := filepath.Join(homeDir, ".ssq-desk")
|
||
if err2 := os.MkdirAll(dataDir, 0755); err2 != nil {
|
||
err = fmt.Errorf("创建数据目录失败: %v", err2)
|
||
return
|
||
}
|
||
|
||
// SQLite 数据库文件路径
|
||
dbPath := filepath.Join(dataDir, "ssq.db")
|
||
|
||
// 直接使用 database/sql 打开连接,确保使用 modernc.org/sqlite(纯 Go,不需要 CGO)
|
||
sqlDB, err2 := sql.Open("sqlite", dbPath)
|
||
if err2 != nil {
|
||
err = fmt.Errorf("SQLite 打开连接失败: %v", err2)
|
||
sqliteDB = nil
|
||
return
|
||
}
|
||
|
||
// 测试连接
|
||
if err2 = sqlDB.Ping(); err2 != nil {
|
||
err = fmt.Errorf("SQLite 连接测试失败: %v", err2)
|
||
sqlDB.Close()
|
||
sqliteDB = nil
|
||
return
|
||
}
|
||
|
||
// 使用已打开的 database/sql 连接创建 GORM 实例
|
||
// 使用 sqlite.Dialector 并指定连接
|
||
sqliteDB, err2 = gorm.Open(sqlite.Dialector{Conn: sqlDB}, &gorm.Config{})
|
||
if err2 != nil {
|
||
err = fmt.Errorf("SQLite GORM 初始化失败: %v", err2)
|
||
sqlDB.Close()
|
||
sqliteDB = nil
|
||
return
|
||
}
|
||
|
||
// 自动迁移表结构(如果表已存在但结构不对,AutoMigrate 会尝试修改)
|
||
// 如果表结构完全不匹配,可能需要手动删除旧表
|
||
err2 = sqliteDB.AutoMigrate(
|
||
&models.SsqHistory{},
|
||
&models.Authorization{},
|
||
&models.Version{},
|
||
)
|
||
if err2 != nil {
|
||
err = fmt.Errorf("SQLite 表迁移失败: %v", err2)
|
||
sqliteDB = nil
|
||
return
|
||
}
|
||
})
|
||
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
return sqliteDB, nil
|
||
}
|
||
|
||
// GetSQLite 获取 SQLite 连接实例
|
||
// 如果连接未初始化或初始化失败,返回 nil
|
||
func GetSQLite() *gorm.DB {
|
||
if sqliteDB == nil {
|
||
db, err := InitSQLite()
|
||
if err != nil {
|
||
// 初始化失败,返回 nil
|
||
return nil
|
||
}
|
||
sqliteDB = db
|
||
}
|
||
return sqliteDB
|
||
}
|