github.com/hasnat/dolt/go@v0.0.0-20210628190320-9eb5d843fbb7/libraries/doltcore/sqle/single_table_info_db.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 sqle 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/dolthub/go-mysql-server/sql" 22 23 "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" 24 "github.com/dolthub/dolt/go/libraries/doltcore/schema" 25 "github.com/dolthub/dolt/go/libraries/doltcore/sqle/sqlutil" 26 "github.com/dolthub/dolt/go/store/types" 27 ) 28 29 // SingleTableInfoDatabase is intended to allow a sole schema to make use of any display functionality in `go-mysql-server`. 30 // For example, you may have constructed a schema that you want a CREATE TABLE statement for, but the schema is not 31 // persisted or is temporary. This allows `go-mysql-server` to interact with that sole schema as though it were a database. 32 // No write operations will work with this database. 33 type SingleTableInfoDatabase struct { 34 tableName string 35 sch schema.Schema 36 foreignKeys []doltdb.ForeignKey 37 parentSchs map[string]schema.Schema 38 } 39 40 var _ sql.Database = (*SingleTableInfoDatabase)(nil) 41 var _ sql.Table = (*SingleTableInfoDatabase)(nil) 42 var _ sql.IndexedTable = (*SingleTableInfoDatabase)(nil) 43 var _ sql.ForeignKeyTable = (*SingleTableInfoDatabase)(nil) 44 45 func NewSingleTableDatabase(tableName string, sch schema.Schema, foreignKeys []doltdb.ForeignKey, parentSchs map[string]schema.Schema) *SingleTableInfoDatabase { 46 return &SingleTableInfoDatabase{ 47 tableName: tableName, 48 sch: sch, 49 foreignKeys: foreignKeys, 50 parentSchs: parentSchs, 51 } 52 } 53 54 // Name implements sql.Table and sql.Database. 55 func (db *SingleTableInfoDatabase) Name() string { 56 return db.tableName 57 } 58 59 // GetTableInsensitive implements sql.Database. 60 func (db *SingleTableInfoDatabase) GetTableInsensitive(ctx *sql.Context, tableName string) (sql.Table, bool, error) { 61 if strings.ToLower(tableName) == strings.ToLower(db.tableName) { 62 return db, true, nil 63 } 64 return nil, false, nil 65 } 66 67 // GetTableNames implements sql.Database. 68 func (db *SingleTableInfoDatabase) GetTableNames(ctx *sql.Context) ([]string, error) { 69 return []string{db.tableName}, nil 70 } 71 72 // String implements sql.Table. 73 func (db *SingleTableInfoDatabase) String() string { 74 return db.tableName 75 } 76 77 // Schema implements sql.Table. 78 func (db *SingleTableInfoDatabase) Schema() sql.Schema { 79 sqlSch, err := sqlutil.FromDoltSchema(db.tableName, db.sch) 80 if err != nil { 81 panic(err) 82 } 83 return sqlSch 84 } 85 86 // Partitions implements sql.Table. 87 func (db *SingleTableInfoDatabase) Partitions(*sql.Context) (sql.PartitionIter, error) { 88 return nil, fmt.Errorf("cannot get paritions of a single table information database") 89 } 90 91 // PartitionRows implements sql.Table. 92 func (db *SingleTableInfoDatabase) PartitionRows(*sql.Context, sql.Partition) (sql.RowIter, error) { 93 return nil, fmt.Errorf("cannot get parition rows of a single table information database") 94 } 95 96 // GetForeignKeys implements sql.ForeignKeyTable. 97 func (db *SingleTableInfoDatabase) GetForeignKeys(ctx *sql.Context) ([]sql.ForeignKeyConstraint, error) { 98 fks := make([]sql.ForeignKeyConstraint, len(db.foreignKeys)) 99 for i, fk := range db.foreignKeys { 100 if parentSch, ok := db.parentSchs[fk.ReferencedTableName]; ok { 101 var err error 102 fks[i], err = toForeignKeyConstraint(fk, db.sch, parentSch) 103 if err != nil { 104 return nil, err 105 } 106 } else { 107 // We can skip here since the given schema may be purposefully incomplete (such as with diffs). 108 continue 109 } 110 } 111 return fks, nil 112 } 113 114 // WithIndexLookup implements sql.IndexedTable. 115 func (db *SingleTableInfoDatabase) WithIndexLookup(sql.IndexLookup) sql.Table { 116 return db 117 } 118 119 // GetIndexes implements sql.IndexedTable. 120 func (db *SingleTableInfoDatabase) GetIndexes(ctx *sql.Context) ([]sql.Index, error) { 121 var sqlIndexes []sql.Index 122 for _, index := range db.sch.Indexes().AllIndexes() { 123 cols := make([]schema.Column, index.Count()) 124 for i, tag := range index.IndexedColumnTags() { 125 cols[i], _ = index.GetColumn(tag) 126 } 127 sqlIndexes = append(sqlIndexes, &doltIndex{ 128 cols: cols, 129 db: db, 130 id: index.Name(), 131 indexRowData: types.EmptyMap, 132 indexSch: index.Schema(), 133 table: nil, 134 tableData: types.EmptyMap, 135 tableName: db.tableName, 136 tableSch: db.sch, 137 unique: index.IsUnique(), 138 comment: index.Comment(), 139 generated: false, 140 }) 141 } 142 return sqlIndexes, nil 143 }