github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/schema/schema.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 "github.com/dolthub/dolt/go/store/types" 18 19 // Schema is an interface for retrieving the columns that make up a schema 20 type Schema interface { 21 // GetPKCols gets the collection of columns which make the primary key. 22 GetPKCols() *ColCollection 23 24 // GetNonPKCols gets the collection of columns which are not part of the primary key. 25 GetNonPKCols() *ColCollection 26 27 // GetAllCols gets the collection of all columns (pk and non-pk) 28 GetAllCols() *ColCollection 29 30 // Indexes returns a collection of all indexes on the table that this schema belongs to. 31 Indexes() IndexCollection 32 33 // Checks returns a collection of all check constraints on the table that this schema belongs to. 34 Checks() CheckCollection 35 } 36 37 // ColFromTag returns a schema.Column from a schema and a tag 38 func ColFromTag(sch Schema, tag uint64) (Column, bool) { 39 return sch.GetAllCols().GetByTag(tag) 40 } 41 42 // ColFromName returns a schema.Column from a schema from it's name 43 func ColFromName(sch Schema, name string) (Column, bool) { 44 return sch.GetAllCols().GetByName(name) 45 } 46 47 // ExtractAllColNames returns a map of tag to column name, with one map entry for every column in the schema. 48 func ExtractAllColNames(sch Schema) (map[uint64]string, error) { 49 colNames := make(map[uint64]string) 50 err := sch.GetAllCols().Iter(func(tag uint64, col Column) (stop bool, err error) { 51 colNames[tag] = col.Name 52 return false, nil 53 }) 54 55 if err != nil { 56 return nil, err 57 } 58 59 return colNames, nil 60 } 61 62 func IsKeyless(sch Schema) bool { 63 return sch.GetPKCols().Size() == 0 && 64 sch.GetAllCols().Size() != 0 65 } 66 67 func HasAutoIncrement(sch Schema) (ok bool) { 68 _ = sch.GetAllCols().Iter(func(tag uint64, col Column) (stop bool, err error) { 69 if col.AutoIncrement { 70 ok = true 71 stop = true 72 } 73 return 74 }) 75 return 76 } 77 78 // SchemasAreEqual tests equality of two schemas. 79 func SchemasAreEqual(sch1, sch2 Schema) bool { 80 if sch1 == nil && sch2 == nil { 81 return true 82 } else if sch1 == nil || sch2 == nil { 83 return false 84 } 85 colCollIsEqual := ColCollsAreEqual(sch1.GetAllCols(), sch2.GetAllCols()) 86 if !colCollIsEqual { 87 return false 88 } 89 return sch1.Indexes().Equals(sch2.Indexes()) 90 } 91 92 // TODO: this function never returns an error 93 // VerifyInSchema tests that the incoming schema matches the schema from the original table 94 // based on the presence of the column name in the original schema. 95 func VerifyInSchema(inSch, outSch Schema) (bool, error) { 96 inSchCols := inSch.GetAllCols() 97 outSchCols := outSch.GetAllCols() 98 99 if inSchCols.Size() != outSchCols.Size() { 100 return false, nil 101 } 102 103 match := true 104 err := inSchCols.Iter(func(tag uint64, inCol Column) (stop bool, err error) { 105 _, isValid := outSchCols.GetByNameCaseInsensitive(inCol.Name) 106 107 if !isValid { 108 match = false 109 return true, nil 110 } 111 112 return false, nil 113 }) 114 115 if err != nil { 116 return false, err 117 } 118 119 return match, nil 120 } 121 122 // GetSharedCols returns a name -> tag mapping for name/kind matches 123 func GetSharedCols(schema Schema, cmpNames []string, cmpKinds []types.NomsKind) map[string]uint64 { 124 existingColKinds := make(map[string]types.NomsKind) 125 existingColTags := make(map[string]uint64) 126 127 _ = schema.GetAllCols().Iter(func(tag uint64, col Column) (stop bool, err error) { 128 existingColKinds[col.Name] = col.Kind 129 existingColTags[col.Name] = col.Tag 130 return false, nil 131 }) 132 133 reuseTags := make(map[string]uint64) 134 for i, col := range cmpNames { 135 if val, ok := existingColKinds[col]; ok { 136 if val == cmpKinds[i] { 137 reuseTags[col] = existingColTags[col] 138 } 139 } 140 } 141 return reuseTags 142 }