添加 Clean 和 Destroy 功能

主要改动:
- Engine: 添加 Clean() 和 Destroy() 方法
- Table: 添加 Clean() 和 Destroy() 方法(不持有 Database 引用)
- Database: 添加 Clean()、CleanTable()、DestroyTable()、Destroy() 方法
- 自动 flush: 添加长时间无写入自动 flush 策略(默认 30 秒)
- WebUI 优化: 优化分页查询性能

新增功能:
- Clean(): 清除数据但保留结构,Engine/Table/Database 仍可用
- Destroy(): 销毁并删除所有文件,对象不可用
- CleanTable(name): 清除指定表的数据
- DestroyTable(name): 销毁指定表并从 Database 中删除
- 自动 flush 监控: 后台定期检查,空闲时自动持久化

代码优化:
- Engine.Close(): 支持 Destroy 后调用,不会 panic
- 二级索引持久化: 在 flush 时自动持久化索引
- WebUI 分页: 预构建字段类型 map,减少 Schema 查询
- 职责分离: Table 不再持有 Database 引用

测试覆盖:
- engine_clean_test.go: Engine Clean/Destroy 测试
- table_clean_test.go: Table Clean/Destroy 测试
- database_clean_test.go: Database Clean/Destroy 测试
- database_table_ops_test.go: Database CleanTable/DestroyTable 测试
This commit is contained in:
2025-10-09 01:03:22 +08:00
parent 23843493b8
commit 9175b98202
8 changed files with 1413 additions and 123 deletions

View File

@@ -380,45 +380,40 @@ func (ui *WebUI) handleTableData(w http.ResponseWriter, r *http.Request, tableNa
}
defer queryRows.Close()
// 收集所有 rows 到内存中用于分页
allRows := make([]*srdb.SSTableRow, 0)
for queryRows.Next() {
row := queryRows.Row()
sstRow := &srdb.SSTableRow{
Seq: row.Data()["_seq"].(int64),
Time: row.Data()["_time"].(int64),
Data: make(map[string]any),
}
// 复制其他字段
for k, v := range row.Data() {
if k != "_seq" && k != "_time" {
sstRow.Data[k] = v
}
}
allRows = append(allRows, sstRow)
}
// 计算分页
totalRows := int64(len(allRows))
// 计算分页范围
offset := (page - 1) * pageSize
end := min(offset+pageSize, int(totalRows))
currentIndex := 0
// 获取当前页数据
rows := make([]*srdb.SSTableRow, 0, pageSize)
if offset < int(totalRows) {
rows = allRows[offset:end]
}
// 构造响应,对 string 字段进行剪裁
// 直接在遍历时进行分页和字段处理
const maxStringLength = 100 // 最大字符串长度
data := make([]map[string]any, 0, len(rows))
for _, row := range rows {
rowData := make(map[string]any)
rowData["_seq"] = row.Seq
rowData["_time"] = row.Time
data := make([]map[string]any, 0, pageSize)
totalRows := int64(0)
for queryRows.Next() {
totalRows++
// 跳过不在当前页的数据
if currentIndex < offset {
currentIndex++
continue
}
// 已经收集够当前页的数据
if len(data) >= pageSize {
continue
}
row := queryRows.Row()
rowData := make(map[string]any)
rowData["_seq"] = row.Data()["_seq"]
rowData["_time"] = row.Data()["_time"]
// 遍历所有字段并进行字符串截断
for k, v := range row.Data() {
if k == "_seq" || k == "_time" {
continue
}
// 遍历所有字段
for k, v := range row.Data {
// 检查字段类型
field, err := tableSchema.GetField(k)
if err == nil && field.Type == srdb.FieldTypeString {
@@ -434,7 +429,9 @@ func (ui *WebUI) handleTableData(w http.ResponseWriter, r *http.Request, tableNa
}
rowData[k] = v
}
data = append(data, rowData)
currentIndex++
}
response := map[string]any{