Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Vanessa 2023-12-31 11:13:16 +08:00
commit fc71c7abc2
9 changed files with 262 additions and 91 deletions

View file

@ -2,7 +2,7 @@ productName: "SiYuan"
appId: "org.b3log.siyuan"
asar: false
compression: "normal"
copyright: "© 2023 Yunnan Liandi Technology Co., Ltd."
copyright: "© 2024 Yunnan Liandi Technology Co., Ltd."
artifactName: "siyuan-${version}-${os}-arm64.${ext}"
extraMetadata:
main: "electron/main.js"

View file

@ -2,7 +2,7 @@ productName: "SiYuan"
appId: "org.b3log.siyuan"
asar: false
compression: "normal"
copyright: "© 2023 Yunnan Liandi Technology Co., Ltd."
copyright: "© 2024 Yunnan Liandi Technology Co., Ltd."
artifactName: "siyuan-${version}-${os}.${ext}"
extraMetadata:
main: "electron/main.js"

View file

@ -2,7 +2,7 @@ productName: "SiYuan"
appId: "org.b3log.siyuan"
asar: false
compression: "normal"
copyright: "© 2023 Yunnan Liandi Technology Co., Ltd."
copyright: "© 2024 Yunnan Liandi Technology Co., Ltd."
artifactName: "siyuan-${version}-${os}.${ext}"
extraMetadata:
main: "electron/main.js"

View file

@ -2,7 +2,7 @@ productName: "SiYuan"
appId: "org.b3log.siyuan"
asar: false
compression: "normal"
copyright: "© 2023 Yunnan Liandi Technology Co., Ltd."
copyright: "© 2024 Yunnan Liandi Technology Co., Ltd."
artifactName: "siyuan-${version}-${os}.${ext}"
extraMetadata:
main: "electron/main.js"

130
kernel/av/relation.go Normal file
View file

@ -0,0 +1,130 @@
package av
import (
"os"
"path/filepath"
"sync"
"github.com/88250/gulu"
"github.com/siyuan-note/filelock"
"github.com/siyuan-note/logging"
"github.com/siyuan-note/siyuan/kernel/util"
"github.com/vmihailenco/msgpack/v5"
)
var (
attributeViewRelationsLock = sync.Mutex{}
)
func GetSrcAvIDs(destAvID string) []string {
attributeViewRelationsLock.Lock()
defer attributeViewRelationsLock.Unlock()
relations := filepath.Join(util.DataDir, "storage", "av", "relations.msgpack")
if !filelock.IsExist(relations) {
return nil
}
data, err := filelock.ReadFile(relations)
if nil != err {
logging.LogErrorf("read attribute view relations failed: %s", err)
return nil
}
avRels := map[string][]string{}
if err = msgpack.Unmarshal(data, &avRels); nil != err {
logging.LogErrorf("unmarshal attribute view relations failed: %s", err)
return nil
}
srcAvIDs := avRels[destAvID]
if nil == srcAvIDs {
return nil
}
return srcAvIDs
}
func RemoveAvRel(srcAvID, destAvID string) {
attributeViewRelationsLock.Lock()
defer attributeViewRelationsLock.Unlock()
relations := filepath.Join(util.DataDir, "storage", "av", "relations.msgpack")
if !filelock.IsExist(relations) {
return
}
data, err := filelock.ReadFile(relations)
if nil != err {
logging.LogErrorf("read attribute view relations failed: %s", err)
return
}
avRels := map[string][]string{}
if err = msgpack.Unmarshal(data, &avRels); nil != err {
logging.LogErrorf("unmarshal attribute view relations failed: %s", err)
return
}
srcAvIDs := avRels[destAvID]
if nil == srcAvIDs {
return
}
var newAvIDs []string
for _, v := range srcAvIDs {
if v != srcAvID {
newAvIDs = append(newAvIDs, v)
}
}
avRels[destAvID] = newAvIDs
data, err = msgpack.Marshal(avRels)
if nil != err {
logging.LogErrorf("marshal attribute view relations failed: %s", err)
return
}
if err = filelock.WriteFile(relations, data); nil != err {
logging.LogErrorf("write attribute view relations failed: %s", err)
return
}
}
func UpsertAvBackRel(srcAvID, destAvID string) {
attributeViewRelationsLock.Lock()
defer attributeViewRelationsLock.Unlock()
avRelations := map[string][]string{}
relations := filepath.Join(util.DataDir, "storage", "av", "relations.msgpack")
if !filelock.IsExist(relations) {
if err := os.MkdirAll(filepath.Dir(relations), 0755); nil != err {
logging.LogErrorf("create attribute view dir failed: %s", err)
return
}
} else {
data, err := filelock.ReadFile(relations)
if nil != err {
logging.LogErrorf("read attribute view relations failed: %s", err)
return
}
if err = msgpack.Unmarshal(data, &avRelations); nil != err {
logging.LogErrorf("unmarshal attribute view relations failed: %s", err)
return
}
}
srcAvIDs := avRelations[destAvID]
srcAvIDs = append(srcAvIDs, srcAvID)
srcAvIDs = gulu.Str.RemoveDuplicatedElem(srcAvIDs)
avRelations[destAvID] = srcAvIDs
data, err := msgpack.Marshal(avRelations)
if nil != err {
logging.LogErrorf("marshal attribute view relations failed: %s", err)
return
}
if err = filelock.WriteFile(relations, data); nil != err {
logging.LogErrorf("write attribute view relations failed: %s", err)
return
}
}

View file

@ -656,16 +656,11 @@ func getBazaarIndex() map[string]*bazaarPackage {
const defaultMinAppVersion = "2.9.0"
func disallowDisplayBazaarPackage(pkg *Package) bool {
if "" == pkg.MinAppVersion { // 目前暂时放过所有不带 minAppVersion 的集市包,后续版本会使用 defaultMinAppVersion
if "" == pkg.MinAppVersion { // TODO: 目前暂时放过所有不带 minAppVersion 的集市包,后续版本会使用 defaultMinAppVersion
return false
}
if 0 < semver.Compare("v"+pkg.MinAppVersion, "v"+util.Ver) {
return true
}
if 0 < len(pkg.Backends) {
}
return false
}

View file

@ -252,7 +252,7 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
destVal.Number.FormatNumber()
}
kv.Values[0].Rollup.Contents = append(kv.Values[0].Rollup.Contents, destAv.GetValue(kv.Key.Rollup.KeyID, bID).String())
kv.Values[0].Rollup.Contents = append(kv.Values[0].Rollup.Contents, destVal.String())
}
kv.Values[0].Rollup.RenderContents(kv.Key.Rollup.Calc)
@ -693,6 +693,14 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a
}
rows[val.BlockID] = values
}
// 数据订正,补全关联
if av.KeyTypeRelation == keyValues.Key.Type && nil != keyValues.Key.Relation {
av.UpsertAvBackRel(attrView.ID, keyValues.Key.Relation.AvID)
if keyValues.Key.Relation.IsTwoWay {
av.UpsertAvBackRel(keyValues.Key.Relation.AvID, attrView.ID)
}
}
}
// 过滤掉不存在的行
@ -980,27 +988,31 @@ func updateAttributeViewColRelation(operation *Operation) (err error) {
srcRel := keyValues.Key.Relation
// 已经设置过双向关联的话需要先断开双向关联
if nil != srcRel && srcRel.IsTwoWay {
oldDestAv, _ := av.ParseAttributeView(srcRel.AvID)
if nil != oldDestAv {
isOldSameAv := oldDestAv.ID == destAv.ID
if isOldSameAv {
oldDestAv = destAv
}
if nil != srcRel {
if srcRel.IsTwoWay {
oldDestAv, _ := av.ParseAttributeView(srcRel.AvID)
if nil != oldDestAv {
isOldSameAv := oldDestAv.ID == destAv.ID
if isOldSameAv {
oldDestAv = destAv
}
oldDestKey, _ := oldDestAv.GetKey(srcRel.BackKeyID)
if nil != oldDestKey && nil != oldDestKey.Relation && oldDestKey.Relation.AvID == srcAv.ID && oldDestKey.Relation.IsTwoWay {
oldDestKey.Relation.IsTwoWay = false
oldDestKey.Relation.BackKeyID = ""
}
oldDestKey, _ := oldDestAv.GetKey(srcRel.BackKeyID)
if nil != oldDestKey && nil != oldDestKey.Relation && oldDestKey.Relation.AvID == srcAv.ID && oldDestKey.Relation.IsTwoWay {
oldDestKey.Relation.IsTwoWay = false
oldDestKey.Relation.BackKeyID = ""
}
if !isOldSameAv {
err = av.SaveAttributeView(oldDestAv)
if nil != err {
return
if !isOldSameAv {
err = av.SaveAttributeView(oldDestAv)
if nil != err {
return
}
}
}
}
av.RemoveAvRel(srcAv.ID, srcRel.AvID)
}
srcRel = &av.Relation{
@ -1069,6 +1081,8 @@ func updateAttributeViewColRelation(operation *Operation) (err error) {
err = av.SaveAttributeView(destAv)
util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": destAv.ID})
}
av.UpsertAvBackRel(srcAv.ID, destAv.ID)
return
}
@ -2116,31 +2130,53 @@ func removeAttributeViewColumn(operation *Operation) (err error) {
}
}
// 删除双向关联的目标列
if nil != removedKey && nil != removedKey.Relation && removedKey.Relation.IsTwoWay {
destAv, _ := av.ParseAttributeView(removedKey.Relation.AvID)
if nil != destAv {
for i, keyValues := range destAv.KeyValues {
if keyValues.Key.ID == removedKey.Relation.BackKeyID {
destAv.KeyValues = append(destAv.KeyValues[:i], destAv.KeyValues[i+1:]...)
break
}
}
if nil != removedKey && av.KeyTypeRelation == removedKey.Type && nil != removedKey.Relation {
if removedKey.Relation.IsTwoWay {
// 删除双向关联的目标列
for _, view := range destAv.Views {
switch view.LayoutType {
case av.LayoutTypeTable:
for i, column := range view.Table.Columns {
if column.ID == removedKey.Relation.BackKeyID {
view.Table.Columns = append(view.Table.Columns[:i], view.Table.Columns[i+1:]...)
break
destAv, _ := av.ParseAttributeView(removedKey.Relation.AvID)
if nil != destAv {
destAvRelSrcAv := false
for i, keyValues := range destAv.KeyValues {
if keyValues.Key.ID == removedKey.Relation.BackKeyID {
destAv.KeyValues = append(destAv.KeyValues[:i], destAv.KeyValues[i+1:]...)
continue
}
if av.KeyTypeRelation == keyValues.Key.Type && keyValues.Key.Relation.AvID == attrView.ID {
destAvRelSrcAv = true
}
}
for _, view := range destAv.Views {
switch view.LayoutType {
case av.LayoutTypeTable:
for i, column := range view.Table.Columns {
if column.ID == removedKey.Relation.BackKeyID {
view.Table.Columns = append(view.Table.Columns[:i], view.Table.Columns[i+1:]...)
break
}
}
}
}
av.SaveAttributeView(destAv)
util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": destAv.ID})
if !destAvRelSrcAv {
av.RemoveAvRel(destAv.ID, attrView.ID)
}
}
av.SaveAttributeView(destAv)
util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": destAv.ID})
srcAvRelDestAv := false
for _, keyValues := range attrView.KeyValues {
if av.KeyTypeRelation == keyValues.Key.Type && keyValues.Key.Relation.AvID == removedKey.Relation.AvID {
srcAvRelDestAv = true
}
}
if !srcAvRelDestAv {
av.RemoveAvRel(attrView.ID, removedKey.Relation.AvID)
}
}
}
@ -2304,7 +2340,7 @@ func UpdateAttributeViewCell(tx *Transaction, avID, keyID, rowID, cellID string,
// 关联列得 content 是自动渲染的,所以不需要保存
val.Relation.Contents = nil
// 计算关联排序模式
// 计算关联变更模式
if len(oldRelationBlockIDs) == len(val.Relation.BlockIDs) {
relationChangeMode = 0
} else {
@ -2349,64 +2385,70 @@ func UpdateAttributeViewCell(tx *Transaction, avID, keyID, rowID, cellID string,
}
key, _ := attrView.GetKey(val.KeyID)
if nil != key && av.KeyTypeRelation == key.Type && nil != key.Relation && key.Relation.IsTwoWay {
if nil != key && av.KeyTypeRelation == key.Type && nil != key.Relation {
destAv, _ := av.ParseAttributeView(key.Relation.AvID)
if nil != destAv {
// relationChangeMode
// 0关联列值不变仅排序不影响目标值
// 1关联列值增加增加目标值
// 2关联列值减少减少目标值
if key.Relation.IsTwoWay {
// relationChangeMode
// 0关联列值不变仅排序不影响目标值
// 1关联列值增加增加目标值
// 2关联列值减少减少目标值
if 1 == relationChangeMode {
addBlockIDs := val.Relation.BlockIDs
for _, bID := range oldRelationBlockIDs {
addBlockIDs = gulu.Str.RemoveElem(addBlockIDs, bID)
}
for _, blockID := range addBlockIDs {
for _, keyValues := range destAv.KeyValues {
if keyValues.Key.ID != key.Relation.BackKeyID {
continue
}
destVal := keyValues.GetValue(blockID)
if nil == destVal {
destVal = &av.Value{ID: ast.NewNodeID(), KeyID: keyValues.Key.ID, BlockID: blockID, Type: keyValues.Key.Type, Relation: &av.ValueRelation{}}
keyValues.Values = append(keyValues.Values, destVal)
}
destVal.Relation.BlockIDs = append(destVal.Relation.BlockIDs, rowID)
destVal.Relation.BlockIDs = gulu.Str.RemoveDuplicatedElem(destVal.Relation.BlockIDs)
break
if 1 == relationChangeMode {
addBlockIDs := val.Relation.BlockIDs
for _, bID := range oldRelationBlockIDs {
addBlockIDs = gulu.Str.RemoveElem(addBlockIDs, bID)
}
}
} else if 2 == relationChangeMode {
removeBlockIDs := oldRelationBlockIDs
for _, bID := range val.Relation.BlockIDs {
removeBlockIDs = gulu.Str.RemoveElem(removeBlockIDs, bID)
}
for _, blockID := range removeBlockIDs {
for _, keyValues := range destAv.KeyValues {
if keyValues.Key.ID != key.Relation.BackKeyID {
continue
for _, blockID := range addBlockIDs {
for _, keyValues := range destAv.KeyValues {
if keyValues.Key.ID != key.Relation.BackKeyID {
continue
}
destVal := keyValues.GetValue(blockID)
if nil == destVal {
destVal = &av.Value{ID: ast.NewNodeID(), KeyID: keyValues.Key.ID, BlockID: blockID, Type: keyValues.Key.Type, Relation: &av.ValueRelation{}}
keyValues.Values = append(keyValues.Values, destVal)
}
destVal.Relation.BlockIDs = append(destVal.Relation.BlockIDs, rowID)
destVal.Relation.BlockIDs = gulu.Str.RemoveDuplicatedElem(destVal.Relation.BlockIDs)
break
}
}
} else if 2 == relationChangeMode {
removeBlockIDs := oldRelationBlockIDs
for _, bID := range val.Relation.BlockIDs {
removeBlockIDs = gulu.Str.RemoveElem(removeBlockIDs, bID)
}
for _, value := range keyValues.Values {
if value.BlockID == blockID {
value.Relation.BlockIDs = gulu.Str.RemoveElem(value.Relation.BlockIDs, rowID)
break
for _, blockID := range removeBlockIDs {
for _, keyValues := range destAv.KeyValues {
if keyValues.Key.ID != key.Relation.BackKeyID {
continue
}
for _, value := range keyValues.Values {
if value.BlockID == blockID {
value.Relation.BlockIDs = gulu.Str.RemoveElem(value.Relation.BlockIDs, rowID)
break
}
}
}
}
}
}
av.SaveAttributeView(destAv)
util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": destAv.ID})
av.SaveAttributeView(destAv)
}
}
}
relatedAvIDs := av.GetSrcAvIDs(avID)
for _, relatedAvID := range relatedAvIDs {
util.BroadcastByType("protyle", "refreshAttributeView", 0, "", map[string]interface{}{"id": relatedAvID})
}
if err = av.SaveAttributeView(attrView); nil != err {
return
}

View file

@ -350,6 +350,10 @@ func matchPackage(keywords []string, pkg *bazaar.Package) bool {
return true
}
if nil == pkg || nil == pkg.DisplayName || nil == pkg.Description {
return false
}
for _, keyword := range keywords {
if strings.Contains(strings.ToLower(pkg.DisplayName.Default), keyword) ||
strings.Contains(strings.ToLower(pkg.DisplayName.ZhCN), keyword) ||

View file

@ -12,7 +12,7 @@
"FileDescription": "SiYuan Kernel",
"FileVersion": "",
"InternalName": "",
"LegalCopyright": "© 2023 Yunnan Liandi Technology Co., Ltd.",
"LegalCopyright": "© 2024 Yunnan Liandi Technology Co., Ltd.",
"LegalTrademarks": "",
"OriginalFilename": "",
"PrivateBuild": "",