A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 164 lines 4.4 kB view raw
1// SiYuan - Refactor your thinking 2// Copyright (c) 2020-present, b3log.org 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU Affero General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU Affero General Public License for more details. 13// 14// You should have received a copy of the GNU Affero General Public License 15// along with this program. If not, see <https://www.gnu.org/licenses/>. 16 17package model 18 19import ( 20 "strings" 21 "time" 22 "unicode/utf8" 23 24 "github.com/88250/gulu" 25 "github.com/88250/lute/ast" 26 "github.com/siyuan-note/siyuan/kernel/av" 27 "github.com/siyuan-note/siyuan/kernel/filesys" 28 "github.com/siyuan-note/siyuan/kernel/treenode" 29 "github.com/siyuan-note/siyuan/kernel/util" 30) 31 32func checkAttrView(attrView *av.AttributeView, view *av.View) { 33 // 字段删除以后需要删除设置的过滤和排序 34 tmpFilters := []*av.ViewFilter{} 35 for _, f := range view.Filters { 36 if k, _ := attrView.GetKey(f.Column); nil != k { 37 tmpFilters = append(tmpFilters, f) 38 } 39 } 40 changed := len(tmpFilters) != len(view.Filters) 41 view.Filters = tmpFilters 42 43 tmpSorts := []*av.ViewSort{} 44 for _, s := range view.Sorts { 45 if k, _ := attrView.GetKey(s.Column); nil != k { 46 tmpSorts = append(tmpSorts, s) 47 } 48 } 49 if !changed { 50 changed = len(tmpSorts) != len(view.Sorts) 51 } 52 view.Sorts = tmpSorts 53 54 // 字段删除以后需要删除设置的分组 55 if nil != view.Group { 56 if k, _ := attrView.GetKey(view.Group.Field); nil == k { 57 view.Group = nil 58 } 59 } 60 61 // 订正视图类型 62 for i, v := range attrView.Views { 63 if av.LayoutTypeGallery == v.LayoutType && nil == v.Gallery { 64 // 切换为卡片视图时可能没有初始化卡片实例 https://github.com/siyuan-note/siyuan/issues/15122 65 if nil != v.Table { 66 v.LayoutType = av.LayoutTypeTable 67 changed = true 68 } else { 69 attrView.Views = append(attrView.Views[:i], attrView.Views[i+1:]...) 70 changed = true 71 } 72 } 73 } 74 75 now := util.CurrentTimeMillis() 76 77 // 订正字段类型 78 for _, kv := range attrView.KeyValues { 79 for _, v := range kv.Values { 80 if v.Type != kv.Key.Type { 81 v.Type = kv.Key.Type 82 if av.KeyTypeBlock == v.Type && nil == v.Block { 83 v.Block = &av.ValueBlock{} 84 if nil != v.Text { 85 v.Block.Content = v.Text.Content 86 } 87 if "" == v.BlockID { 88 v.BlockID = ast.NewNodeID() 89 } 90 createdStr := v.BlockID[:len("20060102150405")] 91 created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local) 92 if nil == parseErr { 93 v.Block.Created = created.UnixMilli() 94 } else { 95 v.Block.Created = now 96 } 97 v.Block.Updated = v.Block.Created 98 } 99 changed = true 100 } 101 } 102 } 103 104 attrView.Name = strings.ReplaceAll(attrView.Name, "\n", " ") 105 // 截断超长的数据库标题 Limit the database title to 512 characters https://github.com/siyuan-note/siyuan/issues/15459 106 if 512 < utf8.RuneCountInString(attrView.Name) { 107 attrView.Name = gulu.Str.SubStr(attrView.Name, 512) 108 changed = true 109 } 110 111 if changed { 112 av.SaveAttributeView(attrView) 113 } 114} 115 116func upgradeAttributeViewSpec(attrView *av.AttributeView) { 117 currentSpec := attrView.Spec 118 119 upgradeAttributeViewSpec1(attrView) 120 av.UpgradeSpec(attrView) 121 122 newSpec := attrView.Spec 123 if currentSpec != newSpec { 124 av.SaveAttributeView(attrView) 125 } 126} 127 128func upgradeAttributeViewSpec1(attrView *av.AttributeView) { 129 if 1 <= attrView.Spec { 130 return 131 } 132 133 var blockIDs []string 134 idBlocks := map[string]*av.Value{} 135 for _, kv := range attrView.KeyValues { 136 switch kv.Key.Type { 137 case av.KeyTypeBlock: 138 for _, v := range kv.Values { 139 if !v.IsDetached { 140 blockIDs = append(blockIDs, v.BlockID) 141 idBlocks[v.BlockID] = v 142 } 143 } 144 } 145 } 146 blockIDs = gulu.Str.RemoveDuplicatedElem(blockIDs) 147 148 trees := filesys.LoadTrees(blockIDs) 149 for _, id := range blockIDs { 150 tree := trees[id] 151 if nil == tree { 152 continue 153 } 154 155 node := treenode.GetNodeInTree(tree, id) 156 if nil == node { 157 continue 158 } 159 160 if block := idBlocks[id].Block; nil != block { 161 block.Icon = node.IALAttr("icon") 162 } 163 } 164}