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