7f7b585ffb
- 在应用程序中新增对达梦数据库(DM)的配置和连接支持 - 实现 SetDmDB 函数以配置达梦数据库连接 - 更新数据库操作逻辑,支持达梦特有的 SQL 语法和功能 - 在相关文件中添加达梦数据库的处理逻辑,包括表创建、数据插入和查询 - 更新 go.mod 和 go.sum 文件以引入达梦数据库驱动 - 增强文档,详细说明达梦数据库的配置和使用方法
295 lines
11 KiB
Go
295 lines
11 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
. "code.hoteas.com/golang/hotime"
|
|
. "code.hoteas.com/golang/hotime/common"
|
|
)
|
|
|
|
// CacheCtr 缓存测试控制器(数据库无关)
|
|
var CacheCtr = Ctr{
|
|
"all": func(that *Context) { that.Display(0, testCacheAll(that)) },
|
|
"compat": func(that *Context) { that.Display(0, testCacheCompatible(that)) },
|
|
"batch": func(that *Context) {
|
|
that.Display(0, Map{"message": "批量缓存测试完成,请查看控制台输出和日志文件"})
|
|
},
|
|
}
|
|
|
|
func testCacheAll(that *Context) Map {
|
|
result := Map{"name": "数据库缓存测试", "tests": Slice{}}
|
|
tests := Slice{}
|
|
|
|
cacheMode := "unknown"
|
|
if that.Application.HoTimeCache != nil && that.Application.HoTimeCache.Config != nil {
|
|
dbConfig := that.Application.HoTimeCache.Config.GetMap("db")
|
|
if dbConfig != nil {
|
|
cacheMode = dbConfig.GetString("mode")
|
|
if cacheMode == "" {
|
|
cacheMode = "new"
|
|
}
|
|
}
|
|
}
|
|
result["cache_mode"] = cacheMode
|
|
|
|
testPrefix := fmt.Sprintf("cache_test_%d_", time.Now().UnixNano())
|
|
|
|
// 1. 基础读写测试
|
|
test1 := Map{"name": "1. 基础 set/get 测试"}
|
|
testKey1 := testPrefix + "basic"
|
|
testValue1 := Map{"name": "测试数据", "count": 123, "active": true}
|
|
that.Application.Cache(testKey1, testValue1)
|
|
cached1 := that.Application.Cache(testKey1)
|
|
if cached1.Data != nil {
|
|
cachedMap := cached1.ToMap()
|
|
test1["result"] = cachedMap.GetString("name") == "测试数据" && cachedMap.GetInt("count") == 123
|
|
test1["cached_value"] = cachedMap
|
|
} else {
|
|
test1["result"] = false
|
|
test1["error"] = "缓存读取返回 nil"
|
|
}
|
|
tests = append(tests, test1)
|
|
|
|
// 2. 删除缓存测试
|
|
test2 := Map{"name": "2. delete 删除缓存测试"}
|
|
testKey2 := testPrefix + "delete"
|
|
that.Application.Cache(testKey2, "删除测试值")
|
|
before := that.Application.Cache(testKey2)
|
|
beforeExists := before.Data != nil
|
|
that.Application.Cache(testKey2, nil)
|
|
after := that.Application.Cache(testKey2)
|
|
afterExists := after.Data != nil
|
|
test2["result"] = beforeExists && !afterExists
|
|
test2["before_exists"] = beforeExists
|
|
test2["after_exists"] = afterExists
|
|
tests = append(tests, test2)
|
|
|
|
// 3. 过期时间测试
|
|
test3 := Map{"name": "3. 过期时间测试(短超时)"}
|
|
testKey3 := testPrefix + "expire"
|
|
that.Application.Cache(testKey3, "短期数据", 2)
|
|
immediate := that.Application.Cache(testKey3)
|
|
immediateExists := immediate.Data != nil
|
|
test3["result"] = immediateExists
|
|
test3["immediate_exists"] = immediateExists
|
|
test3["note"] = "设置了2秒过期,可等待后再次访问验证过期"
|
|
tests = append(tests, test3)
|
|
|
|
// 4. 不存在的 key 读取测试
|
|
test4 := Map{"name": "4. 不存在的 key 读取测试"}
|
|
nonExistKey := testPrefix + "non_exist_key_" + fmt.Sprintf("%d", time.Now().UnixNano())
|
|
nonExist := that.Application.Cache(nonExistKey)
|
|
test4["result"] = nonExist.Data == nil
|
|
test4["value"] = nonExist.Data
|
|
tests = append(tests, test4)
|
|
|
|
// 5. 重复 set 同一个 key 测试
|
|
test5 := Map{"name": "5. 重复 set 同一个 key 测试"}
|
|
testKey5 := testPrefix + "repeat"
|
|
that.Application.Cache(testKey5, "第一次值")
|
|
first := that.Application.Cache(testKey5).ToStr()
|
|
that.Application.Cache(testKey5, "第二次值")
|
|
second := that.Application.Cache(testKey5).ToStr()
|
|
that.Application.Cache(testKey5, Map{"version": 3})
|
|
third := that.Application.Cache(testKey5).ToMap()
|
|
test5["result"] = first == "第一次值" && second == "第二次值" && third.GetInt("version") == 3
|
|
test5["first"] = first
|
|
test5["second"] = second
|
|
test5["third"] = third
|
|
tests = append(tests, test5)
|
|
|
|
// 6. 通配删除测试
|
|
test6 := Map{"name": "6. 通配删除测试 (key*)"}
|
|
wildcardPrefix := testPrefix + "wildcard_"
|
|
that.Application.Cache(wildcardPrefix+"a", "值A")
|
|
that.Application.Cache(wildcardPrefix+"b", "值B")
|
|
that.Application.Cache(wildcardPrefix+"c", "值C")
|
|
aExists := that.Application.Cache(wildcardPrefix+"a").Data != nil
|
|
bExists := that.Application.Cache(wildcardPrefix+"b").Data != nil
|
|
cExists := that.Application.Cache(wildcardPrefix+"c").Data != nil
|
|
allExistBefore := aExists && bExists && cExists
|
|
that.Application.Cache(wildcardPrefix+"*", nil)
|
|
aAfter := that.Application.Cache(wildcardPrefix+"a").Data != nil
|
|
bAfter := that.Application.Cache(wildcardPrefix+"b").Data != nil
|
|
cAfter := that.Application.Cache(wildcardPrefix+"c").Data != nil
|
|
allDeletedAfter := !aAfter && !bAfter && !cAfter
|
|
test6["result"] = allExistBefore && allDeletedAfter
|
|
test6["before"] = Map{"a": aExists, "b": bExists, "c": cExists}
|
|
test6["after"] = Map{"a": aAfter, "b": bAfter, "c": cAfter}
|
|
tests = append(tests, test6)
|
|
|
|
// 7. 不同数据类型测试
|
|
test7 := Map{"name": "7. 不同数据类型存储测试"}
|
|
that.Application.Cache(testPrefix+"type_string", "字符串值")
|
|
typeString := that.Application.Cache(testPrefix + "type_string").ToStr()
|
|
that.Application.Cache(testPrefix+"type_int", 12345)
|
|
typeInt := that.Application.Cache(testPrefix + "type_int").ToInt()
|
|
that.Application.Cache(testPrefix+"type_float", 3.14159)
|
|
typeFloat := that.Application.Cache(testPrefix + "type_float").ToFloat64()
|
|
that.Application.Cache(testPrefix+"type_bool", true)
|
|
typeBoolData := that.Application.Cache(testPrefix + "type_bool").Data
|
|
typeBool := typeBoolData == true || typeBoolData == "true" || typeBoolData == 1.0
|
|
that.Application.Cache(testPrefix+"type_map", Map{"key": "value", "num": 100})
|
|
typeMap := that.Application.Cache(testPrefix + "type_map").ToMap()
|
|
that.Application.Cache(testPrefix+"type_slice", Slice{1, 2, 3, "four", Map{"five": 5}})
|
|
typeSlice := that.Application.Cache(testPrefix + "type_slice").ToSlice()
|
|
test7["result"] = typeString == "字符串值" &&
|
|
typeInt == 12345 &&
|
|
typeFloat > 3.14 && typeFloat < 3.15 &&
|
|
typeBool == true &&
|
|
typeMap.GetString("key") == "value" &&
|
|
len(typeSlice) == 5
|
|
test7["string"] = typeString
|
|
test7["int"] = typeInt
|
|
test7["float"] = typeFloat
|
|
test7["bool"] = typeBool
|
|
test7["map"] = typeMap
|
|
test7["slice"] = typeSlice
|
|
tests = append(tests, test7)
|
|
|
|
// 8. 自定义超时时间测试
|
|
test8 := Map{"name": "8. 自定义超时时间参数测试"}
|
|
testKey8 := testPrefix + "custom_timeout"
|
|
that.Application.Cache(testKey8, "长期数据", 3600)
|
|
longTerm := that.Application.Cache(testKey8)
|
|
test8["result"] = longTerm.Data != nil
|
|
test8["value"] = longTerm.ToStr()
|
|
tests = append(tests, test8)
|
|
|
|
// 9. 查询缓存表状态
|
|
test9 := Map{"name": "9. 缓存表状态查询"}
|
|
prefix := that.Db.GetPrefix()
|
|
newTableName := prefix + "hotime_cache"
|
|
newCount := that.Db.Count(newTableName)
|
|
test9["new_table_count"] = newCount
|
|
test9["new_table_name"] = newTableName
|
|
test9["result"] = newCount >= 0
|
|
tests = append(tests, test9)
|
|
|
|
that.Application.Cache(testPrefix+"*", nil)
|
|
|
|
result["tests"] = tests
|
|
result["success"] = true
|
|
result["cleanup"] = "已清理所有测试缓存数据"
|
|
return result
|
|
}
|
|
|
|
func testCacheCompatible(that *Context) Map {
|
|
result := Map{
|
|
"test_name": "兼容模式白盒测试",
|
|
"timestamp": time.Now().Format("2006-01-02 15:04:05"),
|
|
}
|
|
|
|
prefix := that.Db.GetPrefix()
|
|
newTableName := prefix + "hotime_cache"
|
|
legacyTableName := prefix + "cached"
|
|
|
|
tests := Slice{}
|
|
|
|
test1 := Map{"name": "1. 查询当前缓存模式"}
|
|
cacheConfig := that.Application.Config.GetMap("cache")
|
|
dbConfig := cacheConfig.GetMap("db")
|
|
mode := dbConfig.GetString("mode")
|
|
if mode == "" {
|
|
mode = "默认(compatible)"
|
|
}
|
|
test1["mode"] = mode
|
|
test1["result"] = true
|
|
tests = append(tests, test1)
|
|
|
|
// 根据数据库类型使用不同的引号
|
|
q := "`"
|
|
if that.Db.Dialect != nil {
|
|
q = that.Db.Dialect.QuoteChar()
|
|
}
|
|
|
|
test2 := Map{"name": "2. 查询老表cached现有数据"}
|
|
legacyData := that.Db.Query("SELECT * FROM " + q + legacyTableName + q + " LIMIT 5")
|
|
test2["legacy_table"] = legacyTableName
|
|
test2["count"] = len(legacyData)
|
|
test2["data"] = legacyData
|
|
test2["result"] = true
|
|
tests = append(tests, test2)
|
|
|
|
test3 := Map{"name": "3. 查询新表hotime_cache现有数据"}
|
|
newData := that.Db.Query("SELECT * FROM " + q + newTableName + q + " LIMIT 5")
|
|
test3["new_table"] = newTableName
|
|
test3["count"] = len(newData)
|
|
test3["data"] = newData
|
|
test3["result"] = true
|
|
tests = append(tests, test3)
|
|
|
|
test4 := Map{"name": "4. 测试兼容模式老表回退读取"}
|
|
testKey4 := "test_compat_fallback_" + ObjToStr(time.Now().UnixNano())
|
|
testValue4 := Map{"admin_id": 999, "admin_name": "测试老数据"}
|
|
testValueJson4 := ObjToStr(Map{"data": testValue4})
|
|
that.Db.Insert(legacyTableName, Map{
|
|
"key": testKey4,
|
|
"value": testValueJson4,
|
|
"endtime": time.Now().Unix() + 3600,
|
|
"time": time.Now().UnixNano(),
|
|
})
|
|
test4["test_key"] = testKey4
|
|
newExists := that.Db.Get(newTableName, "*", Map{"key": testKey4})
|
|
test4["key_in_new_table"] = newExists != nil
|
|
cacheValue := that.Application.Cache(testKey4)
|
|
test4["cache_api_result"] = cacheValue.Data
|
|
test4["result"] = newExists == nil && cacheValue.Data != nil
|
|
tests = append(tests, test4)
|
|
|
|
test5 := Map{"name": "5. 测试兼容模式写新删老"}
|
|
testKey5 := "test_compat_write_" + ObjToStr(time.Now().UnixNano())
|
|
testValue5 := "兼容模式测试数据"
|
|
that.Db.Insert(legacyTableName, Map{
|
|
"key": testKey5,
|
|
"value": `{"data":"老表原始数据"}`,
|
|
"endtime": time.Now().Unix() + 3600,
|
|
"time": time.Now().UnixNano(),
|
|
})
|
|
legacyBefore := that.Db.Get(legacyTableName, "*", Map{"key": testKey5})
|
|
test5["step1_legacy_before"] = legacyBefore != nil
|
|
that.Application.Cache(testKey5, testValue5)
|
|
newAfter := that.Db.Get(newTableName, "*", Map{"key": testKey5})
|
|
test5["step2_new_after"] = newAfter != nil
|
|
if newAfter != nil {
|
|
test5["new_value"] = newAfter.GetString("value")
|
|
}
|
|
legacyAfter := that.Db.Get(legacyTableName, "*", Map{"key": testKey5})
|
|
test5["step3_legacy_after_deleted"] = legacyAfter == nil
|
|
test5["result"] = legacyBefore != nil && newAfter != nil && legacyAfter == nil
|
|
tests = append(tests, test5)
|
|
|
|
test6 := Map{"name": "6. 测试兼容模式删除(删除两表)"}
|
|
testKey6 := "test_compat_delete_" + ObjToStr(time.Now().UnixNano())
|
|
that.Db.Insert(legacyTableName, Map{
|
|
"key": testKey6,
|
|
"value": `{"data":"待删除老数据"}`,
|
|
"endtime": time.Now().Unix() + 3600,
|
|
"time": time.Now().UnixNano(),
|
|
})
|
|
that.Db.Insert(newTableName, Map{
|
|
"key": testKey6,
|
|
"value": `"待删除新数据"`,
|
|
"end_time": time.Now().Add(time.Hour).Format("2006-01-02 15:04:05"),
|
|
"state": 0,
|
|
"create_time": time.Now().Format("2006-01-02 15:04:05"),
|
|
"modify_time": time.Now().Format("2006-01-02 15:04:05"),
|
|
})
|
|
test6["before_legacy"] = that.Db.Get(legacyTableName, "*", Map{"key": testKey6}) != nil
|
|
test6["before_new"] = that.Db.Get(newTableName, "*", Map{"key": testKey6}) != nil
|
|
that.Application.Cache(testKey6, nil)
|
|
test6["after_legacy_deleted"] = that.Db.Get(legacyTableName, "*", Map{"key": testKey6}) == nil
|
|
test6["after_new_deleted"] = that.Db.Get(newTableName, "*", Map{"key": testKey6}) == nil
|
|
test6["result"] = test6.GetBool("before_legacy") && test6.GetBool("before_new") &&
|
|
test6.GetBool("after_legacy_deleted") && test6.GetBool("after_new_deleted")
|
|
tests = append(tests, test6)
|
|
|
|
that.Db.Delete(newTableName, Map{"key[~]": "test_compat_%"})
|
|
that.Db.Delete(legacyTableName, Map{"key[~]": "test_compat_%"})
|
|
|
|
result["tests"] = tests
|
|
result["success"] = true
|
|
return result
|
|
}
|