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  }