package cache import ( "database/sql" "fmt" "os" "path/filepath" "sync" "time" _ "modernc.org/sqlite" // 纯 Go 驱动,驱动名是 "sqlite" 而非 "sqlite3" ) var ( GlobalDB *sql.DB once sync.Once // 确保 InitCache 只执行一次(单例初始化) ) // InitCache 初始化 SQLite 数据库连接(全局唯一,兼容 CGO_ENABLED=0) func InitCache() { once.Do(func() { // 1. 数据库文件路径(自定义为你的用户数据库路径) dbPath := "./database/local/user.db" // 2. 创建数据库目录(确保上级目录存在,不存在则自动创建) if err := os.MkdirAll(filepath.Dir(dbPath), 0755); err != nil { panic(fmt.Sprintf("创建数据库目录失败:%v", err)) } // 3. 打开 SQLite 连接:驱动名必须是 "sqlite"(对应 modernc.org/sqlite) db, err := sql.Open("sqlite", dbPath) if err != nil { panic(fmt.Sprintf("打开 SQLite 数据库失败:%v", err)) } // 4. 验证连接有效性(必做,避免连接创建成功但不可用) if err := db.Ping(); err != nil { _ = db.Close() // 连接失败时释放资源 panic(fmt.Sprintf("验证 SQLite 连接失败:%v", err)) } // 5. 连接池配置(适配 SQLite 单文件特性) db.SetMaxOpenConns(1) // 最大打开连接数=1,避免文件锁冲突 db.SetMaxIdleConns(1) // 最大空闲连接数=1,与最大打开数一致 db.SetConnMaxLifetime(0) // 连接生命周期无限制 db.SetConnMaxIdleTime(30 * time.Minute) // 空闲连接30分钟超时释放 // 6. 赋值全局变量,初始化完成 GlobalDB = db fmt.Printf("SQLite 数据库初始化成功,文件路径:%s\n", dbPath) }) } // GetCacheDB 获取全局唯一的 SQLite 连接(必须先调用 InitCache 初始化) func GetCacheDB() *sql.DB { if GlobalDB == nil { panic("数据库未初始化,请先调用 cache.InitCache()") } return GlobalDB } // CloseCache 关闭数据库连接(程序退出时调用,释放资源) func CloseCache() error { if GlobalDB != nil { return GlobalDB.Close() } return nil }