mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 07:00:12 +01:00
♻️ Refactor av data structure
This commit is contained in:
parent
39b28cbc98
commit
1ccdb4c576
2 changed files with 143 additions and 152 deletions
|
|
@ -69,6 +69,19 @@ func RenderAttributeView(avID string) (viewable av.Viewable, attrView *av.Attrib
|
|||
return
|
||||
}
|
||||
|
||||
func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *av.Table, err error) {
|
||||
ret = &av.Table{
|
||||
Spec: attrView.Spec,
|
||||
ID: view.ID,
|
||||
Name: view.Name,
|
||||
Columns: attrView.Columns,
|
||||
Rows: attrView.Rows,
|
||||
Filters: view.Filters,
|
||||
Sorts: view.Sorts,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doSetAttrViewName(operation *Operation) (ret *TxErr) {
|
||||
err := setAttributeViewName(operation)
|
||||
if nil != err {
|
||||
|
|
@ -77,22 +90,6 @@ func (tx *Transaction) doSetAttrViewName(operation *Operation) (ret *TxErr) {
|
|||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doSetAttrViewFilters(operation *Operation) (ret *TxErr) {
|
||||
err := setAttributeViewFilters(operation)
|
||||
if nil != err {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doSetAttrViewSorts(operation *Operation) (ret *TxErr) {
|
||||
err := setAttributeViewSorts(operation)
|
||||
if nil != err {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setAttributeViewName(operation *Operation) (err error) {
|
||||
avID := operation.ID
|
||||
attrView, err := av.ParseAttributeView(avID)
|
||||
|
|
@ -115,6 +112,14 @@ func setAttributeViewName(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doSetAttrViewFilters(operation *Operation) (ret *TxErr) {
|
||||
err := setAttributeViewFilters(operation)
|
||||
if nil != err {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setAttributeViewFilters(operation *Operation) (err error) {
|
||||
avID := operation.ID
|
||||
attrView, err := av.ParseAttributeView(avID)
|
||||
|
|
@ -142,6 +147,14 @@ func setAttributeViewFilters(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doSetAttrViewSorts(operation *Operation) (ret *TxErr) {
|
||||
err := setAttributeViewSorts(operation)
|
||||
if nil != err {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func setAttributeViewSorts(operation *Operation) (err error) {
|
||||
avID := operation.ID
|
||||
attrView, err := av.ParseAttributeView(avID)
|
||||
|
|
@ -169,21 +182,118 @@ func setAttributeViewSorts(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// TODO 下面的方法要重写
|
||||
func (tx *Transaction) doInsertAttrViewBlock(operation *Operation) (ret *TxErr) {
|
||||
firstSrcID := operation.SrcIDs[0]
|
||||
tree, err := tx.loadTree(firstSrcID)
|
||||
if nil != err {
|
||||
logging.LogErrorf("load tree [%s] failed: %s", firstSrcID, err)
|
||||
return &TxErr{code: TxErrCodeBlockNotFound, id: firstSrcID, msg: err.Error()}
|
||||
}
|
||||
|
||||
func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *av.Table, err error) {
|
||||
ret = &av.Table{
|
||||
Spec: attrView.Spec,
|
||||
ID: view.ID,
|
||||
Name: view.Name,
|
||||
Columns: attrView.Columns,
|
||||
Rows: attrView.Rows,
|
||||
Filters: view.Filters,
|
||||
Sorts: view.Sorts,
|
||||
for _, id := range operation.SrcIDs {
|
||||
var avErr error
|
||||
if avErr = addAttributeViewBlock(id, operation, tree, tx); nil != avErr {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: avErr.Error()}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func addAttributeViewBlock(blockID string, operation *Operation, tree *parse.Tree, tx *Transaction) (err error) {
|
||||
node := treenode.GetNodeInTree(tree, blockID)
|
||||
if nil == node {
|
||||
err = ErrBlockNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if ast.NodeAttributeView == node.Type {
|
||||
// 不能将一个属性视图拖拽到另一个属性视图中
|
||||
return
|
||||
}
|
||||
|
||||
block := sql.BuildBlockFromNode(node, tree)
|
||||
if nil == block {
|
||||
err = ErrBlockNotFound
|
||||
return
|
||||
}
|
||||
|
||||
attrView, err := av.ParseAttributeView(operation.AvID)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
// 不允许重复添加相同的块到属性视图中
|
||||
for _, row := range attrView.Rows {
|
||||
blockCell := row.GetBlockCell()
|
||||
if nil == blockCell {
|
||||
continue
|
||||
}
|
||||
|
||||
if blockCell.Value.Block.ID == blockID {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
row := av.NewRow()
|
||||
attrs := parse.IAL2Map(node.KramdownIAL)
|
||||
for _, col := range attrView.Columns {
|
||||
if av.ColumnTypeBlock != col.Type {
|
||||
attrs[NodeAttrNamePrefixAvCol+operation.AvID+"-"+col.ID] = "" // 将列作为属性添加到块中
|
||||
row.Cells = append(row.Cells, av.NewCell(col.Type))
|
||||
} else {
|
||||
row.Cells = append(row.Cells, av.NewCellBlock(blockID, getNodeRefText(node)))
|
||||
}
|
||||
}
|
||||
|
||||
if "" == attrs[NodeAttrNameAVs] {
|
||||
attrs[NodeAttrNameAVs] = operation.AvID
|
||||
} else {
|
||||
avIDs := strings.Split(attrs[NodeAttrNameAVs], ",")
|
||||
avIDs = append(avIDs, operation.AvID)
|
||||
avIDs = gulu.Str.RemoveDuplicatedElem(avIDs)
|
||||
attrs[NodeAttrNameAVs] = strings.Join(avIDs, ",")
|
||||
}
|
||||
|
||||
if err = setNodeAttrsWithTx(tx, node, tree, attrs); nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
if "" == operation.PreviousRowID {
|
||||
attrView.Rows = append([]*av.Row{row}, attrView.Rows...)
|
||||
} else {
|
||||
for i, r := range attrView.Rows {
|
||||
if r.ID == operation.PreviousRowID {
|
||||
attrView.Rows = append(attrView.Rows[:i+1], append([]*av.Row{row}, attrView.Rows[i+1:]...)...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = av.SaveAttributeView(attrView)
|
||||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doRemoveAttrViewBlock(operation *Operation) (ret *TxErr) {
|
||||
var avs []*av.AttributeView
|
||||
avID := operation.ParentID
|
||||
for _, id := range operation.SrcIDs {
|
||||
var av *av.AttributeView
|
||||
var avErr error
|
||||
if av, avErr = removeAttributeViewBlock(id, avID); nil != avErr {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: avID}
|
||||
}
|
||||
|
||||
if nil == av {
|
||||
continue
|
||||
}
|
||||
|
||||
avs = append(avs, av)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// TODO 下面的方法要重写
|
||||
|
||||
func (tx *Transaction) doUpdateAttrViewCell(operation *Operation) (ret *TxErr) {
|
||||
avID := operation.ParentID
|
||||
view, err := av.ParseAttributeView(avID)
|
||||
|
|
@ -249,52 +359,6 @@ func (tx *Transaction) doUpdateAttrViewCell(operation *Operation) (ret *TxErr) {
|
|||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doInsertAttrViewBlock(operation *Operation) (ret *TxErr) {
|
||||
firstSrcID := operation.SrcIDs[0]
|
||||
tree, err := tx.loadTree(firstSrcID)
|
||||
if nil != err {
|
||||
logging.LogErrorf("load tree [%s] failed: %s", firstSrcID, err)
|
||||
return &TxErr{code: TxErrCodeBlockNotFound, id: firstSrcID, msg: err.Error()}
|
||||
}
|
||||
|
||||
avID := operation.ParentID
|
||||
var avs []*av.AttributeView
|
||||
previousID := operation.PreviousID
|
||||
for _, id := range operation.SrcIDs {
|
||||
var av *av.AttributeView
|
||||
var avErr error
|
||||
if av, avErr = addAttributeViewBlock(id, previousID, avID, tree, tx); nil != avErr {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: avID, msg: avErr.Error()}
|
||||
}
|
||||
|
||||
if nil == av {
|
||||
continue
|
||||
}
|
||||
|
||||
avs = append(avs, av)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doRemoveAttrViewBlock(operation *Operation) (ret *TxErr) {
|
||||
var avs []*av.AttributeView
|
||||
avID := operation.ParentID
|
||||
for _, id := range operation.SrcIDs {
|
||||
var av *av.AttributeView
|
||||
var avErr error
|
||||
if av, avErr = removeAttributeViewBlock(id, avID); nil != avErr {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: avID}
|
||||
}
|
||||
|
||||
if nil == av {
|
||||
continue
|
||||
}
|
||||
|
||||
avs = append(avs, av)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doUpdateAttrViewColOption(operation *Operation) (ret *TxErr) {
|
||||
err := updateAttributeViewColumnOption(operation)
|
||||
if nil != err {
|
||||
|
|
@ -803,80 +867,6 @@ func removeAttributeViewBlock(blockID, avID string) (ret *av.AttributeView, err
|
|||
return
|
||||
}
|
||||
|
||||
func addAttributeViewBlock(blockID, previousRowID, avID string, tree *parse.Tree, tx *Transaction) (ret *av.AttributeView, err error) {
|
||||
node := treenode.GetNodeInTree(tree, blockID)
|
||||
if nil == node {
|
||||
err = ErrBlockNotFound
|
||||
return
|
||||
}
|
||||
|
||||
if ast.NodeAttributeView == node.Type {
|
||||
// 不能将一个属性视图拖拽到另一个属性视图中
|
||||
return
|
||||
}
|
||||
|
||||
block := sql.BuildBlockFromNode(node, tree)
|
||||
if nil == block {
|
||||
err = ErrBlockNotFound
|
||||
return
|
||||
}
|
||||
|
||||
ret, err = av.ParseAttributeView(avID)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
// 不允许重复添加相同的块到属性视图中
|
||||
for _, row := range ret.Rows {
|
||||
blockCell := row.GetBlockCell()
|
||||
if nil == blockCell {
|
||||
continue
|
||||
}
|
||||
|
||||
if blockCell.Value.Block.ID == blockID {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
row := av.NewRow()
|
||||
attrs := parse.IAL2Map(node.KramdownIAL)
|
||||
for _, col := range ret.Columns {
|
||||
if av.ColumnTypeBlock != col.Type {
|
||||
attrs[NodeAttrNamePrefixAvCol+avID+"-"+col.ID] = "" // 将列作为属性添加到块中
|
||||
row.Cells = append(row.Cells, av.NewCell(col.Type))
|
||||
} else {
|
||||
row.Cells = append(row.Cells, av.NewCellBlock(blockID, getNodeRefText(node)))
|
||||
}
|
||||
}
|
||||
|
||||
if "" == attrs[NodeAttrNameAVs] {
|
||||
attrs[NodeAttrNameAVs] = avID
|
||||
} else {
|
||||
avIDs := strings.Split(attrs[NodeAttrNameAVs], ",")
|
||||
avIDs = append(avIDs, avID)
|
||||
avIDs = gulu.Str.RemoveDuplicatedElem(avIDs)
|
||||
attrs[NodeAttrNameAVs] = strings.Join(avIDs, ",")
|
||||
}
|
||||
|
||||
if err = setNodeAttrsWithTx(tx, node, tree, attrs); nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
if "" == previousRowID {
|
||||
ret.Rows = append([]*av.Row{row}, ret.Rows...)
|
||||
} else {
|
||||
for i, r := range ret.Rows {
|
||||
if r.ID == previousRowID {
|
||||
ret.Rows = append(ret.Rows[:i+1], append([]*av.Row{row}, ret.Rows[i+1:]...)...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = av.SaveAttributeView(ret)
|
||||
return
|
||||
}
|
||||
|
||||
const (
|
||||
NodeAttrNameAVs = "custom-avs"
|
||||
NodeAttrNamePrefixAvCol = "custom-av-col-"
|
||||
|
|
|
|||
|
|
@ -1053,12 +1053,13 @@ type Operation struct {
|
|||
|
||||
DeckID string `json:"deckID"` // 用于添加/删除闪卡
|
||||
|
||||
AvID string `json:"avID"` // 属性视图 ID
|
||||
ViewID string `json:"viewID"` // 属性视图的视图 ID
|
||||
SrcIDs []string `json:"srcIDs"` // 用于将块拖拽到属性视图中
|
||||
Name string `json:"name"` // 用于属性视图列名
|
||||
Typ string `json:"type"` // 用于属性视图列类型
|
||||
RowID string `json:"rowID"` // 用于属性视图行 ID
|
||||
AvID string `json:"avID"` // 属性视图 ID
|
||||
ViewID string `json:"viewID"` // 属性视图的视图 ID
|
||||
SrcIDs []string `json:"srcIDs"` // 用于将块拖拽到属性视图中
|
||||
Name string `json:"name"` // 属性视图列名
|
||||
Typ string `json:"type"` // 属性视图列类型
|
||||
PreviousRowID string `json:"previousRowID"` // 属性视图前一行 ID
|
||||
RowID string `json:"rowID"` // 属性视图行 ID
|
||||
|
||||
discard bool // 用于标识是否在事务合并中丢弃
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue