- server: Go 单二进制骨架,embed 内嵌前端,配置/迁移/HTTP 路由 - store: system.db + event.db 两套迁移,业务表 + 种子数据 - domain: 积分引擎(并列三口径/计分通道/流水/排名/破纪录)+ 68 个测试 - web: Vite + Vue 三入口骨架 + shared 层(类型/API/WebSocket 客户端) - console: Electron 宿主骨架(选屏/防熄屏/进程守护/托盘)
50 lines
1.2 KiB
Go
50 lines
1.2 KiB
Go
// Package store 负责数据库连接、迁移与仓储。
|
|
package store
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
_ "modernc.org/sqlite"
|
|
)
|
|
|
|
// Store 持有系统库(data/system.db)的连接。
|
|
type Store struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
// Open 打开(必要时创建)数据目录下的 system.db。
|
|
func Open(dataDir string) (*Store, error) {
|
|
if err := os.MkdirAll(dataDir, 0o755); err != nil {
|
|
return nil, fmt.Errorf("创建数据目录 %s: %w", dataDir, err)
|
|
}
|
|
|
|
path := filepath.Join(dataDir, "system.db")
|
|
dsn := "file:" + path +
|
|
"?_pragma=journal_mode(WAL)" +
|
|
"&_pragma=foreign_keys(1)" +
|
|
"&_pragma=busy_timeout(5000)"
|
|
|
|
db, err := sql.Open("sqlite", dsn)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("打开数据库 %s: %w", path, err)
|
|
}
|
|
|
|
// SQLite 只允许单个写者,连接数收紧到 1 最省心。
|
|
db.SetMaxOpenConns(1)
|
|
|
|
if err := db.Ping(); err != nil {
|
|
_ = db.Close()
|
|
return nil, fmt.Errorf("连接数据库 %s: %w", path, err)
|
|
}
|
|
return &Store{db: db}, nil
|
|
}
|
|
|
|
// Close 关闭数据库连接。
|
|
func (s *Store) Close() error { return s.db.Close() }
|
|
|
|
// DB 暴露底层连接,供仓储层使用。
|
|
func (s *Store) DB() *sql.DB { return s.db }
|