github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/sqlutil/convert.go (about) 1 // Copyright 2020 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 sqlutil 16 17 import ( 18 "context" 19 "fmt" 20 21 sqle "github.com/dolthub/go-mysql-server" 22 "github.com/dolthub/go-mysql-server/sql" 23 24 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 25 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 26 "github.com/dolthub/dolt/go/libraries/doltcore/schema/typeinfo" 27 "github.com/dolthub/dolt/go/store/types" 28 ) 29 30 // ToDoltResultSchema returns a dolt Schema from the sql schema given, suitable for use as a result set. For 31 // creating tables, use ToDoltSchema. 32 func ToDoltResultSchema(sqlSchema sql.Schema) (schema.Schema, error) { 33 var cols []schema.Column 34 for i, col := range sqlSchema { 35 convertedCol, err := ToDoltCol(uint64(i), col) 36 if err != nil { 37 return nil, err 38 } 39 cols = append(cols, convertedCol) 40 } 41 42 colColl := schema.NewColCollection(cols...) 43 return schema.UnkeyedSchemaFromCols(colColl), nil 44 } 45 46 func FromDoltSchema(tableName string, sch schema.Schema) (sql.Schema, error) { 47 cols := make([]*sqle.ColumnWithRawDefault, sch.GetAllCols().Size()) 48 49 var i int 50 _ = sch.GetAllCols().Iter(func(tag uint64, col schema.Column) (stop bool, err error) { 51 sqlType := col.TypeInfo.ToSqlType() 52 var extra string 53 if col.AutoIncrement { 54 extra = "auto_increment" 55 } 56 57 cols[i] = &sqle.ColumnWithRawDefault{ 58 SqlColumn: &sql.Column{ 59 Name: col.Name, 60 Type: sqlType, 61 Default: nil, 62 Nullable: col.IsNullable(), 63 Source: tableName, 64 PrimaryKey: col.IsPartOfPK, 65 AutoIncrement: col.AutoIncrement, 66 Comment: col.Comment, 67 Extra: extra, 68 }, 69 Default: col.Default, 70 } 71 i++ 72 return false, nil 73 }) 74 75 return sqle.ResolveDefaults(tableName, cols) 76 } 77 78 // ToDoltSchema returns a dolt Schema from the sql schema given, suitable for use in creating a table. 79 // For result set schemas, see ToDoltResultSchema. 80 func ToDoltSchema(ctx context.Context, root *doltdb.RootValue, tableName string, sqlSchema sql.Schema, headRoot *doltdb.RootValue) (schema.Schema, error) { 81 var cols []schema.Column 82 var err error 83 84 // generate tags for all columns 85 var names []string 86 var kinds []types.NomsKind 87 for _, col := range sqlSchema { 88 names = append(names, col.Name) 89 ti, err := typeinfo.FromSqlType(col.Type) 90 if err != nil { 91 return nil, err 92 } 93 kinds = append(kinds, ti.NomsKind()) 94 } 95 96 tags, err := root.GenerateTagsForNewColumns(ctx, tableName, names, kinds, headRoot) 97 if err != nil { 98 return nil, err 99 } 100 101 if len(tags) != len(sqlSchema) { 102 return nil, fmt.Errorf("number of tags should equal number of columns") 103 } 104 105 for i, col := range sqlSchema { 106 convertedCol, err := ToDoltCol(tags[i], col) 107 if err != nil { 108 return nil, err 109 } 110 cols = append(cols, convertedCol) 111 } 112 113 colColl := schema.NewColCollection(cols...) 114 115 err = schema.ValidateForInsert(colColl) 116 if err != nil { 117 return nil, err 118 } 119 120 return schema.SchemaFromCols(colColl) 121 } 122 123 // ToDoltCol returns the dolt column corresponding to the SQL column given 124 func ToDoltCol(tag uint64, col *sql.Column) (schema.Column, error) { 125 var constraints []schema.ColConstraint 126 if !col.Nullable { 127 constraints = append(constraints, schema.NotNullConstraint{}) 128 } 129 typeInfo, err := typeinfo.FromSqlType(col.Type) 130 if err != nil { 131 return schema.Column{}, err 132 } 133 134 return schema.NewColumnWithTypeInfo(col.Name, tag, typeInfo, col.PrimaryKey, col.Default.String(), col.AutoIncrement, col.Comment, constraints...) 135 } 136 137 func GetColNamesFromSqlSchema(sqlSch sql.Schema) []string { 138 colNames := make([]string, len(sqlSch)) 139 140 for i, col := range sqlSch { 141 colNames[i] = col.Name 142 } 143 144 return colNames 145 }