79 lines
1.8 KiB
Go
79 lines
1.8 KiB
Go
package document_repo
|
|
|
|
import (
|
|
"github.com/XingfenD/yoresee_doc/internal/model"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type DocumentMoveSubtreeOperation struct {
|
|
repo *DocumentRepository
|
|
docID int64
|
|
newParentID int64
|
|
tx *gorm.DB
|
|
}
|
|
|
|
func (r *DocumentRepository) MoveSubtree(docID, newParentID int64) *DocumentMoveSubtreeOperation {
|
|
return &DocumentMoveSubtreeOperation{
|
|
repo: r,
|
|
docID: docID,
|
|
newParentID: newParentID,
|
|
}
|
|
}
|
|
|
|
func (op *DocumentMoveSubtreeOperation) WithTx(tx *gorm.DB) *DocumentMoveSubtreeOperation {
|
|
op.tx = tx
|
|
return op
|
|
}
|
|
|
|
func (op *DocumentMoveSubtreeOperation) Exec() error {
|
|
if op.tx == nil {
|
|
op.tx = op.repo.db
|
|
}
|
|
|
|
type pathDepth struct {
|
|
Path string
|
|
Depth int
|
|
}
|
|
var old pathDepth
|
|
if err := op.tx.Model(&model.Document{}).
|
|
Select("path, depth").
|
|
Where("id = ? AND deleted_at IS NULL", op.docID).
|
|
Take(&old).Error; err != nil {
|
|
return err
|
|
}
|
|
|
|
var newPath string
|
|
var newDepth int
|
|
if op.newParentID == 0 {
|
|
newDepth = 0
|
|
} else {
|
|
var parent pathDepth
|
|
if err := op.tx.Model(&model.Document{}).
|
|
Select("path, depth").
|
|
Where("id = ? AND deleted_at IS NULL", op.newParentID).
|
|
Take(&parent).Error; err != nil {
|
|
return err
|
|
}
|
|
newPath = parent.Path
|
|
newDepth = parent.Depth + 1
|
|
}
|
|
|
|
depthDelta := newDepth - old.Depth
|
|
|
|
if op.newParentID == 0 {
|
|
return op.tx.Exec(`
|
|
UPDATE document_metas
|
|
SET path = (?::text)::ltree || COALESCE(subpath(path, nlevel(?::ltree)), ''::ltree),
|
|
depth = depth + ?
|
|
WHERE path <@ ?::ltree AND deleted_at IS NULL
|
|
`, op.docID, old.Path, depthDelta, old.Path).Error
|
|
}
|
|
|
|
return op.tx.Exec(`
|
|
UPDATE document_metas
|
|
SET path = (?::ltree) || (?::text)::ltree || COALESCE(subpath(path, nlevel(?::ltree)), ''::ltree),
|
|
depth = depth + ?
|
|
WHERE path <@ ?::ltree AND deleted_at IS NULL
|
|
`, newPath, op.docID, old.Path, depthDelta, old.Path).Error
|
|
}
|