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  ```