|
@@ -42,6 +42,59 @@ import (
|
|
|
"github.com/xrash/smetrics"
|
|
|
)
|
|
|
|
|
|
+func AppendAttributeViewDetachedBlocksWithValues(avID string, blocksValues [][]*av.Value) (err error) {
|
|
|
+ attrView, err := av.ParseAttributeView(avID)
|
|
|
+ if nil != err {
|
|
|
+ logging.LogErrorf("parse attribute view [%s] failed: %s", avID, err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ now := util.CurrentTimeMillis()
|
|
|
+ var blockIDs []string
|
|
|
+ for _, blockValues := range blocksValues {
|
|
|
+ blockID := ast.NewNodeID()
|
|
|
+ blockIDs = append(blockIDs, blockID)
|
|
|
+ for _, v := range blockValues {
|
|
|
+ keyValues, _ := attrView.GetKeyValues(v.KeyID)
|
|
|
+ if nil == keyValues {
|
|
|
+ err = fmt.Errorf("key [%s] not found", v.KeyID)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ v.ID = ast.NewNodeID()
|
|
|
+ v.BlockID = blockID
|
|
|
+ v.Type = keyValues.Key.Type
|
|
|
+ if av.KeyTypeBlock == v.Type {
|
|
|
+ v.Block.ID = blockID
|
|
|
+ v.Block.Created = now
|
|
|
+ v.Block.Updated = now
|
|
|
+ }
|
|
|
+ v.IsDetached = true
|
|
|
+ v.CreatedAt = now
|
|
|
+ v.UpdatedAt = now
|
|
|
+
|
|
|
+ keyValues.Values = append(keyValues.Values, v)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range attrView.Views {
|
|
|
+ switch v.LayoutType {
|
|
|
+ case av.LayoutTypeTable:
|
|
|
+ for _, addingBlockID := range blockIDs {
|
|
|
+ v.Table.RowIDs = append(v.Table.RowIDs, addingBlockID)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if err = av.SaveAttributeView(attrView); nil != err {
|
|
|
+ logging.LogErrorf("save attribute view [%s] failed: %s", avID, err)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ util.PushReloadAttrView(avID)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
func DuplicateDatabaseBlock(avID string) (newAvID, newBlockID string, err error) {
|
|
|
storageAvDir := filepath.Join(util.DataDir, "storage", "av")
|
|
|
oldAvPath := filepath.Join(storageAvDir, avID+".json")
|
|
@@ -574,7 +627,7 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
|
|
|
case av.KeyTypeTemplate:
|
|
|
if 0 < len(kv.Values) {
|
|
|
ial := map[string]string{}
|
|
|
- block := getRowBlockValue(keyValues)
|
|
|
+ block := av.GetKeyBlockValue(keyValues)
|
|
|
if nil != block && !block.IsDetached {
|
|
|
ial = GetBlockAttrsWithoutWaitWriting(block.BlockID)
|
|
|
}
|
|
@@ -915,16 +968,6 @@ func renderAttributeView(attrView *av.AttributeView, viewID, query string, page,
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-func getRowBlockValue(keyValues []*av.KeyValues) (ret *av.Value) {
|
|
|
- for _, kv := range keyValues {
|
|
|
- if av.KeyTypeBlock == kv.Key.Type && 0 < len(kv.Values) {
|
|
|
- ret = kv.Values[0]
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
func (tx *Transaction) doUnbindAttrViewBlock(operation *Operation) (ret *TxErr) {
|
|
|
err := unbindAttributeViewBlock(operation, tx)
|
|
|
if nil != err {
|