github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/schema/constraint.go (about) 1 // Copyright 2019 Dolthub, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package schema 16 17 import ( 18 "fmt" 19 20 "github.com/dolthub/dolt/go/store/types" 21 ) 22 23 // ColConstraint is an interface used for evaluating whether a columns value is valid 24 type ColConstraint interface { 25 // SatisfiesConstraint takes in a value and returns true if the value satisfies the constraint 26 SatisfiesConstraint(value types.Value) bool 27 28 // GetConstraintType returns a string representation of the type of constraint. This is used for serialization and 29 // deserialization of constraints (see ColConstraintFromTypeAndParams). 30 GetConstraintType() string 31 32 // GetConstraintParams returns a map[string]string containing the constraints parameters. This is used for 33 // serialization and deserialization of constraints, and a deserialized constraint must be able to reproduce the same 34 // behavior based on the parameters in this map (See ColConstraintFromTypeAndParams). 35 GetConstraintParams() map[string]string 36 37 // Stringer results are used to inform users of the constraint's properties. 38 fmt.Stringer 39 } 40 41 const ( 42 NotNullConstraintType = "not_null" 43 ) 44 45 // ColConstraintFromTypeAndParams takes in a string representing the type of the constraint and a map of parameters 46 // that can be used to determine the behavior of the constraint. An example might be a constraint which validated 47 // a value is in a given range. For this the constraint type might by "in_range_constraint", and the parameters might 48 // be {"min": -10, "max": 10} 49 func ColConstraintFromTypeAndParams(colCnstType string, params map[string]string) ColConstraint { 50 switch colCnstType { 51 case NotNullConstraintType: 52 return NotNullConstraint{} 53 } 54 panic("Unknown column constraint type: " + colCnstType) 55 } 56 57 // NotNullConstraint validates that a value is not null. It does not restrict 0 length strings, or 0 valued ints, or 58 // anything other than non nil values 59 type NotNullConstraint struct{} 60 61 // SatisfiesConstraint returns true if value is not nil and not types.NullValue 62 func (nnc NotNullConstraint) SatisfiesConstraint(value types.Value) bool { 63 return !types.IsNull(value) 64 } 65 66 // GetConstraintType returns "not_null" 67 func (nnc NotNullConstraint) GetConstraintType() string { 68 return NotNullConstraintType 69 } 70 71 // GetConstraintParams returns nil as this constraint does not require any parameters. 72 func (nnc NotNullConstraint) GetConstraintParams() map[string]string { 73 return nil 74 } 75 76 // String returns a useful description of the constraint 77 func (nnc NotNullConstraint) String() string { 78 return "Not null" 79 } 80 81 // IndexOfConstraint returns the index in the supplied slice of the first constraint of matching type. If none are 82 // found then -1 is returned 83 func IndexOfConstraint(constraints []ColConstraint, constraintType string) int { 84 for i, c := range constraints { 85 if c.GetConstraintType() == constraintType { 86 return i 87 } 88 } 89 90 return -1 91 } 92 93 // ColConstraintsAreEqual validates two ColConstraint slices are identical. 94 func ColConstraintsAreEqual(a, b []ColConstraint) bool { 95 if len(a) != len(b) { 96 return false 97 } else if len(a) == 0 { 98 return true 99 } 100 101 // kinda shitty. Probably shouldn't require order to be identital 102 for i := 0; i < len(a); i++ { 103 ca, cb := a[i], b[i] 104 105 if ca.GetConstraintType() != cb.GetConstraintType() { 106 return false 107 } else { 108 pa := ca.GetConstraintParams() 109 pb := cb.GetConstraintParams() 110 111 if len(pa) != len(pb) { 112 return false 113 } else if len(pa) != 0 { 114 for k, va := range pa { 115 vb, ok := pb[k] 116 117 if !ok { 118 return false 119 } else if va != vb { 120 return false 121 } 122 } 123 } 124 } 125 } 126 127 return true 128 }