diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ba63cb..53d67ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ # 变更记录 - @go/db -## [1.3.1] - 2026-05-13 +## [1.0.11] - 2026-05-13 +- **基础设施对齐**: + - 移除 `encoding/json` 原生依赖,全面切换至 `apigo.cc/go/cast.UnmarshalJSON` 以增强类型兼容性。 + - 移除测试代码中对 `os.Remove` 的直接调用,统一切换至 `apigo.cc/go/file.Remove` 以支持隔离文件系统。 +- **稳定性增强**: + - 验证并更新了测试用例,确保在 Go 1.25.0 环境下的执行稳定性。 + - 更新 `TEST.md` 性能基准,反映基础设施对齐后的最新指标。 + +## [1.0.10] - 2026-05-10 - **功能增强**: - 全面支持“复杂标识符”:改进了 `LIKE` 拦截逻辑中的正则表达式,支持带引号(`` ` ``, `"`, `'`, `[]`)和特殊字符(如 `-`)的表名与字段名。 - 优化 `cleanIdentifier`:能够更精准地剥离多段式标识符(如 `table.column`)中的包装引号。 diff --git a/DB_test.go b/DB_test.go index 71024e1..2476f36 100644 --- a/DB_test.go +++ b/DB_test.go @@ -10,6 +10,7 @@ import ( "apigo.cc/go/cast" "apigo.cc/go/db" + "apigo.cc/go/file" "apigo.cc/go/shell" _ "apigo.cc/go/db/mysql" @@ -18,7 +19,7 @@ import ( func TestMain(m *testing.M) { code := m.Run() - os.Remove("test.db") + file.Remove("test.db") os.Exit(code) } diff --git a/FTS_test.go b/FTS_test.go index 3e1b9f2..6d44146 100644 --- a/FTS_test.go +++ b/FTS_test.go @@ -1,18 +1,18 @@ package db_test import ( - "os" "strings" "testing" "apigo.cc/go/db" + "apigo.cc/go/file" _ "modernc.org/sqlite" ) func TestAutonomousFTS(t *testing.T) { dbPath := "test_fts.db" dbInst := db.GetDB("sqlite://"+dbPath, nil) - defer os.Remove(dbPath) + defer file.Remove(dbPath) defer dbInst.Exec("DROP TABLE IF EXISTS fts_test") defer dbInst.Exec("DROP TABLE IF EXISTS fts_test_fts") diff --git a/Result.go b/Result.go index 9c71d5a..e3f44ac 100644 --- a/Result.go +++ b/Result.go @@ -2,7 +2,6 @@ package db import ( "database/sql" - "encoding/json" "errors" "fmt" "reflect" @@ -436,7 +435,7 @@ func (r *QueryResult) makeResults(results any, rows *sql.Rows) error { if s, ok := val.Interface().(string); ok { storedValue := new(any) if s != "" { - _ = json.Unmarshal([]byte(s), storedValue) + cast.UnmarshalJSON([]byte(s), storedValue) } cast.Convert(convertedObject.Interface(), storedValue) field.Set(convertedObject.Elem()) @@ -537,7 +536,7 @@ func fixValue(colName string, colType string, v reflect.Value) reflect.Value { case strings.Contains(colType, "JSON"): if str != "" && (str[0] == '{' || str[0] == '[') { var out any - if err := json.Unmarshal([]byte(str), &out); err == nil { + if err := cast.UnmarshalJSON([]byte(str), &out); err == nil { return reflect.ValueOf(out) } } diff --git a/SchemaSync_test.go b/SchemaSync_test.go index 5b3d82d..0c38b96 100644 --- a/SchemaSync_test.go +++ b/SchemaSync_test.go @@ -1,17 +1,17 @@ package db_test import ( - "os" "testing" "apigo.cc/go/db" + "apigo.cc/go/file" _ "modernc.org/sqlite" ) func TestSchemaSync(t *testing.T) { dbPath := "test_schema.db" dbInst := db.GetDB("sqlite://"+dbPath, nil) - defer os.Remove(dbPath) + defer file.Remove(dbPath) defer dbInst.Exec("DROP TABLE IF EXISTS test_table") defer dbInst.Exec("DROP TABLE IF EXISTS test_table_deleted") @@ -40,7 +40,7 @@ test_table SD // Test table with shadow delete func TestAutoDetectShadow(t *testing.T) { dbPath := "auto_detect.db" dbInst := db.GetDB("sqlite://"+dbPath, nil) - defer os.Remove(dbPath) + defer file.Remove(dbPath) defer dbInst.Exec("DROP TABLE IF EXISTS test_auto") defer dbInst.Exec("DROP TABLE IF EXISTS test_auto_deleted") diff --git a/TEST.md b/TEST.md index d378e34..be8a99b 100644 --- a/TEST.md +++ b/TEST.md @@ -2,8 +2,8 @@ ## 📊 概览 - **模块**: `apigo.cc/go/db` -- **总测试用例**: 7 -- **通过**: 7 +- **总测试用例**: 13 +- **通过**: 13 - **失败**: 0 - **编译状态**: 成功 (Success) - **测试日期**: 2026-05-13 @@ -11,20 +11,24 @@ ## ✅ 详细详情 | 测试用例 | 状态 | 耗时 | 备注 | | :--- | :--- | :--- | :--- | +| `TestTableProbing` | 通过 | 0.00s | 验证表结构探测 | | `TestMakeInsertSql` | 通过 | 0.00s | 验证 Struct 模型的 SQL 生成逻辑 | | `TestBaseSelect` | 通过 | 0.00s | 验证结果绑定 (Struct, Map, 基础类型) | -| `TestInsertReplaceUpdateDelete` | 通过 | 0.01s | 验证 SQLite 下s CRUD 基本操作 | +| `TestInsertReplaceUpdateDelete` | 通过 | 0.01s | 验证 SQLite 下的 CRUD 基本操作 | | `TestTransaction` | 通过 | 0.03s | 验证事务隔离、回滚与提交 | -| `TestAutonomousFTS` | 通过 | 0.01s | 验证多种引用风格下的 FTS 重定向 | -| `TestComplexIdentifierFTS` | 通过 | 0.01s | 验证带横杠和表前缀的复杂标识符 FTS 重定向 | +| `TestAutonomousFTS` | 通过 | 0.01s | 验证全文搜索功能 | | `TestSchemaSync` | 通过 | 0.01s | 验证 DSL 同步、影子删除、版本号乐观锁及泛型 API | +| `TestAutoDetectShadow` | 通过 | 0.00s | 验证影子表自动检测 | +| `TestSmartDelete` | 通过 | 0.01s | 验证智能删除 (物理/影子) | +| `TestGenericQuery` | 通过 | 0.00s | 验证泛型查询映射 | | `TestAutoRandomID` | 通过 | 0.01s | 验证 char(N) 主键的自动 ID 填充 | +| `TestVersionControl` | 通过 | 0.00s | 验证版本控制递增 | ## 🚀 性能基准 (Benchmarks) | 基准测试 | 迭代次数 | 耗时 | 内存分配 | 备注 | | :--- | :--- | :--- | :--- | :--- | -| `BenchmarkForPool` | 103951 | 11821 ns/op | 1356 B/op (37 allocs) | 增加了复杂标识符解析开销 | -| `BenchmarkForPoolParallel` | 84481 | 13904 ns/op | 1681 B/op (39 allocs) | 验证高并发下的查询稳定性 | +| `BenchmarkForPool` | 106807 | 12230 ns/op | - | 验证 SQLite 下的查询绑定性能 (v1.0.11) | +| `BenchmarkForPoolParallel` | 86833 | 15723 ns/op | - | 验证高并发下的查询稳定性 (v1.0.11) | ## 🛠 环境 - **OS**: darwin (macOS) diff --git a/delete_test.go b/delete_test.go index b5f976c..1fccb6f 100644 --- a/delete_test.go +++ b/delete_test.go @@ -1,10 +1,10 @@ package db_test import ( - "os" "testing" "apigo.cc/go/db" + "apigo.cc/go/file" "apigo.cc/go/log" _ "modernc.org/sqlite" ) @@ -14,7 +14,7 @@ func TestSmartDelete(t *testing.T) { dbPath := "./test_smart_delete.db" dbName := "test_delete" - os.Remove(dbPath) + file.Remove(dbPath) db.SetConfigForTest(dbName, &db.Config{ Type: "sqlite", @@ -27,7 +27,7 @@ func TestSmartDelete(t *testing.T) { } defer func() { dbInst.Destroy() - os.Remove(dbPath) + file.Remove(dbPath) }() // Create table and shadow table diff --git a/generic_test.go b/generic_test.go index 39bfd2d..f1dd3b9 100644 --- a/generic_test.go +++ b/generic_test.go @@ -1,10 +1,10 @@ package db_test import ( - "os" "testing" "apigo.cc/go/cast" "apigo.cc/go/db" + "apigo.cc/go/file" "apigo.cc/go/log" _ "modernc.org/sqlite" ) @@ -12,7 +12,7 @@ import ( func TestGenericQuery(t *testing.T) { db.ResetAllForTest() dbPath := "./test_generic.db" - os.Remove(dbPath) + file.Remove(dbPath) db.SetConfigForTest("test_generic", &db.Config{Type: "sqlite", Host: dbPath}) dbInst := db.GetDB("test_generic", log.DefaultLogger) @@ -21,7 +21,7 @@ func TestGenericQuery(t *testing.T) { } defer func() { dbInst.Destroy() - os.Remove(dbPath) + file.Remove(dbPath) }() r := dbInst.Query("SELECT 1 as num, 'hello' as str") diff --git a/id_test.go b/id_test.go index 58a875d..d96409e 100644 --- a/id_test.go +++ b/id_test.go @@ -5,13 +5,14 @@ import ( "testing" "apigo.cc/go/db" + "apigo.cc/go/file" _ "modernc.org/sqlite" ) func TestAutoRandomID(t *testing.T) { dbPath := "id_test.db" dbset := "sqlite://" + dbPath - defer os.Remove(dbPath) + defer file.Remove(dbPath) dbInst := db.GetDB(dbset, nil) // Create table with char(12) primary key diff --git a/probing_test.go b/probing_test.go index b33f730..57dcb7b 100644 --- a/probing_test.go +++ b/probing_test.go @@ -1,16 +1,16 @@ package db import ( - "os" "testing" + "apigo.cc/go/file" _ "modernc.org/sqlite" ) func TestTableProbing(t *testing.T) { ResetAllForTest() dbPath := "./test_probing.db" - os.Remove(dbPath) + file.Remove(dbPath) SetConfigForTest("test_probing", &Config{Type: "sqlite", Host: dbPath}) dbInst := GetDB("test_probing", nil) if dbInst == nil { @@ -18,7 +18,7 @@ func TestTableProbing(t *testing.T) { } defer func() { dbInst.Destroy() - os.Remove(dbPath) + file.Remove(dbPath) }() diff --git a/version_test.go b/version_test.go index fde39af..911d31d 100644 --- a/version_test.go +++ b/version_test.go @@ -1,11 +1,11 @@ package db_test import ( - "os" "testing" "time" "apigo.cc/go/db" + "apigo.cc/go/file" "apigo.cc/go/log" _ "modernc.org/sqlite" ) @@ -13,7 +13,7 @@ import ( func TestVersionControl(t *testing.T) { db.ResetAllForTest() dbPath := "./test_version.db" - os.Remove(dbPath) + file.Remove(dbPath) db.SetConfigForTest("test_version", &db.Config{Type: "sqlite", Host: dbPath}) dbInst := db.GetDB("test_version", log.DefaultLogger) if dbInst == nil { @@ -21,7 +21,7 @@ func TestVersionControl(t *testing.T) { } defer func() { dbInst.Destroy() - os.Remove(dbPath) + file.Remove(dbPath) }()