up
This commit is contained in:
+67
-19
@@ -6,50 +6,98 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"simple_portal/config"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
// DB is the global database connection pointer.
|
||||
var DB *sql.DB
|
||||
|
||||
// InitDB initializes the SQLite database, creates the data directory,
|
||||
// opens the connection, sets WAL mode, and creates default tables and data.
|
||||
// InitDB 根据配置初始化数据库,支持 SQLite 和 MySQL
|
||||
func InitDB() error {
|
||||
dbPath := filepath.Join(".", "data", "portal.db")
|
||||
dbType := config.Cfg.Database.Type
|
||||
dataDir := config.Cfg.Data.Dir
|
||||
|
||||
// Create data directory if not exists
|
||||
switch dbType {
|
||||
case "mysql":
|
||||
return initMySQL()
|
||||
case "sqlite":
|
||||
return initSQLite(dataDir)
|
||||
default:
|
||||
return fmt.Errorf("不支持的数据库类型: %s(可选: sqlite, mysql)", dbType)
|
||||
}
|
||||
}
|
||||
|
||||
// initSQLite 初始化 SQLite 数据库
|
||||
func initSQLite(dataDir string) error {
|
||||
dbPath := config.GetDBPath()
|
||||
|
||||
// 创建数据目录
|
||||
if err := os.MkdirAll(filepath.Dir(dbPath), 0755); err != nil {
|
||||
return fmt.Errorf("failed to create data directory: %w", err)
|
||||
return fmt.Errorf("创建数据目录失败: %w", err)
|
||||
}
|
||||
|
||||
var err error
|
||||
DB, err = sql.Open("sqlite", dbPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open database: %w", err)
|
||||
return fmt.Errorf("打开 SQLite 数据库失败: %w", err)
|
||||
}
|
||||
|
||||
// SQLite requires max open conns = 1 for safe writes
|
||||
// SQLite 需要限制最大连接数为 1 以保证写安全
|
||||
DB.SetMaxOpenConns(1)
|
||||
|
||||
// Enable WAL mode for better concurrent read performance
|
||||
// 启用 WAL 模式提升并发读性能
|
||||
if _, err := DB.Exec("PRAGMA journal_mode=WAL"); err != nil {
|
||||
return fmt.Errorf("failed to set WAL mode: %w", err)
|
||||
return fmt.Errorf("设置 WAL 模式失败: %w", err)
|
||||
}
|
||||
|
||||
// Create tables
|
||||
// 创建表
|
||||
if err := createTables(); err != nil {
|
||||
return fmt.Errorf("failed to create tables: %w", err)
|
||||
return fmt.Errorf("创建数据表失败: %w", err)
|
||||
}
|
||||
|
||||
// Seed default data
|
||||
// 初始化默认数据
|
||||
if err := seedData(); err != nil {
|
||||
return fmt.Errorf("failed to seed data: %w", err)
|
||||
return fmt.Errorf("初始化默认数据失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createTables creates the cards, settings, and admins tables.
|
||||
// initMySQL 初始化 MySQL 数据库
|
||||
func initMySQL() error {
|
||||
dsn := config.Cfg.Database.MySQL.GetDSN()
|
||||
|
||||
var err error
|
||||
DB, err = sql.Open("mysql", dsn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("打开 MySQL 数据库失败: %w", err)
|
||||
}
|
||||
|
||||
// 测试连接
|
||||
if err := DB.Ping(); err != nil {
|
||||
return fmt.Errorf("连接 MySQL 失败: %w", err)
|
||||
}
|
||||
|
||||
// MySQL 不限制最大连接数(使用默认池)
|
||||
DB.SetMaxOpenConns(0)
|
||||
|
||||
// 创建表
|
||||
if err := createTables(); err != nil {
|
||||
return fmt.Errorf("创建数据表失败: %w", err)
|
||||
}
|
||||
|
||||
// 初始化默认数据
|
||||
if err := seedData(); err != nil {
|
||||
return fmt.Errorf("初始化默认数据失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createTables 创建所有数据表
|
||||
func createTables() error {
|
||||
_, err := DB.Exec(`
|
||||
CREATE TABLE IF NOT EXISTS cards (
|
||||
@@ -110,9 +158,9 @@ func createTables() error {
|
||||
return err
|
||||
}
|
||||
|
||||
// seedData inserts default admin account and search engine setting if not present.
|
||||
// seedData 插入默认管理员和搜索引擎配置
|
||||
func seedData() error {
|
||||
// Insert default admin if not exists
|
||||
// 插入默认管理员
|
||||
var count int
|
||||
err := DB.QueryRow("SELECT COUNT(*) FROM admins WHERE username = ?", "admin").Scan(&count)
|
||||
if err != nil {
|
||||
@@ -129,7 +177,7 @@ func seedData() error {
|
||||
}
|
||||
}
|
||||
|
||||
// Insert default search engine setting if not exists
|
||||
// 插入默认搜索引擎设置
|
||||
var settingCount int
|
||||
err = DB.QueryRow("SELECT COUNT(*) FROM settings WHERE key = ?", "search_engine").Scan(&settingCount)
|
||||
if err != nil {
|
||||
@@ -146,7 +194,7 @@ func seedData() error {
|
||||
}
|
||||
}
|
||||
|
||||
// Insert default homepage settings if not exists
|
||||
// 插入默认主页设置
|
||||
defaultSettings := []struct {
|
||||
key string
|
||||
value string
|
||||
@@ -172,7 +220,7 @@ func seedData() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// CloseDB closes the database connection.
|
||||
// CloseDB 关闭数据库连接
|
||||
func CloseDB() error {
|
||||
if DB != nil {
|
||||
return DB.Close()
|
||||
|
||||
Reference in New Issue
Block a user