migrate from github

This commit is contained in:
2026-07-15 22:42:31 +08:00
commit 3ad559f05e
262 changed files with 21637 additions and 0 deletions
@@ -0,0 +1,149 @@
package document_repo
import (
"context"
"errors"
"github.com/XingfenD/yoresee_doc/internal/model"
"github.com/XingfenD/yoresee_doc/pkg/key"
"gorm.io/gorm"
)
type DocumentGetSubtreeOperation struct {
repo *DocumentRepository
rootParentID int64
knowledgeID *int64
depth *int
directoryOnly bool
tx *gorm.DB
}
func (r *DocumentRepository) GetSubtree(rootParentID int64) *DocumentGetSubtreeOperation {
return &DocumentGetSubtreeOperation{
repo: r,
rootParentID: rootParentID,
}
}
func (op *DocumentGetSubtreeOperation) WithTx(tx *gorm.DB) *DocumentGetSubtreeOperation {
op.tx = tx
return op
}
func (op *DocumentGetSubtreeOperation) WithKnowledgeID(knowledgeID *int64) *DocumentGetSubtreeOperation {
op.knowledgeID = knowledgeID
return op
}
func (op *DocumentGetSubtreeOperation) WithDepth(depth *int) *DocumentGetSubtreeOperation {
op.depth = depth
return op
}
func (op *DocumentGetSubtreeOperation) WithDirectoryOnly(with bool) *DocumentGetSubtreeOperation {
op.directoryOnly = with
return op
}
func (op *DocumentGetSubtreeOperation) Exec(ctx context.Context) ([]*model.Document, error) {
db := op.repo.db
if op.tx != nil {
db = op.tx
}
var documents []*model.Document
if op.depth != nil && *op.depth == 0 {
return documents, nil
}
type pathDepth struct {
Path string
Depth int
}
var root pathDepth
err := db.Model(&model.Document{}).
Select("path, depth").
Where("id = ?", op.rootParentID).
Take(&root).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return documents, nil
}
return nil, err
}
// in-transaction query should bypass cache to avoid stale reads
if op.tx != nil || op.repo.redis == nil {
return op.queryWithRoot(db, root.Path, root.Depth)
}
version, err := op.repo.getSubtreeVersion(ctx, root.Path)
if err == nil {
cacheKey := key.KeyDocSubtree(root.Path, version, op.depth)
if cachedIDs, ok, err := getCachedSubtreeIDs(ctx, cacheKey); err == nil && ok {
return op.repo.fetchDocumentsByIDs(cachedIDs)
}
val, err, _ := subtreeCacheSF.Do(cacheKey, func() (interface{}, error) {
dbDocs, err := op.queryWithRoot(db, root.Path, root.Depth)
if err != nil {
return nil, err
}
ids := make([]int64, 0, len(dbDocs))
for _, doc := range dbDocs {
ids = append(ids, doc.ID)
}
setCachedSubtreeIDs(ctx, cacheKey, ids)
return dbDocs, nil
})
if err != nil {
return nil, err
}
if typed, ok := val.([]*model.Document); ok {
return typed, nil
}
}
return op.queryWithRoot(db, root.Path, root.Depth)
}
func (op *DocumentGetSubtreeOperation) queryWithRoot(db *gorm.DB, rootPath string, rootDepth int) ([]*model.Document, error) {
var documents []*model.Document
query := `
SELECT *
FROM document_metas
WHERE deleted_at IS NULL
AND id <> ?
AND path <@ ?
`
if op.directoryOnly {
query = `
SELECT id, external_id, title, parent_id, type
FROM document_metas
WHERE deleted_at IS NULL
AND id <> ?
AND path <@ ?
`
}
args := []interface{}{op.rootParentID, rootPath}
if op.knowledgeID != nil {
query += " AND knowledge_id = ?"
args = append(args, *op.knowledgeID)
}
if op.depth != nil {
maxDepth := rootDepth + *op.depth
query += " AND depth <= ?"
args = append(args, maxDepth)
}
query += " ORDER BY depth, created_at"
if err := db.Raw(query, args...).Find(&documents).Error; err != nil {
return nil, err
}
return documents, nil
}