package main import ( "encoding/json" "fmt" "os" "time" . "code.hoteas.com/golang/hotime" . "code.hoteas.com/golang/hotime/common" . "code.hoteas.com/golang/hotime/db" ) // 调试日志文件路径 const debugLogPath = `d:\work\hotimev1\.cursor\debug.log` // debugLog 写入调试日志 func debugLog(location, message string, data interface{}, hypothesisId string) { // #region agent log logEntry := Map{ "location": location, "message": message, "data": data, "timestamp": time.Now().UnixMilli(), "sessionId": "debug-session", "runId": "hotimedb-test-run", "hypothesisId": hypothesisId, } jsonBytes, _ := json.Marshal(logEntry) f, err := os.OpenFile(debugLogPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err == nil { f.WriteString(string(jsonBytes) + "\n") f.Close() } // #endregion } func main() { debugLog("main.go:35", "开始 HoTimeDB 全功能测试", nil, "START") appIns := Init("config/config.json") appIns.SetConnectListener(func(that *Context) (isFinished bool) { return isFinished }) appIns.Run(Router{ "app": { "test": { // 测试入口 - 运行所有测试 "all": func(that *Context) { results := Map{} debugLog("main.go:48", "开始所有测试", nil, "ALL_TESTS") // 初始化测试表 initTestTables(that) // 1. 基础 CRUD 测试 results["1_basic_crud"] = testBasicCRUD(that) // 2. 条件查询语法测试 results["2_condition_syntax"] = testConditionSyntax(that) // 3. 链式查询测试 results["3_chain_query"] = testChainQuery(that) // 4. JOIN 查询测试 results["4_join_query"] = testJoinQuery(that) // 5. 聚合函数测试 results["5_aggregate"] = testAggregate(that) // 6. 分页查询测试 results["6_pagination"] = testPagination(that) // 7. 批量插入测试 results["7_batch_insert"] = testBatchInsert(that) // 8. Upsert 测试 results["8_upsert"] = testUpsert(that) // 9. 事务测试 results["9_transaction"] = testTransaction(that) // 10. 原生 SQL 测试 results["10_raw_sql"] = testRawSQL(that) debugLog("main.go:80", "所有测试完成", results, "ALL_TESTS_DONE") that.Display(0, results) }, // 查询数据库表结构 "tables": func(that *Context) { debugLog("main.go:tables", "查询数据库表结构", nil, "TABLES") // 查询所有表 tables := that.Db.Query("SHOW TABLES") debugLog("main.go:tables", "表列表", tables, "TABLES") that.Display(0, Map{"tables": tables}) }, // 查询指定表的结构 "describe": func(that *Context) { tableName := that.Req.FormValue("table") if tableName == "" { that.Display(1, "请提供 table 参数") return } // 查询表结构 columns := that.Db.Query("DESCRIBE " + tableName) // 查询表数据(前10条) data := that.Db.Select(tableName, Map{"LIMIT": 10}) debugLog("main.go:describe", "表结构", Map{"table": tableName, "columns": columns, "data": data}, "DESCRIBE") that.Display(0, Map{"table": tableName, "columns": columns, "sample_data": data}) }, // 单独测试入口 "crud": func(that *Context) { that.Display(0, testBasicCRUD(that)) }, "condition": func(that *Context) { that.Display(0, testConditionSyntax(that)) }, "chain": func(that *Context) { that.Display(0, testChainQuery(that)) }, "join": func(that *Context) { that.Display(0, testJoinQuery(that)) }, "aggregate": func(that *Context) { that.Display(0, testAggregate(that)) }, "pagination": func(that *Context) { that.Display(0, testPagination(that)) }, "batch": func(that *Context) { that.Display(0, testBatchInsert(that)) }, "upsert": func(that *Context) { that.Display(0, testUpsert(that)) }, "transaction": func(that *Context) { that.Display(0, testTransaction(that)) }, "rawsql": func(that *Context) { that.Display(0, testRawSQL(that)) }, }, }, }) } // initTestTables 初始化测试表(MySQL真实数据库) func initTestTables(that *Context) { // MySQL 真实数据库已有表,创建测试用的临时表 // 创建测试用的批量插入表 that.Db.Exec(`CREATE TABLE IF NOT EXISTS test_batch ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(100), title VARCHAR(200), state INT DEFAULT 0, create_time DATETIME )`) // 检查 admin 表数据 adminCount := that.Db.Count("admin") articleCount := that.Db.Count("article") debugLog("main.go:init", "MySQL数据库初始化检查完成", Map{ "adminCount": adminCount, "articleCount": articleCount, "dbType": "MySQL", }, "INIT") } // ==================== 1. 基础 CRUD 测试 ==================== func testBasicCRUD(that *Context) Map { result := Map{"name": "基础CRUD测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:103", "开始基础 CRUD 测试 (MySQL)", nil, "H1_CRUD") // 1.1 Insert 测试 - 使用 admin 表 insertTest := Map{"name": "Insert 插入测试 (admin表)"} adminId := that.Db.Insert("admin", Map{ "name": "测试管理员_" + fmt.Sprintf("%d", time.Now().Unix()), "phone": fmt.Sprintf("138%d", time.Now().Unix()%100000000), "state": 1, "password": "test123456", "role_id": 1, "title": "测试职位", "create_time[#]": "NOW()", "modify_time[#]": "NOW()", }) insertTest["result"] = adminId > 0 insertTest["adminId"] = adminId insertTest["lastQuery"] = that.Db.LastQuery debugLog("main.go:118", "Insert 测试", Map{"adminId": adminId, "success": adminId > 0, "query": that.Db.LastQuery}, "H1_INSERT") tests = append(tests, insertTest) // 1.2 Get 测试 getTest := Map{"name": "Get 获取单条记录测试"} admin := that.Db.Get("admin", "*", Map{"id": adminId}) getTest["result"] = admin != nil && admin.GetInt64("id") == adminId getTest["admin"] = admin debugLog("main.go:126", "Get 测试", Map{"admin": admin, "success": admin != nil}, "H1_GET") tests = append(tests, getTest) // 1.3 Select 测试 - 单条件 selectTest1 := Map{"name": "Select 单条件查询测试"} admins1 := that.Db.Select("admin", "*", Map{"state": 1, "LIMIT": 5}) selectTest1["result"] = len(admins1) >= 0 // 可能表中没有数据 selectTest1["count"] = len(admins1) debugLog("main.go:134", "Select 单条件测试", Map{"count": len(admins1)}, "H1_SELECT1") tests = append(tests, selectTest1) // 1.4 Select 测试 - 多条件(自动 AND) selectTest2 := Map{"name": "Select 多条件自动AND测试"} admins2 := that.Db.Select("admin", "*", Map{ "state": 1, "role_id[>]": 0, "ORDER": "id DESC", "LIMIT": 5, }) selectTest2["result"] = true // 只要不报错就算成功 selectTest2["count"] = len(admins2) selectTest2["lastQuery"] = that.Db.LastQuery debugLog("main.go:149", "Select 多条件自动AND测试", Map{"count": len(admins2), "query": that.Db.LastQuery}, "H1_SELECT2") tests = append(tests, selectTest2) // 1.5 Update 测试 updateTest := Map{"name": "Update 更新测试"} affected := that.Db.Update("admin", Map{ "title": "更新后的职位", "modify_time[#]": "NOW()", }, Map{"id": adminId}) updateTest["result"] = affected > 0 updateTest["affected"] = affected debugLog("main.go:160", "Update 测试", Map{"affected": affected}, "H1_UPDATE") tests = append(tests, updateTest) // 1.6 Delete 测试 - 使用 test_batch 表 deleteTest := Map{"name": "Delete 删除测试"} // 先创建一个临时记录用于删除 tempId := that.Db.Insert("test_batch", Map{ "name": "临时删除测试", "title": "测试标题", "state": 1, "create_time[#]": "NOW()", }) deleteAffected := that.Db.Delete("test_batch", Map{"id": tempId}) deleteTest["result"] = deleteAffected > 0 deleteTest["affected"] = deleteAffected debugLog("main.go:175", "Delete 测试", Map{"affected": deleteAffected}, "H1_DELETE") tests = append(tests, deleteTest) result["tests"] = tests result["success"] = true return result } // ==================== 2. 条件查询语法测试 ==================== func testConditionSyntax(that *Context) Map { result := Map{"name": "条件查询语法测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:188", "开始条件查询语法测试 (MySQL)", nil, "H2_CONDITION") // 2.1 等于 (=) - 使用 article 表 test1 := Map{"name": "等于条件 (=)"} articles1 := that.Db.Select("article", "id,title", Map{"state": 0, "LIMIT": 3}) test1["result"] = true test1["count"] = len(articles1) debugLog("main.go:195", "等于条件测试", Map{"count": len(articles1)}, "H2_EQUAL") tests = append(tests, test1) // 2.2 不等于 ([!]) test2 := Map{"name": "不等于条件 ([!])"} articles2 := that.Db.Select("article", "id,title,state", Map{"state[!]": -1, "LIMIT": 3}) test2["result"] = true test2["count"] = len(articles2) test2["lastQuery"] = that.Db.LastQuery debugLog("main.go:204", "不等于条件测试", Map{"count": len(articles2), "query": that.Db.LastQuery}, "H2_NOT_EQUAL") tests = append(tests, test2) // 2.3 大于 ([>]) 和 小于 ([<]) test3 := Map{"name": "大于小于条件 ([>], [<])"} articles3 := that.Db.Select("article", "id,title,click_num", Map{ "click_num[>]": 0, "click_num[<]": 100000, "LIMIT": 3, }) test3["result"] = true test3["count"] = len(articles3) debugLog("main.go:216", "大于小于条件测试", Map{"count": len(articles3)}, "H2_GREATER_LESS") tests = append(tests, test3) // 2.4 大于等于 ([>=]) 和 小于等于 ([<=]) test4 := Map{"name": "大于等于小于等于条件 ([>=], [<=])"} articles4 := that.Db.Select("article", "id,title,sort", Map{ "sort[>=]": 0, "sort[<=]": 100, "LIMIT": 3, }) test4["result"] = true test4["count"] = len(articles4) debugLog("main.go:228", "大于等于小于等于条件测试", Map{"count": len(articles4)}, "H2_GTE_LTE") tests = append(tests, test4) // 2.5 LIKE 模糊查询 ([~]) test5 := Map{"name": "LIKE 模糊查询 ([~])"} articles5 := that.Db.Select("article", "id,title", Map{"title[~]": "新闻", "LIMIT": 3}) test5["result"] = true test5["count"] = len(articles5) test5["lastQuery"] = that.Db.LastQuery debugLog("main.go:237", "LIKE 模糊查询测试", Map{"count": len(articles5), "query": that.Db.LastQuery}, "H2_LIKE") tests = append(tests, test5) // 2.6 右模糊 ([~!]) test6 := Map{"name": "右模糊查询 ([~!])"} articles6 := that.Db.Select("admin", "id,name", Map{"name[~!]": "管理", "LIMIT": 3}) test6["result"] = true test6["count"] = len(articles6) debugLog("main.go:245", "右模糊查询测试", Map{"count": len(articles6)}, "H2_LIKE_RIGHT") tests = append(tests, test6) // 2.7 BETWEEN ([<>]) test7 := Map{"name": "BETWEEN 区间查询 ([<>])"} articles7 := that.Db.Select("article", "id,title,click_num", Map{"click_num[<>]": Slice{0, 1000}, "LIMIT": 3}) test7["result"] = true test7["count"] = len(articles7) test7["lastQuery"] = that.Db.LastQuery debugLog("main.go:254", "BETWEEN 区间查询测试", Map{"count": len(articles7), "query": that.Db.LastQuery}, "H2_BETWEEN") tests = append(tests, test7) // 2.8 NOT BETWEEN ([><]) test8 := Map{"name": "NOT BETWEEN 查询 ([><])"} articles8 := that.Db.Select("article", "id,title,sort", Map{"sort[><]": Slice{-10, 0}, "LIMIT": 3}) test8["result"] = true test8["count"] = len(articles8) debugLog("main.go:262", "NOT BETWEEN 查询测试", Map{"count": len(articles8)}, "H2_NOT_BETWEEN") tests = append(tests, test8) // 2.9 IN 查询 test9 := Map{"name": "IN 查询"} articles9 := that.Db.Select("article", "id,title", Map{"id": Slice{1, 2, 3, 4, 5}, "LIMIT": 5}) test9["result"] = true test9["count"] = len(articles9) test9["lastQuery"] = that.Db.LastQuery debugLog("main.go:271", "IN 查询测试", Map{"count": len(articles9), "query": that.Db.LastQuery}, "H2_IN") tests = append(tests, test9) // 2.10 NOT IN ([!]) test10 := Map{"name": "NOT IN 查询 ([!])"} articles10 := that.Db.Select("article", "id,title", Map{"id[!]": Slice{1, 2, 3}, "LIMIT": 5}) test10["result"] = true test10["count"] = len(articles10) debugLog("main.go:279", "NOT IN 查询测试", Map{"count": len(articles10)}, "H2_NOT_IN") tests = append(tests, test10) // 2.11 IS NULL test11 := Map{"name": "IS NULL 查询"} articles11 := that.Db.Select("article", "id,title,img", Map{"img": nil, "LIMIT": 3}) test11["result"] = true test11["count"] = len(articles11) debugLog("main.go:287", "IS NULL 查询测试", Map{"count": len(articles11)}, "H2_IS_NULL") tests = append(tests, test11) // 2.12 IS NOT NULL ([!]) test12 := Map{"name": "IS NOT NULL 查询 ([!])"} articles12 := that.Db.Select("article", "id,title,create_time", Map{"create_time[!]": nil, "LIMIT": 3}) test12["result"] = true test12["count"] = len(articles12) debugLog("main.go:295", "IS NOT NULL 查询测试", Map{"count": len(articles12)}, "H2_IS_NOT_NULL") tests = append(tests, test12) // 2.13 直接 SQL ([##] 用于 SQL 片段) test13 := Map{"name": "直接 SQL 片段查询 ([##])"} articles13 := that.Db.Select("article", "id,title,create_time", Map{ "[##]": "create_time > DATE_SUB(NOW(), INTERVAL 365 DAY)", "LIMIT": 3, }) test13["result"] = true test13["count"] = len(articles13) test13["lastQuery"] = that.Db.LastQuery debugLog("main.go:307", "直接 SQL 片段查询测试", Map{"count": len(articles13), "query": that.Db.LastQuery}, "H2_RAW_SQL") tests = append(tests, test13) // 2.14 显式 AND 条件 test14 := Map{"name": "显式 AND 条件"} articles14 := that.Db.Select("article", "id,title,state,click_num", Map{ "AND": Map{ "state": 0, "click_num[>=]": 0, }, "LIMIT": 3, }) test14["result"] = true test14["count"] = len(articles14) debugLog("main.go:321", "显式 AND 条件测试", Map{"count": len(articles14)}, "H2_EXPLICIT_AND") tests = append(tests, test14) // 2.15 OR 条件 test15 := Map{"name": "OR 条件"} articles15 := that.Db.Select("article", "id,title,sort,click_num", Map{ "OR": Map{ "sort": 0, "click_num[>]": 10, }, "LIMIT": 5, }) test15["result"] = true test15["count"] = len(articles15) debugLog("main.go:335", "OR 条件测试", Map{"count": len(articles15)}, "H2_OR") tests = append(tests, test15) // 2.16 嵌套 AND/OR 条件 test16 := Map{"name": "嵌套 AND/OR 条件"} articles16 := that.Db.Select("article", "id,title,sort,state", Map{ "AND": Map{ "state": 0, "OR": Map{ "sort[>=]": 0, "click_num[>]": 0, }, }, "LIMIT": 5, }) test16["result"] = true test16["count"] = len(articles16) test16["lastQuery"] = that.Db.LastQuery debugLog("main.go:353", "嵌套 AND/OR 条件测试", Map{"count": len(articles16), "query": that.Db.LastQuery}, "H2_NESTED") tests = append(tests, test16) result["tests"] = tests result["success"] = true return result } // ==================== 3. 链式查询测试 ==================== func testChainQuery(that *Context) Map { result := Map{"name": "链式查询测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:366", "开始链式查询测试 (MySQL)", nil, "H3_CHAIN") // 3.1 基本链式查询 - 使用 article 表 test1 := Map{"name": "基本链式查询 Table().Where().Select()"} articles1 := that.Db.Table("article"). Where("state", 0). Select("id,title,author") test1["result"] = len(articles1) >= 0 test1["count"] = len(articles1) debugLog("main.go:375", "基本链式查询测试", Map{"count": len(articles1)}, "H3_BASIC") tests = append(tests, test1) // 3.2 链式 And 条件 test2 := Map{"name": "链式 And 条件"} articles2 := that.Db.Table("article"). Where("state", 0). And("click_num[>=]", 0). And("sort[>=]", 0). Select("id,title,click_num") test2["result"] = len(articles2) >= 0 test2["count"] = len(articles2) debugLog("main.go:387", "链式 And 条件测试", Map{"count": len(articles2)}, "H3_AND") tests = append(tests, test2) // 3.3 链式 Or 条件 test3 := Map{"name": "链式 Or 条件"} articles3 := that.Db.Table("article"). Where("state", 0). Or(Map{ "sort": 0, "click_num[>]": 10, }). Select("id,title,sort,click_num") test3["result"] = len(articles3) >= 0 test3["count"] = len(articles3) debugLog("main.go:401", "链式 Or 条件测试", Map{"count": len(articles3)}, "H3_OR") tests = append(tests, test3) // 3.4 链式 Order test4 := Map{"name": "链式 Order 排序"} articles4 := that.Db.Table("article"). Where("state", 0). Order("create_time DESC", "id ASC"). Limit(0, 5). Select("id,title,create_time") test4["result"] = len(articles4) >= 0 test4["count"] = len(articles4) debugLog("main.go:413", "链式 Order 排序测试", Map{"count": len(articles4)}, "H3_ORDER") tests = append(tests, test4) // 3.5 链式 Limit test5 := Map{"name": "链式 Limit 限制"} articles5 := that.Db.Table("article"). Where("state", 0). Limit(0, 3). Select("id,title") test5["result"] = len(articles5) <= 3 test5["count"] = len(articles5) debugLog("main.go:424", "链式 Limit 限制测试", Map{"count": len(articles5)}, "H3_LIMIT") tests = append(tests, test5) // 3.6 链式 Get 单条 test6 := Map{"name": "链式 Get 获取单条"} article6 := that.Db.Table("article"). Where("state", 0). Get("id,title,author") test6["result"] = article6 != nil || true // 允许为空 test6["article"] = article6 debugLog("main.go:434", "链式 Get 获取单条测试", Map{"article": article6}, "H3_GET") tests = append(tests, test6) // 3.7 链式 Count test7 := Map{"name": "链式 Count 统计"} count7 := that.Db.Table("article"). Where("state", 0). Count() test7["result"] = count7 >= 0 test7["count"] = count7 debugLog("main.go:444", "链式 Count 统计测试", Map{"count": count7}, "H3_COUNT") tests = append(tests, test7) // 3.8 链式 Page 分页 test8 := Map{"name": "链式 Page 分页"} articles8 := that.Db.Table("article"). Where("state", 0). Page(1, 5). Select("id,title") test8["result"] = len(articles8) <= 5 test8["count"] = len(articles8) debugLog("main.go:455", "链式 Page 分页测试", Map{"count": len(articles8)}, "H3_PAGE") tests = append(tests, test8) // 3.9 链式 Group 分组 test9 := Map{"name": "链式 Group 分组"} stats9 := that.Db.Table("article"). Where("state", 0). Group("ctg_id"). Select("ctg_id, COUNT(*) as cnt") test9["result"] = len(stats9) >= 0 test9["stats"] = stats9 debugLog("main.go:466", "链式 Group 分组测试", Map{"stats": stats9}, "H3_GROUP") tests = append(tests, test9) // 3.10 链式 Update test10 := Map{"name": "链式 Update 更新"} // 先获取一个文章ID testArticle := that.Db.Table("article").Where("state", 0).Get("id") if testArticle != nil { affected := that.Db.Table("article"). Where("id", testArticle.GetInt64("id")). Update(Map{"modify_time[#]": "NOW()"}) test10["result"] = affected >= 0 test10["affected"] = affected } else { test10["result"] = true test10["note"] = "无可用测试数据" } debugLog("main.go:483", "链式 Update 更新测试", test10, "H3_UPDATE") tests = append(tests, test10) result["tests"] = tests result["success"] = true return result } // ==================== 4. JOIN 查询测试 ==================== func testJoinQuery(that *Context) Map { result := Map{"name": "JOIN查询测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:496", "开始 JOIN 查询测试 (MySQL)", nil, "H4_JOIN") // 4.1 LEFT JOIN 链式 - article 关联 ctg test1 := Map{"name": "LEFT JOIN 链式查询"} articles1 := that.Db.Table("article"). LeftJoin("ctg", "article.ctg_id = ctg.id"). Where("article.state", 0). Limit(0, 5). Select("article.id, article.title, ctg.name as ctg_name") test1["result"] = len(articles1) >= 0 test1["count"] = len(articles1) test1["data"] = articles1 debugLog("main.go:508", "LEFT JOIN 链式查询测试", Map{"count": len(articles1)}, "H4_LEFT_JOIN") tests = append(tests, test1) // 4.2 传统 JOIN 语法 test2 := Map{"name": "传统 JOIN 语法"} articles2 := that.Db.Select("article", Slice{ Map{"[>]ctg": "article.ctg_id = ctg.id"}, }, "article.id, article.title, ctg.name as ctg_name", Map{ "article.state": 0, "LIMIT": 5, }) test2["result"] = len(articles2) >= 0 test2["count"] = len(articles2) test2["lastQuery"] = that.Db.LastQuery debugLog("main.go:525", "传统 JOIN 语法测试", Map{"count": len(articles2), "query": that.Db.LastQuery}, "H4_TRADITIONAL_JOIN") tests = append(tests, test2) // 4.3 多表 JOIN - article 关联 ctg 和 admin test3 := Map{"name": "多表 JOIN"} articles3 := that.Db.Table("article"). LeftJoin("ctg", "article.ctg_id = ctg.id"). LeftJoin("admin", "article.admin_id = admin.id"). Where("article.state", 0). Limit(0, 5). Select("article.id, article.title, ctg.name as ctg_name, admin.name as admin_name") test3["result"] = len(articles3) >= 0 test3["count"] = len(articles3) test3["data"] = articles3 debugLog("main.go:539", "多表 JOIN 测试", Map{"count": len(articles3)}, "H4_MULTI_JOIN") tests = append(tests, test3) // 4.4 INNER JOIN test4 := Map{"name": "INNER JOIN"} articles4 := that.Db.Table("article"). InnerJoin("ctg", "article.ctg_id = ctg.id"). Where("ctg.state", 0). Limit(0, 5). Select("article.id, article.title, ctg.name as ctg_name") test4["result"] = len(articles4) >= 0 test4["count"] = len(articles4) debugLog("main.go:551", "INNER JOIN 测试", Map{"count": len(articles4)}, "H4_INNER_JOIN") tests = append(tests, test4) result["tests"] = tests result["success"] = true return result } // ==================== 5. 聚合函数测试 ==================== func testAggregate(that *Context) Map { result := Map{"name": "聚合函数测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:564", "开始聚合函数测试 (MySQL)", nil, "H5_AGGREGATE") // 5.1 Count 总数 test1 := Map{"name": "Count 总数统计"} count1 := that.Db.Count("article") test1["result"] = count1 >= 0 test1["count"] = count1 debugLog("main.go:571", "Count 总数统计测试", Map{"count": count1}, "H5_COUNT") tests = append(tests, test1) // 5.2 Count 带条件 test2 := Map{"name": "Count 条件统计"} count2 := that.Db.Count("article", Map{"state": 0}) test2["result"] = count2 >= 0 test2["count"] = count2 debugLog("main.go:579", "Count 条件统计测试", Map{"count": count2}, "H5_COUNT_WHERE") tests = append(tests, test2) // 5.3 Sum 求和 test3 := Map{"name": "Sum 求和"} sum3 := that.Db.Sum("article", "click_num", Map{"state": 0}) test3["result"] = sum3 >= 0 test3["sum"] = sum3 debugLog("main.go:587", "Sum 求和测试", Map{"sum": sum3}, "H5_SUM") tests = append(tests, test3) // 5.4 Avg 平均值 test4 := Map{"name": "Avg 平均值"} avg4 := that.Db.Avg("article", "click_num", Map{"state": 0}) test4["result"] = avg4 >= 0 test4["avg"] = avg4 debugLog("main.go:595", "Avg 平均值测试", Map{"avg": avg4}, "H5_AVG") tests = append(tests, test4) // 5.5 Max 最大值 test5 := Map{"name": "Max 最大值"} max5 := that.Db.Max("article", "click_num", Map{"state": 0}) test5["result"] = max5 >= 0 test5["max"] = max5 debugLog("main.go:603", "Max 最大值测试", Map{"max": max5}, "H5_MAX") tests = append(tests, test5) // 5.6 Min 最小值 test6 := Map{"name": "Min 最小值"} min6 := that.Db.Min("article", "sort", Map{"state": 0}) test6["result"] = true // sort 可能为 0 test6["min"] = min6 debugLog("main.go:611", "Min 最小值测试", Map{"min": min6}, "H5_MIN") tests = append(tests, test6) // 5.7 GROUP BY 分组统计 test7 := Map{"name": "GROUP BY 分组统计"} stats7 := that.Db.Select("article", "ctg_id, COUNT(*) as article_count, AVG(click_num) as avg_clicks, SUM(click_num) as total_clicks", Map{ "state": 0, "GROUP": "ctg_id", "ORDER": "article_count DESC", "LIMIT": 10, }) test7["result"] = len(stats7) >= 0 test7["stats"] = stats7 debugLog("main.go:625", "GROUP BY 分组统计测试", Map{"stats": stats7}, "H5_GROUP_BY") tests = append(tests, test7) result["tests"] = tests result["success"] = true return result } // ==================== 6. 分页查询测试 ==================== func testPagination(that *Context) Map { result := Map{"name": "分页查询测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:638", "开始分页查询测试 (MySQL)", nil, "H6_PAGINATION") // 6.1 PageSelect 分页查询 test1 := Map{"name": "PageSelect 分页查询"} articles1 := that.Db.Page(1, 5).PageSelect("article", "*", Map{ "state": 0, "ORDER": "id DESC", }) test1["result"] = len(articles1) <= 5 test1["count"] = len(articles1) debugLog("main.go:648", "PageSelect 分页查询测试", Map{"count": len(articles1)}, "H6_PAGE_SELECT") tests = append(tests, test1) // 6.2 第二页 test2 := Map{"name": "PageSelect 第二页"} articles2 := that.Db.Page(2, 5).PageSelect("article", "*", Map{ "state": 0, "ORDER": "id DESC", }) test2["result"] = len(articles2) <= 5 test2["count"] = len(articles2) debugLog("main.go:659", "PageSelect 第二页测试", Map{"count": len(articles2)}, "H6_PAGE_2") tests = append(tests, test2) // 6.3 链式分页 test3 := Map{"name": "链式 Page 分页"} articles3 := that.Db.Table("article"). Where("state", 0). Order("id DESC"). Page(1, 3). Select("id,title,author") test3["result"] = len(articles3) <= 3 test3["count"] = len(articles3) debugLog("main.go:671", "链式 Page 分页测试", Map{"count": len(articles3)}, "H6_CHAIN_PAGE") tests = append(tests, test3) // 6.4 Offset 偏移 test4 := Map{"name": "Offset 偏移查询"} articles4 := that.Db.Table("article"). Where("state", 0). Limit(3). Offset(2). Select("id,title") test4["result"] = len(articles4) <= 3 test4["count"] = len(articles4) test4["lastQuery"] = that.Db.LastQuery debugLog("main.go:684", "Offset 偏移查询测试", Map{"count": len(articles4), "query": that.Db.LastQuery}, "H6_OFFSET") tests = append(tests, test4) result["tests"] = tests result["success"] = true return result } // ==================== 7. 批量插入测试 ==================== func testBatchInsert(that *Context) Map { result := Map{"name": "批量插入测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:697", "开始批量插入测试 (MySQL)", nil, "H7_BATCH") // 7.1 批量插入 test1 := Map{"name": "BatchInsert 批量插入"} timestamp := time.Now().UnixNano() affected1 := that.Db.BatchInsert("test_batch", []Map{ {"name": fmt.Sprintf("批量测试1_%d", timestamp), "title": "标题1", "state": 1}, {"name": fmt.Sprintf("批量测试2_%d", timestamp), "title": "标题2", "state": 1}, {"name": fmt.Sprintf("批量测试3_%d", timestamp), "title": "标题3", "state": 1}, }) test1["result"] = affected1 >= 0 test1["affected"] = affected1 test1["lastQuery"] = that.Db.LastQuery debugLog("main.go:710", "BatchInsert 批量插入测试", Map{"affected": affected1, "query": that.Db.LastQuery}, "H7_BATCH_INSERT") tests = append(tests, test1) // 7.2 带 [#] 的批量插入 test2 := Map{"name": "BatchInsert 带 [#] 标记"} timestamp2 := time.Now().UnixNano() affected2 := that.Db.BatchInsert("test_batch", []Map{ {"name": fmt.Sprintf("带时间测试1_%d", timestamp2), "title": "标题带时间1", "state": 1, "create_time[#]": "NOW()"}, {"name": fmt.Sprintf("带时间测试2_%d", timestamp2), "title": "标题带时间2", "state": 1, "create_time[#]": "NOW()"}, }) test2["result"] = affected2 >= 0 test2["affected"] = affected2 debugLog("main.go:722", "BatchInsert 带 [#] 标记测试", Map{"affected": affected2}, "H7_BATCH_RAW") tests = append(tests, test2) // 清理测试数据 that.Db.Delete("test_batch", Map{"name[~]": fmt.Sprintf("_%d", timestamp)}) that.Db.Delete("test_batch", Map{"name[~]": fmt.Sprintf("_%d", timestamp2)}) result["tests"] = tests result["success"] = true return result } // ==================== 8. Upsert 测试 ==================== func testUpsert(that *Context) Map { result := Map{"name": "Upsert测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:739", "开始 Upsert 测试 (MySQL)", nil, "H8_UPSERT") // 使用 admin 表测试 Upsert(MySQL ON DUPLICATE KEY UPDATE) timestamp := time.Now().Unix() testPhone := fmt.Sprintf("199%08d", timestamp%100000000) // 8.1 Upsert 插入新记录 test1 := Map{"name": "Upsert 插入新记录 (admin表)"} affected1 := that.Db.Upsert("admin", Map{ "name": "Upsert测试管理员", "phone": testPhone, "state": 1, "password": "test123", "role_id": 1, "title": "测试职位", "create_time[#]": "NOW()", "modify_time[#]": "NOW()", }, Slice{"phone"}, Slice{"name", "state", "title", "modify_time"}, ) test1["result"] = affected1 >= 0 test1["affected"] = affected1 test1["lastQuery"] = that.Db.LastQuery debugLog("main.go:763", "Upsert 插入新记录测试", Map{"affected": affected1, "query": that.Db.LastQuery}, "H8_UPSERT_INSERT") tests = append(tests, test1) // 8.2 Upsert 更新已存在记录 test2 := Map{"name": "Upsert 更新已存在记录"} affected2 := that.Db.Upsert("admin", Map{ "name": "Upsert更新后管理员", "phone": testPhone, "state": 1, "password": "updated123", "role_id": 2, "title": "更新后职位", "create_time[#]": "NOW()", "modify_time[#]": "NOW()", }, Slice{"phone"}, Slice{"name", "title", "role_id", "modify_time"}, ) test2["result"] = affected2 >= 0 test2["affected"] = affected2 debugLog("main.go:783", "Upsert 更新已存在记录测试", Map{"affected": affected2}, "H8_UPSERT_UPDATE") tests = append(tests, test2) // 验证更新结果 updatedAdmin := that.Db.Get("admin", "*", Map{"phone": testPhone}) test2["updatedAdmin"] = updatedAdmin // 清理测试数据 that.Db.Delete("admin", Map{"phone": testPhone}) result["tests"] = tests result["success"] = true return result } // ==================== 9. 事务测试 ==================== func testTransaction(that *Context) Map { result := Map{"name": "事务测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:803", "开始事务测试 (MySQL)", nil, "H9_TRANSACTION") // 9.1 事务成功提交 test1 := Map{"name": "事务成功提交"} timestamp := time.Now().Unix() testName1 := fmt.Sprintf("事务测试_%d", timestamp) success1 := that.Db.Action(func(tx HoTimeDB) bool { // 插入记录到 test_batch 表 recordId := tx.Insert("test_batch", Map{ "name": testName1, "title": "事务提交测试", "state": 1, "create_time[#]": "NOW()", }) debugLog("main.go:818", "事务内插入记录", Map{"recordId": recordId}, "H9_TX_INSERT") return recordId != 0 }) test1["result"] = success1 // 验证数据是否存在 checkRecord := that.Db.Get("test_batch", "*", Map{"name": testName1}) test1["recordExists"] = checkRecord != nil debugLog("main.go:831", "事务成功提交测试", Map{"success": success1, "recordExists": checkRecord != nil}, "H9_TX_SUCCESS") tests = append(tests, test1) // 9.2 事务回滚 test2 := Map{"name": "事务回滚"} testName2 := fmt.Sprintf("事务回滚测试_%d", timestamp) success2 := that.Db.Action(func(tx HoTimeDB) bool { // 插入记录 recordId := tx.Insert("test_batch", Map{ "name": testName2, "title": "事务回滚测试", "state": 1, "create_time[#]": "NOW()", }) debugLog("main.go:846", "事务内插入(将回滚)", Map{"recordId": recordId}, "H9_TX_ROLLBACK_INSERT") // 返回 false 触发回滚 return false }) test2["result"] = !success2 // 期望回滚,所以 success2 应该为 false // 验证数据是否不存在(已回滚) checkRecord2 := that.Db.Get("test_batch", "*", Map{"name": testName2}) test2["recordRolledBack"] = checkRecord2 == nil debugLog("main.go:856", "事务回滚测试", Map{"success": success2, "rolledBack": checkRecord2 == nil}, "H9_TX_ROLLBACK") tests = append(tests, test2) // 清理测试数据 that.Db.Delete("test_batch", Map{"name": testName1}) result["tests"] = tests result["success"] = true return result } // ==================== 10. 原生 SQL 测试 ==================== func testRawSQL(that *Context) Map { result := Map{"name": "原生SQL测试", "tests": Slice{}} tests := Slice{} debugLog("main.go:872", "开始原生 SQL 测试 (MySQL)", nil, "H10_RAW_SQL") // 10.1 Query 查询 - 使用真实的 article 表 test1 := Map{"name": "Query 原生查询"} articles1 := that.Db.Query("SELECT id, title, author FROM `article` WHERE state = ? LIMIT ?", 0, 5) test1["result"] = len(articles1) >= 0 test1["count"] = len(articles1) debugLog("main.go:879", "Query 原生查询测试", Map{"count": len(articles1)}, "H10_QUERY") tests = append(tests, test1) // 10.2 Exec 执行 - 使用 article 表 test2 := Map{"name": "Exec 原生执行"} // 更新一条记录 testArticle := that.Db.Get("article", "id", Map{"state": 0}) if testArticle != nil { res, err := that.Db.Exec("UPDATE `article` SET modify_time = NOW() WHERE id = ?", testArticle.GetInt64("id")) if err.GetError() == nil && res != nil { affected, _ := res.RowsAffected() test2["result"] = affected >= 0 test2["affected"] = affected } else { test2["result"] = false test2["error"] = err.GetError() } } else { test2["result"] = true test2["note"] = "无可用测试数据" } debugLog("main.go:899", "Exec 原生执行测试", test2, "H10_EXEC") tests = append(tests, test2) result["tests"] = tests result["success"] = true return result }