sqlboiler/dbdrivers/interface.go

119 lines
2.6 KiB
Go
Raw Normal View History

package dbdrivers
import "github.com/pkg/errors"
2016-04-03 09:15:35 +02:00
2016-03-23 05:25:57 +01:00
// Interface for a database driver. Functionality required to support a specific
// database type (eg, MySQL, Postgres etc.)
type Interface interface {
2016-04-03 09:15:35 +02:00
TableNames() ([]string, error)
Columns(tableName string) ([]Column, error)
PrimaryKeyInfo(tableName string) (*PrimaryKey, error)
ForeignKeyInfo(tableName string) ([]ForeignKey, error)
2016-03-23 05:25:57 +01:00
2016-04-03 09:15:35 +02:00
// TranslateColumnType takes a Database column type and returns a go column type.
TranslateColumnType(Column) Column
// Open the database connection
Open() error
// Close the database connection
Close()
}
2016-03-23 05:25:57 +01:00
// Table metadata from the database schema.
type Table struct {
Name string
Columns []Column
2016-03-23 07:02:11 +01:00
PKey *PrimaryKey
FKeys []ForeignKey
2016-03-23 05:25:57 +01:00
IsJoinTable bool
}
// Column holds information about a database column.
// Types are Go types, converted by TranslateColumnType.
2016-03-23 05:25:57 +01:00
type Column struct {
2016-04-03 09:15:35 +02:00
Name string
Type string
Default string
2016-04-03 09:15:35 +02:00
IsNullable bool
}
2016-03-23 07:02:11 +01:00
// PrimaryKey represents a primary key constraint in a database
type PrimaryKey struct {
Name string
Columns []string
}
// ForeignKey represents a foreign key constraint in a database
type ForeignKey struct {
Name string
Column string
ForeignTable string
ForeignColumn string
}
2016-04-03 09:15:35 +02:00
// Tables returns the table metadata for the given tables, or all tables if
// no tables are provided.
func Tables(db Interface, names ...string) ([]Table, error) {
var err error
if len(names) == 0 {
if names, err = db.TableNames(); err != nil {
return nil, errors.Wrap(err, "unable to get table names")
2016-04-03 09:15:35 +02:00
}
}
var tables []Table
for _, name := range names {
t := Table{Name: name}
if t.Columns, err = db.Columns(name); err != nil {
return nil, errors.Wrapf(err, "unable to fetch table column info (%s)", name)
2016-04-03 09:15:35 +02:00
}
for i, c := range t.Columns {
t.Columns[i] = db.TranslateColumnType(c)
}
if t.PKey, err = db.PrimaryKeyInfo(name); err != nil {
return nil, errors.Wrapf(err, "unable to fetch table pkey info (%s)", name)
2016-04-03 09:15:35 +02:00
}
if t.FKeys, err = db.ForeignKeyInfo(name); err != nil {
return nil, errors.Wrapf(err, "unable to fetch table fkey info (%s)", name)
2016-04-03 09:15:35 +02:00
}
setIsJoinTable(&t)
tables = append(tables, t)
}
return tables, nil
}
2016-04-03 10:02:41 +02:00
// setIsJoinTable iff there are:
// There is a composite primary key involving two columns
// Both primary key columns are also foreign keys
2016-04-03 09:15:35 +02:00
func setIsJoinTable(t *Table) {
2016-04-03 10:02:41 +02:00
if t.PKey == nil || len(t.PKey.Columns) != 2 || len(t.FKeys) < 2 {
2016-04-03 09:15:35 +02:00
return
}
for _, c := range t.PKey.Columns {
found := false
for _, f := range t.FKeys {
if c == f.Column {
found = true
break
}
}
if !found {
return
}
}
t.IsJoinTable = true
}