refactor: standardize Hook signatures to use *Document
This commit is contained in:
parent
cfabbab466
commit
158907f36a
@ -1,5 +1,10 @@
|
||||
# CHANGELOG
|
||||
|
||||
## v1.0.9 (2026-05-16)
|
||||
- **Hook 系统重构**:
|
||||
- **参数标准化**: `Hooks` 结构体中的所有回调函数(`OnUpdatedDoc`, `OnRemovedDoc`, `OnUpdatedToC`, `OnRemovedToC`)现在统一接收 `*Document` 对象作为参数,极大地方便了外部处理逻辑直接获取文档元数据与路径。
|
||||
- **触发逻辑对齐**: 确保在文档删除、重命名及 ToC 更新时,钩子都能正确获取到相关的文档上下文。
|
||||
|
||||
## [1.0.0] - 2026-05-15
|
||||
### Added
|
||||
- 从 `knowbase` 项目剥离生成的独立 `docDB` 项目。
|
||||
|
||||
14
README.md
14
README.md
@ -1,4 +1,4 @@
|
||||
# @go/docDB
|
||||
# @go/docDB v1.0.9
|
||||
|
||||
`docDB` 是一个独立的高级文档存储引擎,基于 `@go/tableDB` 构建,提供全自动版本管理、历史存证、流式大文件处理及精细化生命周期钩子。
|
||||
|
||||
@ -38,27 +38,27 @@ db := engine.Auth("user_123")
|
||||
|
||||
- **`SetDoc(doc *Document) error`**:保存文档,提升版本。触发 `OnUpdatedDoc` 和 `OnUpdatedToC`。
|
||||
- **`SetMeta(path string, meta map[string]any) error`**:更新元数据,**不提升版本**。若包含 `textContent` 且为 Markdown,会自动触发 `OnRemovedToC` 和 `OnUpdatedToC`。
|
||||
- **`Move(oldPath, newPath string) error`**:重命名。触发 `OnRemovedDoc(oldPath)` -> `OnUpdatedDoc(newPath)`。
|
||||
- **`Move(oldPath, newPath string) error`**:重命名。触发 `OnRemovedDoc(oldDoc)` -> `OnUpdatedDoc(newDoc)`。
|
||||
- **`Get(path string) (*Document, error)`**:获取最新版。
|
||||
- **`GetByVersion(path string, version uint64) (*Document, error)`**:获取历史版(含已删除)。
|
||||
- **`Remove(path string) error`**:删除文档。触发 `OnRemovedDoc`。
|
||||
- **`Remove(path string) error`**:删除文档。触发 `OnRemovedDoc(doc)`。
|
||||
|
||||
### 3. 生命周期钩子 (Hooks)
|
||||
|
||||
```go
|
||||
// 文档级事件
|
||||
// 所有 Hook 统一返回 *Document 对象,方便外部获取 Path, ToC, Metadata 等完整上下文
|
||||
engine.Hooks.OnUpdatedDoc = func(doc *docDB.Document) {
|
||||
// 文档创建或内容更新时触发 (SetDoc 或 Move 触发)
|
||||
}
|
||||
engine.Hooks.OnRemovedDoc = func(path string) {
|
||||
engine.Hooks.OnRemovedDoc = func(doc *docDB.Document) {
|
||||
// 文档被物理删除或 Move 移除旧路径时触发
|
||||
}
|
||||
|
||||
// 目录(ToC)级事件
|
||||
engine.Hooks.OnUpdatedToC = func(path string, toc []docDB.ToCNode) {
|
||||
engine.Hooks.OnUpdatedToC = func(doc *docDB.Document) {
|
||||
// 目录生成或变更时触发
|
||||
}
|
||||
engine.Hooks.OnRemovedToC = func(path string) {
|
||||
engine.Hooks.OnRemovedToC = func(doc *docDB.Document) {
|
||||
// 目录失效时触发
|
||||
}
|
||||
```
|
||||
|
||||
60
doc.go
60
doc.go
@ -16,9 +16,9 @@ import (
|
||||
// Hooks 生命周期钩子
|
||||
type Hooks struct {
|
||||
OnUpdatedDoc func(doc *Document)
|
||||
OnRemovedDoc func(path string)
|
||||
OnUpdatedToC func(path string, toc []ToCNode)
|
||||
OnRemovedToC func(path string)
|
||||
OnRemovedDoc func(doc *Document)
|
||||
OnUpdatedToC func(doc *Document)
|
||||
OnRemovedToC func(doc *Document)
|
||||
}
|
||||
|
||||
// DocDBUnauthorized 实例
|
||||
@ -135,7 +135,7 @@ func (a *DocDB) SetDoc(docObj *Document) error {
|
||||
var internalID string
|
||||
|
||||
if existing != nil {
|
||||
a.triggerRemovedToC(docObj.Path)
|
||||
a.triggerRemovedToC(a.toDoc(existing))
|
||||
a.archive(existing)
|
||||
internalID = cast.String(existing["id"])
|
||||
docObj.Version = cast.Uint64(existing["version"]) + 1
|
||||
@ -168,7 +168,7 @@ func (a *DocDB) SetDoc(docObj *Document) error {
|
||||
if err == nil {
|
||||
a.triggerUpdatedDoc(docObj)
|
||||
if docObj.ToC != nil {
|
||||
a.triggerUpdatedToC(docObj.Path, docObj.ToC)
|
||||
a.triggerUpdatedToC(docObj)
|
||||
}
|
||||
}
|
||||
return err
|
||||
@ -185,10 +185,9 @@ func (a *DocDB) SetMeta(path string, meta map[string]any) error {
|
||||
if text, ok := meta["textContent"].(string); ok {
|
||||
docType := cast.String(existing["type"])
|
||||
if docType == "markdown" || strings.HasSuffix(strings.ToLower(path), ".md") {
|
||||
a.triggerRemovedToC(path)
|
||||
a.triggerRemovedToC(a.toDoc(existing))
|
||||
newToC := ExtractToC(text)
|
||||
meta["toc"] = newToC
|
||||
a.triggerUpdatedToC(path, newToC)
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,7 +195,11 @@ func (a *DocDB) SetMeta(path string, meta map[string]any) error {
|
||||
existing[k] = v
|
||||
}
|
||||
|
||||
return a.table.Set(existing)
|
||||
err = a.table.Set(existing)
|
||||
if err == nil && meta["toc"] != nil {
|
||||
a.triggerUpdatedToC(a.toDoc(existing))
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// Move 修改路径 (重命名)
|
||||
@ -207,9 +210,10 @@ func (a *DocDB) Move(oldPath, newPath string) error {
|
||||
}
|
||||
|
||||
// 触发删除旧路径事件
|
||||
a.triggerRemovedDoc(oldPath)
|
||||
oldDoc := a.toDoc(existing)
|
||||
a.triggerRemovedDoc(oldDoc)
|
||||
if existing["toc"] != nil {
|
||||
a.triggerRemovedToC(oldPath)
|
||||
a.triggerRemovedToC(oldDoc)
|
||||
}
|
||||
|
||||
existing["path"] = newPath
|
||||
@ -219,7 +223,7 @@ func (a *DocDB) Move(oldPath, newPath string) error {
|
||||
if newDoc != nil {
|
||||
a.triggerUpdatedDoc(newDoc)
|
||||
if newDoc.ToC != nil {
|
||||
a.triggerUpdatedToC(newPath, newDoc.ToC)
|
||||
a.triggerUpdatedToC(newDoc)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -234,6 +238,15 @@ func (a *DocDB) getRaw(path string) (map[string]any, error) {
|
||||
return res[0], nil
|
||||
}
|
||||
|
||||
func (a *DocDB) toDoc(record map[string]any) *Document {
|
||||
if record == nil {
|
||||
return nil
|
||||
}
|
||||
var doc Document
|
||||
cast.Convert(&doc, record)
|
||||
return &doc
|
||||
}
|
||||
|
||||
func (a *DocDB) archive(existing map[string]any) {
|
||||
histRecord := make(map[string]any)
|
||||
for k, v := range existing {
|
||||
@ -284,9 +297,7 @@ func (a *DocDB) Get(path string) (*Document, error) {
|
||||
if err != nil || res == nil {
|
||||
return nil, err
|
||||
}
|
||||
var doc Document
|
||||
cast.Convert(&doc, res)
|
||||
return &doc, nil
|
||||
return a.toDoc(res), nil
|
||||
}
|
||||
|
||||
// GetByVersion 按版本获取文档
|
||||
@ -316,9 +327,7 @@ func (a *DocDB) GetByVersion(path string, version uint64) (*Document, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var doc Document
|
||||
cast.Convert(&doc, histRes[0])
|
||||
return &doc, nil
|
||||
return a.toDoc(histRes[0]), nil
|
||||
}
|
||||
|
||||
// Remove 删除文档 (自动保存最后一版到历史)
|
||||
@ -328,9 +337,10 @@ func (a *DocDB) Remove(path string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
a.triggerRemovedDoc(path)
|
||||
doc := a.toDoc(existing)
|
||||
a.triggerRemovedDoc(doc)
|
||||
if existing["toc"] != nil {
|
||||
a.triggerRemovedToC(path)
|
||||
a.triggerRemovedToC(doc)
|
||||
}
|
||||
|
||||
a.archive(existing)
|
||||
@ -343,21 +353,21 @@ func (a *DocDB) triggerUpdatedDoc(doc *Document) {
|
||||
}
|
||||
}
|
||||
|
||||
func (a *DocDB) triggerRemovedDoc(path string) {
|
||||
func (a *DocDB) triggerRemovedDoc(doc *Document) {
|
||||
if a.parent.Hooks.OnRemovedDoc != nil {
|
||||
a.parent.Hooks.OnRemovedDoc(path)
|
||||
a.parent.Hooks.OnRemovedDoc(doc)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *DocDB) triggerUpdatedToC(path string, toc []ToCNode) {
|
||||
func (a *DocDB) triggerUpdatedToC(doc *Document) {
|
||||
if a.parent.Hooks.OnUpdatedToC != nil {
|
||||
a.parent.Hooks.OnUpdatedToC(path, toc)
|
||||
a.parent.Hooks.OnUpdatedToC(doc)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *DocDB) triggerRemovedToC(path string) {
|
||||
func (a *DocDB) triggerRemovedToC(doc *Document) {
|
||||
if a.parent.Hooks.OnRemovedToC != nil {
|
||||
a.parent.Hooks.OnRemovedToC(path)
|
||||
a.parent.Hooks.OnRemovedToC(doc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -21,9 +21,9 @@ func TestDocDB(t *testing.T) {
|
||||
|
||||
var updatedCalled, removedDocCalled, updatedToCCalled, removedToCCalled bool
|
||||
docDBInst.Hooks.OnUpdatedDoc = func(doc *Document) { updatedCalled = true }
|
||||
docDBInst.Hooks.OnRemovedDoc = func(path string) { removedDocCalled = true }
|
||||
docDBInst.Hooks.OnUpdatedToC = func(path string, toc []ToCNode) { updatedToCCalled = true }
|
||||
docDBInst.Hooks.OnRemovedToC = func(path string) { removedToCCalled = true }
|
||||
docDBInst.Hooks.OnRemovedDoc = func(doc *Document) { removedDocCalled = true }
|
||||
docDBInst.Hooks.OnUpdatedToC = func(doc *Document) { updatedToCCalled = true }
|
||||
docDBInst.Hooks.OnRemovedToC = func(doc *Document) { removedToCCalled = true }
|
||||
|
||||
// 1. 测试 SetDoc (创建)
|
||||
docPath := "/test/doc1.md"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user