github.com/voedger/voedger@v0.0.0-20240520144910-273e84102129/pkg/appdefcompat/README.md (about) 1 # Compatibility 2 3 Motivation 4 - [Parser: Package AST compatibility tool](https://github.com/voedger/voedger/issues/617) 5 6 ## Functional Design 7 8 ### Concepts 9 10 Compatibility error types: 11 12 - Projector Read compatibility (some projectors reads fail or even crash). Some examples: 13 - Table is removed from a workspace 14 - Table is removed from a package 15 - Table usage is removed form a workspace 16 - Field order is changed in a Table 17 - Field is added to a View key 18 - Table is removed from a workspace scope 19 - Field type is changed 20 - Projector Write compatibility (some projectors writes fail). Some examples: 21 - Constraint is added/changed/removed 22 - Other possible compatibility errors examples: 23 - ACL entry is added or changed, it changes API behaviour for non-System authorization 24 25 Why "Projector..."? To simplify definition, Projector uses System authorization and is not affected by ACL changes. 26 27 28 29 ### Principles 30 31 - Only Projector Read compatibility errors are checked 32 33 ### Functions 34 35 ```go 36 37 func CheckBackwardCompatibility(oldAppDef, newAppDef appdef.IAppDef) (cerrs *CompatibilityErrors) 38 39 func IgnoreCompatibilityErrors(cerrs *CompatibilityErrors, pathsToIgnore [][]string) (cerrsOut *CompatibilityErrors) 40 ``` 41 42 ## Technical Design 43 44 ### Principles 45 46 - appdef.AppDef is used, not parser.ASTs 47 - Rationale: appdef.AppDef is easier to use, e.g. 48 - Parser.PackageAST contains multiple definitions of Workspace that must be merged before use 49 - AST does not provide list of all QNames in a package 50 - Algorythm 51 1. Build old and new `CompatibilityTree`-s 52 2. Compare CompatibilityTree-s using `NodeConstraint`-s 53 54 55 ### Tree and Constraints 56 57 ```go 58 type Constraint string 59 type NodeType string 60 61 const ( 62 ConstraintValueMatch Constraint = "ConstraintValueMatch" 63 ConstraintAppendOnly Constraint = "ConstraintAppendOnly" 64 ConstraintInsertOnly Constraint = "ConstraintInsertOnly" 65 ConstraintNonModifiable Constraint = "ConstraintNonModifiable" 66 ) 67 68 type CompatibilityTreeNode { 69 ParentNode *CompatibilityTreeNode 70 Name string 71 Props []*CompatibilityTreeNode 72 Value interface{} 73 invisibleInPath bool 74 } 75 76 type NodeConstraint struct { 77 NodeName string 78 Constraint Constraint 79 } 80 ``` 81 82 ### CompatibilityTree example 83 84 - AppDef AppDef 85 - Packages 86 - packagePath1 LocalName1 87 - packagePath2 LocalName2 88 - packagePath3 LocalName3 89 - packagePath4 LocalName4 90 - packagePath5 LocalName5 91 - Types 92 - pkg1.Workspace1 // IWorkspace 93 - Types 94 - pkg1.Table5 95 - pkg5.View2 96 - Inheritance // FIXME not implemented??? 97 - pkg1.Workspace2 98 - pkg1.Workspace3 99 - Descriptor pkg1.Workspace1Descriptor 100 - pkg2.SomeQName // IType 101 - Abstract true // IWithAbstract 102 - Fields // IFields 103 - Name1 int // IField 104 - Name2 varchar (no length here) // IField 105 - Containers // IContainers 106 - Name1 QName1 107 - Name2 QName2 108 - pkg3.SomeTable // IDoc 109 - Abstract true // IWithAbstract 110 - Fields // IFields 111 - Name1 int // IField 112 - Name2 varchar (no length here) // IField 113 - Containers // IContainers 114 - Name1 QName1 115 - Name2 QName2 116 - Uniques // IUniques 117 - Name1 QName1 // IUnique 118 - UniqueFields 119 - Name2 varchar 120 - Name1 int 121 - Parent 122 - Abstract true // IWithAbstract 123 - Fields // IFields 124 - Name1 int 125 - Name2 varchar (no length here) 126 - Containers // IContainers 127 - Name1 QName1 128 - Name2 QName2 129 - Name2 QName2 // IUnique 130 - UniqueFields 131 - Name1 int 132 - Name2 varchar 133 - Parent 134 - Abstract true // IWithAbstract 135 - Fields // IFields 136 - Name1 int 137 - Name2 varchar (no length here) 138 - Containers // IContainers 139 - Name1 QName1 140 - Name2 QName2 141 - pkg3.View // IView 142 - PartKeyFields // Key().Partition() 143 - Name1 int 144 - Name2 int 145 - ClustColsFields // Key().ClustCols() 146 - Name1 int 147 - Name2 varchar 148 - Fields // Value fields 149 - ... 150 // FIXME Containers ??? 151 - pkg3.Projector Props 152 - Sync true 153 -pkg3.Command Props // ICommand 154 - CommandArgs Props 155 - UnloggedArgs Props 156 - CommandResult Props 157 - pkg3.Query // IQuery 158 - QueryArgs Props 159 - QueryResult Props 160 161 ### Constraints 162 163 NodeConstraint examples: 164 ```golang 165 166 typesConstraint := NodeConstraint{"Types", ConstraintInsertOnly} 167 fieldsConstraint := NodeConstraint{"Fields", ConstraintAppendOnly} 168 ``` 169 170 ### CompatibilityError 171 172 ```golang 173 type CompatibilityError struct { 174 Constraint Constraint 175 176 OldTreePath []string 177 178 // NodeRemoved: (NonModifiable, AppendOnly,InsertOnly) : one error per removed node 179 // OrderChanged: (NonModifiable, AppendOnly): one error for the container 180 // NodeInserted: (NonModifiable): one error for the container 181 // ValueChanged: one error for one node 182 // NodeModified: one error for the container 183 ErrorType ErrorType 184 } 185 ``` 186 OldTreePath example: 187 ```golang 188 []string{"AppDef", "Types", "sys.Workspace1", "Types", "sys.Table5", "Fields", "Name1"} 189 ``` 190 191 ```golang 192 type CompatibilityErrors { 193 Errors []CompatibilityError 194 Error() string 195 } 196 ```