Tui 模块开发完成,数据正常写入数据库

This commit is contained in:
2026-03-06 16:33:08 +08:00
parent 3f5e333a4d
commit 8bc4f4fe04
7 changed files with 674 additions and 535 deletions

View File

@@ -3,6 +3,7 @@ package database
import (
"database/sql"
"fmt"
"strings"
"sync"
"sunhpc/pkg/config"
@@ -22,22 +23,20 @@ var (
dbErr error
)
// =========================================================
// 封装数据库函数使用Go实现
// =========================================================
// MapCategory - 根据类别名称查ID
// 查询方式: globalID, err := db.MapCategory(conn, "global")
func MapCategory(conn *sql.DB, catname string) (int, error) {
var id int
query := "select id from categories where name = ?"
logger.Debugf("查询SQL: %s", query)
logger.Debugf("查询类别ID: %s", catname)
fullSQL := ReplaceSQLQuery(query, catname)
err := conn.QueryRow(query, catname).Scan(&id)
if err == sql.ErrNoRows {
logger.Debugf("未找到类别 %s, 返回ID=0", catname)
return 0, nil // 无匹配返回0
}
logger.Debugf("查询到类别 %s, ID=%d", catname, id)
logger.Debugf("查询语句: %s , CatName=%s, ID=%d", fullSQL, catname, id)
return id, nil
}
@@ -49,14 +48,15 @@ func MapCategoryIndex(conn *sql.DB, catindexName, categoryIndex string) (int, er
select index_id from vmapCategoryIndex
where categoryName = ? and categoryIndex = ?
`
logger.Debugf("查询SQL: %s", query)
logger.Debugf("查询索引ID: %s, 类别: %s", catindexName, categoryIndex)
fullSQL := ReplaceSQLQuery(query, catindexName, categoryIndex)
err := conn.QueryRow(query, catindexName, categoryIndex).Scan(&id)
if err == sql.ErrNoRows {
logger.Debugf("未找到索引 %s, 返回ID=0", catindexName)
return 0, nil // 无匹配返回0
}
logger.Debugf("查询到索引 %s, ID=%d", catindexName, id)
logger.Debugf("查询语句: %s , CatIndexName=%s, CategoryIndex=%s, ID=%d",
fullSQL, catindexName, categoryIndex, id)
return id, nil
}
@@ -165,6 +165,13 @@ func GetDB() (*sql.DB, error) {
return
}
var version string
err = sqlDB.QueryRow("select sqlite_version()").Scan(&version)
if err != nil {
version = "unknown"
}
logger.Debugf("数据库版本: %s", version)
logger.Debug("数据库连接成功")
dbInstance = sqlDB
})
@@ -178,10 +185,44 @@ func GetDB() (*sql.DB, error) {
func InitTables(db *sql.DB, force bool) error {
// 临时关闭外键约束(解决外键依赖删除报错问题)
_, err := db.Exec("PRAGMA foreign_keys = OFF;")
if err != nil {
logger.Errorf("关闭外键约束失败: %v", err)
return err
}
defer func() {
// 延迟恢复外键约束(确保在函数退出时恢复)
_, err := db.Exec("PRAGMA foreign_keys = ON;")
if err != nil {
logger.Errorf("恢复外键约束失败: %v", err)
}
}()
// ✅ 调用 schema.go 中的函数
//for _, ddl := range CreateTableStatements() {
for _, ddl := range BaseTables() {
logger.Debugf("执行: %s", ddl)
for name, ddl := range BaseTables() {
// 删除表或者试图(如果存在)
logger.Debugf("执行删除 - %s", name)
// 先尝试作为表进行删除
query := fmt.Sprintf("DROP TABLE IF EXISTS %s;", name)
logger.Debugf("执行语句: %s", query)
_, err := db.Exec(query)
if err != nil {
// 如果作为表删除失败,尝试作为试图删除
logger.Debugf("删除表失败: %v", err)
query = fmt.Sprintf("DROP VIEW IF EXISTS %s;", name)
logger.Debugf("执行语句: %s", query)
_, err = db.Exec(query)
if err != nil {
return fmt.Errorf("删除失败: %w", err)
}
}
logger.Debugf("执行图表 - %s", name)
logger.Debugf("执行语句: %s", ddl)
if _, err := db.Exec(ddl); err != nil {
return fmt.Errorf("数据表创建失败: %w", err)
}
@@ -291,28 +332,36 @@ func ExecWithTransaction(ddl []string) error {
return err
}
var finished bool
// 延迟处理:如果函数异常,回滚事务
defer func() {
if r := recover(); r != nil {
// 捕获 panic 并回滚事务
tx.Rollback()
logger.Errorf("事务执行中发生 panic: %v", r)
if !finished {
// 捕获 panic 并回滚事务
tx.Rollback()
logger.Errorf("事务执行中发生 panic: %v", r)
}
panic(r)
}
}()
// 遍历执行 DDL 语句
for idx, sql := range ddl {
logger.Debugf("执行 DDL 语句 %d: %s", idx+1, sql)
_, err = tx.Exec(sql)
if err != nil {
// 执行失败时,回滚事务
rollbackErr := tx.Rollback()
finished = true // 标记事务已完成
if rollbackErr != nil {
logger.Errorf("执行失败: 回滚失败: %v (原错误: %v, SQL: %s)", rollbackErr, err, sql)
} else {
logger.Errorf("执行失败: 回滚事务: %v, SQL: %s", err, sql)
}
logger.Errorf("执行 %d 条, 失败: %w (SQL: %s)", idx+1, err, sql)
return fmt.Errorf("执行 %d 条, 失败: %w (SQL: %s)", idx+1, err, sql)
}
}
@@ -323,6 +372,21 @@ func ExecWithTransaction(ddl []string) error {
return err
}
finished = true // 标记事务已完成
logger.Debugf("成功执行 %d 条 SQL 语句, 事务已提交.", len(ddl))
return nil
}
func ReplaceSQLQuery(query string, args ...interface{}) string {
for _, arg := range args {
switch v := arg.(type) {
case string:
query = strings.Replace(query, "?", fmt.Sprintf("'%s'", v), 1)
case int, int64, float64:
query = strings.Replace(query, "?", fmt.Sprintf("%v", v), 1)
default:
query = strings.Replace(query, "?", fmt.Sprintf("%v", v), 1)
}
}
return strings.TrimSpace(strings.ReplaceAll(query, "\n", " "))
}