schema

package
v0.8.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 4, 2025 License: MIT Imports: 10 Imported by: 1

Documentation

Index

Examples

Constants

View Source
const (
	Untyped   = ColumnType("")
	Bool      = ColumnType("bool")
	Int       = ColumnType("int")
	Int64     = ColumnType("int64")
	Float     = ColumnType("float")
	Text      = ColumnType("text")
	Blob      = ColumnType("blob")
	Time      = ColumnType("time")
	Date      = ColumnType("date")
	Timestamp = ColumnType("timestamp")
	UUID      = ColumnType("uuid")
	JSON      = ColumnType("json")
	JSONB     = ColumnType("jsonb")
)
View Source
const (
	Virtual = GeneratedStorage(iota)
	Stored
)
View Source
const (
	SetNull = ForeignKeyAction(iota + 1)
	SetDefault
	Cascade
	Restrict
	NoAction
)
View Source
const TemporaryTable = CreateFlag(1)

Variables

View Source
var ErrInvalidForeignKeyAction = errors.New("invalid foreign key action")
View Source
var ErrInvalidGeneratedStorage = errors.New("invalid generated storage")

Functions

func IsEmpty

func IsEmpty(src Querier) (bool, error)

IsEmpty tests if a database has empty schema.

func NormalizeDefault added in v0.3.0

func NormalizeDefault(c *Column)

func NormalizeNames added in v0.3.0

func NormalizeNames(t *Table, uppercase bool)

func SortColumns added in v0.3.0

func SortColumns(t *Table)

func SortIndices added in v0.3.0

func SortIndices(t *Table)

func SortTables added in v0.3.0

func SortTables(tt []*Table)

Types

type Column

type Column struct {
	Name      string     `json:"name" yaml:"name"`
	Type      ColumnType `json:"type,omitempty" yaml:"type,omitempty"`
	Nullable  bool       `json:"nullable,omitempty" yaml:"nullable,omitempty"`
	Default   Literal    `json:"default,omitempty" yaml:"default,omitempty"`
	Generated *Generated `json:"generated,omitempty" yaml:"generated,omitempty"`
	Comment   string     `json:"comment,omitempty" yaml:"comment,omitempty"`
}

Column contains schema scan results for column within a table.

func (*Column) CompatibleTo

func (column *Column) CompatibleTo(info *Column) bool

CompatibleTo returns true if both column signatures are compatible.

func (*Column) MarshalYAML added in v0.2.1

func (c *Column) MarshalYAML() (any, error)

func (*Column) UnmarshalYAML added in v0.6.0

func (c *Column) UnmarshalYAML(node *yaml.Node) error

UnmarshalYAML fixes issue where Literal is not unmarshalled correctly.

type ColumnType added in v0.3.0

type ColumnType string

func NormalizeType added in v0.3.0

func NormalizeType(s ColumnType) ColumnType

type CreateFlag added in v0.3.0

type CreateFlag int

type CurrentDate added in v0.3.0

type CurrentDate struct{}

func (CurrentDate) MarshalJSON added in v0.3.0

func (v CurrentDate) MarshalJSON() ([]byte, error)

func (CurrentDate) MarshalYAML added in v0.3.0

func (v CurrentDate) MarshalYAML() (any, error)

func (CurrentDate) SQLLiteral added in v0.3.0

func (v CurrentDate) SQLLiteral() string

func (CurrentDate) SqliteXXLiteral added in v0.8.1

func (v CurrentDate) SqliteXXLiteral() string

type CurrentTime added in v0.3.0

type CurrentTime struct{}

func (CurrentTime) MarshalJSON added in v0.3.0

func (v CurrentTime) MarshalJSON() ([]byte, error)

func (CurrentTime) MarshalYAML added in v0.3.0

func (v CurrentTime) MarshalYAML() (any, error)

func (CurrentTime) SQLLiteral added in v0.3.0

func (v CurrentTime) SQLLiteral() string

func (CurrentTime) SqliteXXLiteral added in v0.8.1

func (v CurrentTime) SqliteXXLiteral() string

type CurrentTimestamp added in v0.3.0

type CurrentTimestamp struct{}

func (CurrentTimestamp) MarshalJSON added in v0.3.0

func (v CurrentTimestamp) MarshalJSON() ([]byte, error)

func (CurrentTimestamp) MarshalYAML added in v0.3.0

func (v CurrentTimestamp) MarshalYAML() (any, error)

func (CurrentTimestamp) SQLLiteral added in v0.3.0

func (v CurrentTimestamp) SQLLiteral() string

func (CurrentTimestamp) SqliteXXLiteral added in v0.8.1

func (v CurrentTimestamp) SqliteXXLiteral() string

type Database

type Database struct {
	Tables []*Table `json:"tables" yaml:"tables"`
}

Database contains table schemas, typically obtained when calling the Scan routine on a database connection.

Example
db, _ := sql.Open("sqlite3", ":memory:")
_, err := db.Exec(`
		create table t1 (
			id       int64,
			uid      uuid  not null unique,
			n1       int   default 42,
			n2       int   default null,
			n3       int,
			nn1      int   not null default 42,
			nn2      int   not null default null,
			nn3      int   not null,
			s1       text  default "42",
			s2       text  default "null",
			s3       text  default null,
			s4       text,
			s5       text  not null default "42",
			s6       text  not null default "null",
			s7       text  not null default null,
			s8       text  not null,
			f1		 timestamp not null default current_timestamp,
			primary key (id)
		);
	`)
if err != nil {
	fmt.Print(err)
}
_, err = db.Exec(`
		create table t2 (
			id      int64 not null unique,
			t_id    int64  not null,
			primary key (id)
			foreign key (t_id) references t(id) on delete cascade on update cascade
		);
	`)
if err != nil {
	fmt.Print(err)
}

dbsch, err := Scan(db)
if err != nil {
	fmt.Print(err)
} else {
	y, _ := yaml.Marshal(dbsch.Tables)
	fmt.Print(string(y))
}
Output:

- table: t2
  columns:
    - {name: id, type: int64}
    - {name: t_id, type: int64}
  indices:
    - {name: sqlite_autoindex_t2_1, unique: true}
  pk: [id]
  foreign_keys:
    - child_key: [t_id]
      parent_table: id
      parent_key: [id]
      on_delete: cascade
      on_update: cascade
- table: t1
  columns:
    - {name: id, type: int64, nullable: true}
    - {name: uid, type: uuid}
    - {name: n1, type: INT, nullable: true, default: 42}
    - {name: n2, type: INT, nullable: true, default: null}
    - {name: n3, type: INT, nullable: true}
    - {name: nn1, type: INT, default: 42}
    - {name: nn2, type: INT, default: null}
    - {name: nn3, type: INT}
    - {name: s1, type: TEXT, nullable: true, default: '"42"'}
    - {name: s2, type: TEXT, nullable: true, default: '"null"'}
    - {name: s3, type: TEXT, nullable: true, default: null}
    - {name: s4, type: TEXT, nullable: true}
    - {name: s5, type: TEXT, default: '"42"'}
    - {name: s6, type: TEXT, default: '"null"'}
    - {name: s7, type: TEXT, default: null}
    - {name: s8, type: TEXT}
    - {name: f1, type: timestamp, default: CURRENT_TIMESTAMP}
  indices:
    - {name: sqlite_autoindex_t1_2, unique: true}
    - {name: sqlite_autoindex_t1_1, unique: true}
  pk: [id]

func Scan

func Scan(src Querier) (*Database, error)

Scan obtains all the schema details from the sqlite database.

func (*Database) CheckTables

func (db *Database) CheckTables(names ...string) (missing ErrMissingTables)

CheckTables validates existance of the specified tables.

func (*Database) HasTable added in v0.3.0

func (db *Database) HasTable(tablename string) bool

type ErrIncompatibleColumns

type ErrIncompatibleColumns []string

ErrIncompatibleColumns is a list of column names that can be used as the 'incimpatible columns' error.

func (ErrIncompatibleColumns) Error

func (e ErrIncompatibleColumns) Error() string

Error implements support for the standard error interface.

type ErrIncompatibleIndices

type ErrIncompatibleIndices []string

ErrIncompatibleIndices is a list of index names that can be used as the 'incimpatible columns' error.

func (ErrIncompatibleIndices) Error

func (e ErrIncompatibleIndices) Error() string

Error implements support for the standard error interface.

type ErrIndices

type ErrIndices struct {
	Missing      ErrMissingIndices
	Incompatible ErrIncompatibleIndices
}

ErrIndices enlists missing and incompatible indices in a table.

func (*ErrIndices) Error

func (e *ErrIndices) Error() string

Error implements support for the standard error interface.

type ErrMissingColumns

type ErrMissingColumns []string

ErrMissingColumns is a list of column names that can be used as the 'missing columns' error.

func (ErrMissingColumns) Error

func (e ErrMissingColumns) Error() string

Error implements support for the standard error interface.

type ErrMissingIndices

type ErrMissingIndices []string

ErrMissingIndices is a list of index names that can be used as the 'missing columns' error.

func (ErrMissingIndices) Error

func (e ErrMissingIndices) Error() string

Error implements support for the standard error interface.

type ErrMissingTables

type ErrMissingTables []string

ErrMissingTables is a list of column names that can be used as the 'missing tables' error.

func (ErrMissingTables) Error

func (e ErrMissingTables) Error() string

Error implements support for the standard error interface.

type ErrTableColumns

type ErrTableColumns struct {
	Missing      ErrMissingColumns
	Incompatible ErrIncompatibleColumns
}

ErrTableColumns enlists missing and incompatible columns in a table.

func (*ErrTableColumns) Error

func (e *ErrTableColumns) Error() string

Error implements support for the standard error interface.

type ForeignKey added in v0.7.1

type ForeignKey struct {
	ChildKey    []string         `json:"child_key" yaml:"child_key,omitempty,flow"`
	ParentTable string           `json:"parent_table" yaml:"parent_table"`
	ParentKey   []string         `json:"parent_key,omitempty" yaml:"parent_key,omitempty,flow"`
	OnDelete    ForeignKeyAction `json:"on_delete,omitempty" yaml:"on_delete,omitempty"`
	OnUpdate    ForeignKeyAction `json:"on_update,omitempty" yaml:"on_update,omitempty"`
}

type ForeignKeyAction added in v0.7.1

type ForeignKeyAction int

func (*ForeignKeyAction) MarshalJSON added in v0.7.1

func (a *ForeignKeyAction) MarshalJSON() (bb []byte, err error)

func (*ForeignKeyAction) MarshalText added in v0.7.1

func (a *ForeignKeyAction) MarshalText() (bb []byte, err error)

func (ForeignKeyAction) MarshalYAML added in v0.7.1

func (a ForeignKeyAction) MarshalYAML() (any, error)

func (ForeignKeyAction) String added in v0.7.1

func (a ForeignKeyAction) String() string

func (*ForeignKeyAction) UnmarshalJSON added in v0.7.1

func (a *ForeignKeyAction) UnmarshalJSON(b []byte) (err error)

func (*ForeignKeyAction) UnmarshalText added in v0.7.1

func (a *ForeignKeyAction) UnmarshalText(b []byte) (err error)

type Generated added in v0.8.1

type Generated struct {
	Expression string           `json:"expression" yaml:"expression"`
	Storage    GeneratedStorage `json:"storage" yaml:"storage"`
}

type GeneratedStorage added in v0.8.1

type GeneratedStorage int

func (*GeneratedStorage) MarshalJSON added in v0.8.1

func (v *GeneratedStorage) MarshalJSON() (bb []byte, err error)

func (*GeneratedStorage) MarshalText added in v0.8.1

func (v *GeneratedStorage) MarshalText() (bb []byte, err error)

func (GeneratedStorage) MarshalYAML added in v0.8.1

func (v GeneratedStorage) MarshalYAML() (any, error)

func (GeneratedStorage) String added in v0.8.1

func (gs GeneratedStorage) String() string

func (*GeneratedStorage) UnmarshalJSON added in v0.8.1

func (v *GeneratedStorage) UnmarshalJSON(b []byte) (err error)

func (*GeneratedStorage) UnmarshalText added in v0.8.1

func (v *GeneratedStorage) UnmarshalText(b []byte) (err error)

type Index

type Index struct {
	Name    string   `json:"name" yaml:"name"`
	Unique  bool     `json:"unique,omitempty" yaml:"unique,omitempty"`
	Columns []string `json:"columns,omitempty" yaml:"columns,omitempty"`
}

Index contains schema scan results for table's index.

func (*Index) CompatibleTo

func (idx *Index) CompatibleTo(other *Index) bool

func (*Index) MarshalYAML added in v0.2.1

func (i *Index) MarshalYAML() (any, error)

type Literal added in v0.3.0

type Literal interface {
	json.Marshaler
	yaml.Marshaler
	SQLLiteral() string
	SqliteXXLiteral() string
}

type LiteralBoolean added in v0.3.0

type LiteralBoolean bool

func (LiteralBoolean) MarshalJSON added in v0.3.0

func (v LiteralBoolean) MarshalJSON() ([]byte, error)

func (LiteralBoolean) MarshalYAML added in v0.3.0

func (v LiteralBoolean) MarshalYAML() (any, error)

func (LiteralBoolean) SQLLiteral added in v0.3.0

func (v LiteralBoolean) SQLLiteral() string

func (LiteralBoolean) SqliteXXLiteral added in v0.8.1

func (v LiteralBoolean) SqliteXXLiteral() string

type LiteralInt added in v0.3.0

type LiteralInt int64

func (LiteralInt) MarshalJSON added in v0.3.0

func (v LiteralInt) MarshalJSON() ([]byte, error)

func (LiteralInt) MarshalYAML added in v0.3.0

func (v LiteralInt) MarshalYAML() (any, error)

func (LiteralInt) SQLLiteral added in v0.3.0

func (v LiteralInt) SQLLiteral() string

func (LiteralInt) SqliteXXLiteral added in v0.8.1

func (v LiteralInt) SqliteXXLiteral() string

type NULL added in v0.3.0

type NULL struct{}

func (NULL) MarshalJSON added in v0.3.0

func (v NULL) MarshalJSON() ([]byte, error)

func (NULL) MarshalYAML added in v0.3.0

func (v NULL) MarshalYAML() (any, error)

func (NULL) SQLLiteral added in v0.3.0

func (v NULL) SQLLiteral() string

func (NULL) SqliteXXLiteral added in v0.8.1

func (v NULL) SqliteXXLiteral() string

type Querier added in v0.1.1

type Querier interface {
	Query(query string, args ...interface{}) (*sql.Rows, error)
	QueryRow(query string, args ...interface{}) *sql.Row
}

Querier is a generic db query runner, typically should be hooked to sql.Tx or sql.DB.

type RawLiteral added in v0.3.0

type RawLiteral string

func (RawLiteral) MarshalJSON added in v0.3.0

func (v RawLiteral) MarshalJSON() ([]byte, error)

func (RawLiteral) MarshalYAML added in v0.3.0

func (v RawLiteral) MarshalYAML() (any, error)

func (RawLiteral) SQLLiteral added in v0.3.0

func (v RawLiteral) SQLLiteral() string

func (RawLiteral) SqliteXXLiteral added in v0.8.1

func (v RawLiteral) SqliteXXLiteral() string

type Table

type Table struct {
	Name         string        `json:"table" yaml:"table"`
	Columns      []*Column     `json:"columns,omitempty" yaml:"columns,omitempty"`
	Indices      []*Index      `json:"indices,omitempty" yaml:"indices,omitempty"`
	PK           []string      `json:"pk,omitempty" yaml:"pk,omitempty,flow"`
	ForeignKeys  []*ForeignKey `json:"foreign_keys,omitempty" yaml:"foreign_keys,omitempty"`
	WithoutRowID bool          `json:"without_rowid,omitempty" yaml:"without_rowid,omitempty"`
	Strict       bool          `json:"strict,omitempty" yaml:"strict,omitempty"`
}

Table contains the descriptions for columns and indices within a table.

func (*Table) CheckColumnTypes

func (table *Table) CheckColumnTypes(required map[string]*Column) *ErrTableColumns

CheckColumnTypes checks if the specified database columns match the signatures required by the datamodel.

func (*Table) CheckIndices

func (table *Table) CheckIndices(required map[string]*Index) *ErrIndices

CheckIndices validates if database signatures of specified indices match the indices specified in the data model.

func (*Table) ColumnMapping added in v0.3.0

func (t *Table) ColumnMapping() map[string]*Column

func (*Table) ColumnNames added in v0.1.2

func (table *Table) ColumnNames() map[string]struct{}

func (*Table) CreateIndexStatement added in v0.3.0

func (t *Table) CreateIndexStatement(idx *Index) string

func (*Table) CreateStatements added in v0.3.0

func (t *Table) CreateStatements(w io.Writer, flags ...CreateFlag)
Example
d := Table{
	Name: "MyTable",
	Columns: []*Column{
		{Name: "uid", Type: UUID, Comment: "key"},
		{Name: "name", Type: Text},
		{Name: "created_at", Type: Timestamp},
		{Name: "deleted_at", Type: Timestamp, Nullable: true},
		{Name: "untyped", Nullable: true},
		{Name: "age", Type: Int, Nullable: true},
		{Name: "gen", Generated: &Generated{Expression: `name + " " + age`, Storage: Virtual}},
	},
	PK: []string{"uid"},
	ForeignKeys: []*ForeignKey{
		{
			ChildKey:    []string{"uid"},
			ParentTable: "other_table", ParentKey: []string{"uid"},
			OnDelete: Cascade,
			OnUpdate: Cascade,
		},
	},
	WithoutRowID: true,
	Indices: []*Index{
		{Name: "idx_name", Columns: []string{"name"}, Unique: true},
	},
}

b := bytes.Buffer{}
d.CreateStatements(&b)
fmt.Print(b.String())
Output:

create table MyTable (
    uid         uuid       not null,
    name        text       not null,
    created_at  timestamp  not null,
    deleted_at  timestamp,
    untyped,
    age         int,
    gen                    not null generated always as (name + " " + age) virtual,
    primary key (uid),
    foreign key (uid) references other_table(uid) on delete cascade on update cascade
) without rowid;
create unique index idx_name on MyTable(name);

func (*Table) FindColumn added in v0.3.0

func (t *Table) FindColumn(columnname string) (*Column, bool)

func (*Table) FindIndex added in v0.3.0

func (t *Table) FindIndex(indexname string) (*Index, bool)

func (*Table) IndexMapping added in v0.3.0

func (t *Table) IndexMapping() map[string]*Index

func (*Table) ValidateColumns

func (table *Table) ValidateColumns(names ...string) (validated []string, optmissing []string, missing ErrMissingColumns)

ValidateColumns checks table schema for presense of columns with the specified names. Column names prefixed with '?' are considered optional. Columns named as 'NULL' are passed through without validation.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL