tengo

package
v1.11.2 Latest Latest
Warning

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

Go to latest
Published: Apr 3, 2024 License: Apache-2.0 Imports: 32 Imported by: 0

Documentation

Overview

Package tengo (Go La Tengo) is a database automation library. In its current form, its functionality is focused on MySQL schema introspection and diff'ing. Future releases will add more general-purpose automation features.

Index

Constants

This section is empty.

Variables

View Source
var (
	LatestMySQLVersion   = Version{8, 3}
	LatestMariaDBVersion = Version{11, 3}
)

Variables representing the latest major.minor releases of MySQL and MariaDB at the time of this release. These intentionally exclude patch release numbers; corresponding logic handles this appropriately.

View Source
var (
	OldestSupportedMySQLVersion   = Version{5, 5}
	OldestSupportedMariaDBVersion = Version{10, 1}
)

Variables representing the oldest major.minor releases of MySQL and MariaDB supported by this software. These intentionally exclude patch release numbers; corresponding logic handles this appropriately.

View Source
var ErrNoDockerCLI = errors.New("unable to find `docker` command-line client among directories in PATH")
View Source
var FlavorUnknown = Flavor{}

FlavorUnknown represents a flavor that cannot be parsed. This is the zero value for Flavor.

View Source
var IntrospectionBadSQLModes = sqlModeFilter{
	"ANSI":                     true,
	"ANSI_QUOTES":              true,
	"NO_FIELD_OPTIONS":         true,
	"NO_KEY_OPTIONS":           true,
	"NO_TABLE_OPTIONS":         true,
	"IGNORE_BAD_TABLE_OPTIONS": true,
}

IntrospectionBadSQLModes indicates which sql_mode values are problematic for schema introspection purposes.

View Source
var NonPortableSQLModes = sqlModeFilter{
	"NO_AUTO_CREATE_USER": true,
	"NO_FIELD_OPTIONS":    true,
	"NO_KEY_OPTIONS":      true,
	"NO_TABLE_OPTIONS":    true,
	"DB2":                 true,
	"MAXDB":               true,
	"MSSQL":               true,
	"MYSQL323":            true,
	"MYSQL40":             true,
	"ORACLE":              true,
	"POSTGRESQL":          true,

	"TIME_TRUNCATE_FRACTIONAL": true,

	"IGNORE_BAD_TABLE_OPTIONS": true,
	"EMPTY_STRING_IS_NULL":     true,
	"SIMULTANEOUS_ASSIGNMENT":  true,
	"TIME_ROUND_FRACTIONAL":    true,
}

NonPortableSQLModes indicates which sql_mode values are not available in all flavors.

Functions

func ContainerNameForImage

func ContainerNameForImage(image string) string

ContainerNameForImage returns a usable container name (or portion of a name) based on the supplied image name.

func DockerEngineArchitecture added in v1.11.0

func DockerEngineArchitecture() (string, error)

DockerEngineArchitecture returns the architecture of the Docker engine's server, with values like those of runtime.GOARCH. The result is typically the same as runtime.GOARCH in most situations, but may differ from GOARCH if e.g. running an amd64 Skeema binary on Apple Silicon via Rosetta 2.

func EscapeIdentifier

func EscapeIdentifier(input string) string

EscapeIdentifier is for use in safely escaping MySQL identifiers (table names, column names, etc). It doubles any backticks already present in the input string, and then returns the string wrapped in outer backticks.

func EscapeValueForCreateTable

func EscapeValueForCreateTable(input string) string

EscapeValueForCreateTable returns the supplied value (typically obtained from querying an information_schema table) escaped in the same manner as SHOW CREATE TABLE would display it. Examples include default values, table comments, column comments, index comments.

func FilterSQLMode added in v1.11.2

func FilterSQLMode(orig string, remove sqlModeFilter) string

FilterSQLMode splits the supplied comma-separated orig sql_mode value and filters out any sql_mode values which map to true values in the supplied sqlModeFilter mapping.

func IsAccessError

func IsAccessError(err error) bool

IsAccessError returns true if err indicates an authentication or authorization problem, at connection time or query time. Can be a problem with credentials, client host, no access to requested default database, missing privilege, etc. There is no sense in immediately retrying the connection or query when encountering this type of error.

func IsDatabaseError

func IsDatabaseError(err error, specificErrors ...uint16) bool

IsDatabaseError returns true if err came from a database server, typically as a response to a query or connection attempt. If one or more specificErrors are supplied, IsDatabaseError only returns true if the database error code matched one of those numbers.

func IsReservedWord added in v1.10.0

func IsReservedWord(word string, flavor Flavor) bool

IsReservedWord returns true if word is a reserved word in flavor, or false otherwise. This result is only designed to be accurate in common situations, and does not necessarily account for changes in specific point releases (especially pre-GA ones), special sql_mode values like MariaDB's ORACLE mode support, or flavors that this package does not support.

func IsSyntaxError

func IsSyntaxError(err error) bool

IsSyntaxError returns true if err is a SQL syntax error, or false otherwise.

func IsUnsafeDiff added in v1.11.0

func IsUnsafeDiff(err error) bool

IsUnsafeDiff returns true if err represents an "unsafe" alteration that has not explicitly been permitted by the supplied StatementModifiers.

func IsUnsupportedDiff

func IsUnsupportedDiff(err error) bool

IsUnsupportedDiff returns true if err represents an object that cannot be diff'ed due to use of features not supported by this package.

func IsVendorReservedWord added in v1.10.0

func IsVendorReservedWord(word string, vendor Vendor) bool

IsVendorReservedWord returns true if word is a reserved word in ANY version of vendor, or false otherwise.

func MergeParamStrings added in v1.10.1

func MergeParamStrings(params ...string) string

MergeParamStrings combines any number of query-string-style formatted DB connection parameter strings. In case of conflicts for any given parameter, values from later args override earlier args. This is inefficient and should be avoided in hot paths; eventually we will move away from DSNs and use Connectors instead, which will remove the need for this logic.

func NormalizeCreateOptions

func NormalizeCreateOptions(createStmt string) string

NormalizeCreateOptions adjusts the supplied CREATE TABLE statement to remove any no-op table options that are persisted in SHOW CREATE TABLE, but not reflected in information_schema and serve no purpose for InnoDB tables. This function is not guaranteed to be safe for non-InnoDB tables.

func ParseCreateAutoInc

func ParseCreateAutoInc(createStmt string) (string, uint64)

ParseCreateAutoInc parses a CREATE TABLE statement, formatted in the same manner as SHOW CREATE TABLE, and removes the table-level next-auto-increment clause if present. The modified CREATE TABLE will be returned, along with the next auto-increment value if one was found.

func ParseCreatePartitioning

func ParseCreatePartitioning(createStmt string) (base, partitionClause string)

ParseCreatePartitioning parses a CREATE TABLE statement, formatted in the same manner as SHOW CREATE TABLE, and splits out the base CREATE clauses from the partioning clause.

func ParseCreateTablespace added in v1.8.1

func ParseCreateTablespace(createStmt string) string

ParseCreateTablespace parses a TABLESPACE clause out of a CREATE TABLE statement.

func ReservedWordMap added in v1.10.0

func ReservedWordMap(flavor Flavor) map[string]bool

ReservedWordMap returns a map which can be used for looking up whether a given word is a reserved word in the supplied flavor. Keys in the map are all lowercase. If called repeatedly on the same flavor, a reference to the same underlying map will be returned each time. The caller should not modify this map. The returned map is only designed to be accurate in common situations, and does not necessarily account for changes in specific point releases (especially pre-GA ones), special sql_mode values like MariaDB's ORACLE mode support, or flavors that this package does not support.

func RunSuite

func RunSuite(suite IntegrationTestSuite, t *testing.T, backends []string)

RunSuite runs all test methods in the supplied suite once per backend. It calls suite.Setup(backend) once per backend, then iterates through all Test methods in suite. For each test method, suite.BeforeTest will be run, followed by the test itself. Finally, suite.Teardown(backend) will be run. Backends are just strings, and may contain docker image names or any other string representation that the test suite understands.

func SkeemaTestImages added in v1.11.0

func SkeemaTestImages(t *testing.T) []string

SkeemaTestImages examines the SKEEMA_TEST_IMAGES env variable (which should be set to a comma-separated list of Docker images) and returns a slice of strings. It may perform some conversions in the process, if the configured images are only available from non-Dockerhub locations. If no images are configured, the test will be marked as skipped. If any configured images are known to be unavailable for the system's architecture, the test is marked as failed.

func SplitHostOptionalPort

func SplitHostOptionalPort(hostaddr string) (string, int, error)

SplitHostOptionalPort takes an address string containing a hostname, ipv4 addr, or ipv6 addr; *optionally* followed by a colon and port number. It splits the hostname portion from the port portion and returns them separately. If no port was present, 0 will be returned for that portion. If hostaddr contains an ipv6 address, the IP address portion must be wrapped in brackets on input, and the brackets will still be present on output.

func StripDisplayWidth

func StripDisplayWidth(colType string) (strippedType string, didStrip bool)

StripDisplayWidth examines the supplied column type, and removes its integer display width if it is either an int family type, or a YEAR(4) type. No change is made if the column type isn't one that has a notion of integer display width. Additionally, no change is made to tinyint(1) types, nor types with a zerofill modifier, as per handling in MySQL 8.0.19.

func UseFilteredDriverLogger

func UseFilteredDriverLogger()

UseFilteredDriverLogger overrides the mysql driver's logger to avoid excessive messages. This suppresses the driver's "unexpected EOF" output, which occurs when an initial connection is refused or a connection drops early. This excessive logging can occur whenever DockerClient.CreateInstance() or DockerClient.GetInstance() is waiting for the instance to finish starting.

func VendorReservedWordMap added in v1.10.0

func VendorReservedWordMap(vendor Vendor) map[string]bool

VendorReservedWordMap returns a map containing all reserved words in any version of the supplied vendor. For additional documentation on the returned map, see ReservedWordMap.

Types

type AddCheck

type AddCheck struct {
	Check *Check
	// contains filtered or unexported fields
}

AddCheck represents a new check constraint that is present on the right-side ("to") schema version of the table, but not the left-side ("from") version. It satisfies the TableAlterClause interface.

func (AddCheck) Clause

func (acc AddCheck) Clause(mods StatementModifiers) string

Clause returns an ADD CONSTRAINT ... CHECK clause of an ALTER TABLE statement.

type AddColumn

type AddColumn struct {
	Table         *Table
	Column        *Column
	PositionFirst bool
	PositionAfter *Column
}

AddColumn represents a new column that is present on the right-side ("to") schema version of the table, but not the left-side ("from") version. It satisfies the TableAlterClause interface.

func (AddColumn) Clause

func (ac AddColumn) Clause(mods StatementModifiers) string

Clause returns an ADD COLUMN clause of an ALTER TABLE statement.

type AddForeignKey

type AddForeignKey struct {
	ForeignKey *ForeignKey
	// contains filtered or unexported fields
}

AddForeignKey represents a new foreign key that is present on the right-side ("to") schema version of the table, but not the left-side ("from") version. It satisfies the TableAlterClause interface.

func (AddForeignKey) Clause

func (afk AddForeignKey) Clause(mods StatementModifiers) string

Clause returns an ADD CONSTRAINT ... FOREIGN KEY clause of an ALTER TABLE statement.

type AddIndex

type AddIndex struct {
	Index *Index
	// contains filtered or unexported fields
}

AddIndex represents an index that is present on the right-side ("to") schema version of the table, but was not identically present on the left- side ("from") version. It satisfies the TableAlterClause interface.

func (AddIndex) Clause

func (ai AddIndex) Clause(mods StatementModifiers) string

Clause returns an ADD KEY clause of an ALTER TABLE statement.

type AlterCheck

type AlterCheck struct {
	Check          *Check
	NewEnforcement bool
}

AlterCheck represents a change in a check's enforcement status in MySQL 8+. It satisfies the TableAlterClause interface.

func (AlterCheck) Clause

func (alcc AlterCheck) Clause(mods StatementModifiers) string

Clause returns an ALTER CHECK clause of an ALTER TABLE statement.

type AlterIndex

type AlterIndex struct {
	Index        *Index
	NewInvisible bool // true if index is being changed from visible to invisible
	// contains filtered or unexported fields
}

AlterIndex represents a change in an index's visibility in MySQL 8+ or MariaDB 10.6+.

func (AlterIndex) Clause

func (ai AlterIndex) Clause(mods StatementModifiers) string

Clause returns an ALTER INDEX clause of an ALTER TABLE statement. It will be suppressed if the flavor does not support invisible/ignored indexes, and/or if the statement modifiers are respecting exact index order (in which case this ALTER TABLE will also have DROP and re-ADD clauses for this index, which prevents use of an ALTER INDEX clause.)

type BulkDropOptions

type BulkDropOptions struct {
	OnlyIfEmpty     bool    // If true, when dropping tables, error if any have rows
	MaxConcurrency  int     // Max objects to drop at once
	SkipBinlog      bool    // If true, use session sql_log_bin=0 (requires superuser)
	PartitionsFirst bool    // If true, drop RANGE/LIST partitioned tables one partition at a time
	LockWaitTimeout int     // If greater than 0, limit how long to wait for metadata locks (in seconds)
	Schema          *Schema // If non-nil, obtain object lists from Schema instead of running I_S queries
}

BulkDropOptions controls how objects are dropped in bulk.

func (BulkDropOptions) Concurrency

func (opts BulkDropOptions) Concurrency() int

Concurrency returns the concurrency, with a minimum value of 1.

type ChangeAutoIncrement

type ChangeAutoIncrement struct {
	OldNextAutoIncrement uint64
	NewNextAutoIncrement uint64
}

ChangeAutoIncrement represents a difference in next-auto-increment value between two versions of a table. It satisfies the TableAlterClause interface.

func (ChangeAutoIncrement) Clause

Clause returns an AUTO_INCREMENT clause of an ALTER TABLE statement.

type ChangeCharSet

type ChangeCharSet struct {
	FromCharSet   string
	FromCollation string
	ToCharSet     string
	ToCollation   string
}

ChangeCharSet represents a difference in default character set and/or collation between two versions of a table. It satisfies the TableAlterClause interface.

func (ChangeCharSet) Clause

func (ccs ChangeCharSet) Clause(_ StatementModifiers) string

Clause returns a DEFAULT CHARACTER SET clause of an ALTER TABLE statement.

type ChangeComment

type ChangeComment struct {
	NewComment string
}

ChangeComment represents a difference in the table-level comment between two versions of a table. It satisfies the TableAlterClause interface.

func (ChangeComment) Clause

Clause returns a clause of an ALTER TABLE statement that changes a table's comment.

type ChangeCreateOptions

type ChangeCreateOptions struct {
	OldCreateOptions string
	NewCreateOptions string
}

ChangeCreateOptions represents a difference in the create options (row_format, stats_persistent, stats_auto_recalc, etc) between two versions of a table. It satisfies the TableAlterClause interface.

func (ChangeCreateOptions) Clause

Clause returns a clause of an ALTER TABLE statement that sets one or more create options.

type ChangeStorageEngine

type ChangeStorageEngine struct {
	NewStorageEngine string
}

ChangeStorageEngine represents a difference in the table's storage engine. It satisfies the TableAlterClause interface. Please note that Go La Tengo's support for non-InnoDB storage engines is currently very limited, however it still provides the ability to generate ALTERs that change engine.

func (ChangeStorageEngine) Clause

Clause returns a clause of an ALTER TABLE statement that changes a table's storage engine.

func (ChangeStorageEngine) Unsafe

func (cse ChangeStorageEngine) Unsafe(_ StatementModifiers) (unsafe bool, reason string)

Unsafe returns true if this clause is potentially destructive of data. ChangeStorageEngine is always considered unsafe, due to the potential complexity in converting a table's data to the new storage engine.

type ChangeTablespace added in v1.8.1

type ChangeTablespace struct {
	NewTablespace string
}

ChangeTablespace represents a difference in the table's TABLESPACE clause between two versions of a table. It satisfies the TableAlterClause interface.

func (ChangeTablespace) Clause added in v1.8.1

Clause returns a clause of an ALTER TABLE statement that changes a table's tablespace.

type Check

type Check struct {
	Name     string `json:"name"`
	Clause   string `json:"clause"`
	Enforced bool   `json:"enforced"` // Always true in MariaDB
}

Check represents a single check constraint in a table.

func (*Check) Definition

func (cc *Check) Definition(flavor Flavor) string

Definition returns this Check's definition clause, for use as part of a DDL statement.

type Column

type Column struct {
	Name                string `json:"name"`
	TypeInDB            string `json:"type"`
	Nullable            bool   `json:"nullable,omitempty"`
	AutoIncrement       bool   `json:"autoIncrement,omitempty"`
	Default             string `json:"default,omitempty"` // Stored as an expression, i.e. quote-wrapped if string
	OnUpdate            string `json:"onUpdate,omitempty"`
	GenerationExpr      string `json:"generationExpression,omitempty"` // Only populated if generated column
	Virtual             bool   `json:"virtual,omitempty"`
	CharSet             string `json:"charSet,omitempty"`       // Only populated if textual type
	Collation           string `json:"collation,omitempty"`     // Only populated if textual type
	ShowCharSet         bool   `json:"showCharSet,omitempty"`   // Include CHARACTER SET in SHOW CREATE TABLE: always true if different than table default, sometimes true in other cases
	ShowCollation       bool   `json:"showCollation,omitempty"` // Include COLLATE in SHOW CREATE TABLE: logic differs by flavor
	Compression         string `json:"compression,omitempty"`   // Only non-empty if using column compression in Percona Server or MariaDB
	Comment             string `json:"comment,omitempty"`
	Invisible           bool   `json:"invisible,omitempty"` // True if an invisible column (MariaDB 10.3+, MySQL 8.0.23+)
	CheckClause         string `json:"check,omitempty"`     // Only non-empty for MariaDB inline check constraint clause
	SpatialReferenceID  uint32 `json:"srid,omitempty"`      // Can be non-zero only for spatial types in MySQL 8+
	HasSpatialReference bool   `json:"has_srid,omitempty"`  // True if SRID attribute present; disambiguates SRID 0 vs no SRID
}

Column represents a single column of a table.

func (*Column) Definition

func (c *Column) Definition(flavor Flavor) string

Definition returns this column's definition clause, for use as part of a DDL statement.

func (*Column) Equals

func (c *Column) Equals(other *Column) bool

Equals returns true if two columns are identical, false otherwise.

func (*Column) Equivalent added in v1.7.1

func (c *Column) Equivalent(other *Column) bool

Equivalent returns true if two columns are equal, or only differ in cosmetic/ non-functional ways. Cosmetic differences can come about in MySQL 8 when a column was created with CHARACTER SET or COLLATION clauses that are unnecessary (equal to table's default); or when comparing a table across different versions of MySQL 8 (one which supports int display widths, and one that removes them). Note that, for the purposes of this method, column comments are NOT considered cosmetic. This method returns false if c and other only differ by a comment.

type Compounder added in v1.10.0

type Compounder interface {
	IsCompoundStatement() bool
}

Compounder is implemented by types that have the ability to represent compound statements, requiring special delimiter handling.

type DatabaseDiff

type DatabaseDiff struct {
	From *Schema
	To   *Schema
}

DatabaseDiff represents differences of schema characteristics (default character set or default collation), or a difference in the existence of the the schema.

func (*DatabaseDiff) DiffType

func (dd *DatabaseDiff) DiffType() DiffType

DiffType returns the type of diff operation.

func (*DatabaseDiff) ObjectKey

func (dd *DatabaseDiff) ObjectKey() ObjectKey

ObjectKey returns a value representing the type and name of the schema being diff'ed. The name will be the From side schema, unless it is nil (CREATE DATABASE), in which case the To side schema name is returned.

func (*DatabaseDiff) Statement

func (dd *DatabaseDiff) Statement(_ StatementModifiers) (string, error)

Statement returns a DDL statement corresponding to the DatabaseDiff. A blank string may be returned if there is no statement to execute.

type DefKeyer added in v1.7.0

type DefKeyer interface {
	ObjectKeyer
	Def() string
}

DefKeyer is an interface that extends ObjectKeyer with an additional Def method, for returning a CREATE statement corresponding to the object. No guarantees are made as to whether this corresponds to a normalized value obtained from SHOW CREATE, an imputed value based on a particular Flavor, or an arbitrarily-formatted CREATE obtained from some other source. This flexibility allows DefKeyer to be used for purposes beyond just representing live database objects.

type DiffType

type DiffType int

DiffType enumerates possible ways that two objects differ

const (
	DiffTypeNone DiffType = iota
	DiffTypeCreate
	DiffTypeDrop
	DiffTypeAlter
	DiffTypeRename
)

Constants representing the types of diff operations.

func (DiffType) String

func (dt DiffType) String() string

type DockerizedInstance

type DockerizedInstance struct {
	*Instance
	// contains filtered or unexported fields
}

DockerizedInstance is a database instance running in a local Docker container.

func CreateDockerizedInstance added in v1.11.0

func CreateDockerizedInstance(opts DockerizedInstanceOptions) (*DockerizedInstance, error)

CreateDockerizedInstance attempts to create a database instance inside a Docker container. Of the opts fields, only Image is mandatory. A connection pool will be established for the instance.

func GetDockerizedInstance added in v1.11.0

func GetDockerizedInstance(opts DockerizedInstanceOptions) (*DockerizedInstance, error)

GetInstance attempts to find an existing container with name equal to opts.Name. If the container is found, it will be started if not already running, and a connection pool will be established. If the container does not exist or cannot be started or connected to, a nil *DockerizedInstance and a non-nil error will be returned. If a non-blank opts.Image is supplied, and the existing container has a a different image, the instance's flavor will be examined as a fallback. If it also does not match the requested image, an error will be returned.

func GetOrCreateDockerizedInstance added in v1.11.0

func GetOrCreateDockerizedInstance(opts DockerizedInstanceOptions) (*DockerizedInstance, error)

GetOrCreateDockerizedInstance attempts to fetch an existing Docker container with name equal to opts.Name. If it exists and its image (or flavor) matches opts.Image, and there are no errors starting or connecting to the instance, it will be returned. If it exists but its image/flavor don't match, or it cannot be started or connected to, an error will be returned. If no container exists with this name, a new one will attempt to be created.

func (*DockerizedInstance) ContainerName added in v1.11.0

func (di *DockerizedInstance) ContainerName() string

ContainerName returns the DockerizedInstance's container name.

func (*DockerizedInstance) Destroy

func (di *DockerizedInstance) Destroy() error

Destroy stops and deletes the corresponding containerized mysql-server.

func (*DockerizedInstance) Exec added in v1.8.0

func (di *DockerizedInstance) Exec(cmd []string, stdin io.Reader) (stdoutStr string, stderrStr string, err error)

Exec executes the supplied command/args in the container, blocks until completion, and returns STDOUT and STDERR. An input stream may optionally be supplied for the exec's STDIN, or supply nil to use the parent process's STDIN and possibly allocate a TTY. If di.Instance.Password is non-blank, the $MYSQL_PWD env variable will be set to it automatically.

func (*DockerizedInstance) NukeData

func (di *DockerizedInstance) NukeData() error

NukeData drops all non-system schemas and tables in the containerized mysql-server, making it useful as a per-test cleanup method in implementations of IntegrationTestSuite.BeforeTest. This method should never be used on a "real" production database!

func (*DockerizedInstance) Port

func (di *DockerizedInstance) Port() int

Port returns the actual port number on localhost that maps to the container's internal port 3306.

func (*DockerizedInstance) PortMap added in v1.8.0

func (di *DockerizedInstance) PortMap(containerPort int) int

PortMap returns the port number on localhost that maps to the container's specified internal tcp port.

func (*DockerizedInstance) SourceSQL

func (di *DockerizedInstance) SourceSQL(filePaths ...string) (string, error)

SourceSQL reads the specified files and executes them sequentially against the containerized mysql-server. Each file should contain one or more valid SQL instructions, typically a mix of DML and/or DDL statements. This is useful as a per-test setup method in implementations of IntegrationTestSuite.BeforeTest.

func (*DockerizedInstance) Start

func (di *DockerizedInstance) Start() error

Start starts the corresponding containerized mysql-server. If it is not already running, an error will be returned if it cannot be started. If it is already running, nil will be returned.

func (*DockerizedInstance) Stop

func (di *DockerizedInstance) Stop() error

Stop halts the corresponding containerized mysql-server, but does not destroy the container. If the container was not already running, no error is returned.

func (*DockerizedInstance) String

func (di *DockerizedInstance) String() string

func (*DockerizedInstance) TryConnect

func (di *DockerizedInstance) TryConnect() (err error)

TryConnect sets up a connection pool to the containerized mysql-server, and tests connectivity. It returns an error if a connection cannot be established within 30 seconds.

type DockerizedInstanceOptions

type DockerizedInstanceOptions struct {
	Name              string // Name for new container, or look up existing container by name
	Image             string // Image for new container, or verify flavor of existing container
	RootPassword      string // Root password for new instance, or for connecting to existing instance
	DefaultConnParams string // Options formatted as URL query string, used for conns to new or existing instance

	// Options that only affect new container creation:
	DataBindMount       string // Host path to bind-mount as /var/lib/mysql in container
	DataTmpfs           bool   // Use tmpfs for /var/lib/mysql. Only used if no DataBindMount, runtime.GOOS is Linux, and image is from a top-level repo (e.g. "foo" but not "foo/bar")
	EnableBinlog        bool   // Enable or disable binary log in database server
	LowerCaseTableNames uint8  // lower_case_table_names setting (0, 1, or 2) in database server
}

DockerizedInstanceOptions specifies options for creating or finding a sandboxed database instance inside a Docker container.

type DropCheck

type DropCheck struct {
	Check *Check
	// contains filtered or unexported fields
}

DropCheck represents a check constraint that was present on the left-side ("from") schema version of the table, but not the right-side ("to") version. It satisfies the TableAlterClause interface.

func (DropCheck) Clause

func (dcc DropCheck) Clause(mods StatementModifiers) string

Clause returns a DROP CHECK or DROP CONSTRAINT clause of an ALTER TABLE statement, depending on the flavor.

type DropColumn

type DropColumn struct {
	Column *Column
}

DropColumn represents a column that was present on the left-side ("from") schema version of the table, but not the right-side ("to") version. It satisfies the TableAlterClause interface.

func (DropColumn) Clause

func (dc DropColumn) Clause(_ StatementModifiers) string

Clause returns a DROP COLUMN clause of an ALTER TABLE statement.

func (DropColumn) Unsafe

func (dc DropColumn) Unsafe(_ StatementModifiers) (unsafe bool, reason string)

Unsafe returns true if this clause is potentially destructive of data. DropColumn is always unsafe, unless it's a virtual column (which is easy to roll back; there's no inherent data loss from dropping a virtual column).

type DropForeignKey

type DropForeignKey struct {
	ForeignKey *ForeignKey
	// contains filtered or unexported fields
}

DropForeignKey represents a foreign key that was present on the left-side ("from") schema version of the table, but not the right-side ("to") version. It satisfies the TableAlterClause interface.

func (DropForeignKey) Clause

func (dfk DropForeignKey) Clause(mods StatementModifiers) string

Clause returns a DROP FOREIGN KEY clause of an ALTER TABLE statement.

type DropIndex

type DropIndex struct {
	Index *Index
	// contains filtered or unexported fields
}

DropIndex represents an index that was present on the left-side ("from") schema version of the table, but not identically present the right-side ("to") version. It satisfies the TableAlterClause interface.

func (DropIndex) Clause

func (di DropIndex) Clause(mods StatementModifiers) string

Clause returns a DROP KEY clause of an ALTER TABLE statement.

type Flavor

type Flavor struct {
	Vendor   Vendor
	Version  Version
	Variants Variant // bit set of |'ed together Variant flags
}

Flavor represents a database server release, consisting of a vendor, a version, and optionally some variant flags.

func IdentifyFlavor added in v1.7.1

func IdentifyFlavor(versionString, versionComment string) (flavor Flavor)

IdentifyFlavor returns a Flavor value based on inputs obtained from server vars @@global.version and @@global.version_comment. It accounts for how some distributions and/or cloud platforms manipulate those values. This method can detect VariantPercona (and will include it in the return value appropriately), but not VariantAurora.

func ParseFlavor

func ParseFlavor(s string) Flavor

ParseFlavor returns a Flavor value based on the supplied string in format "base:major.minor" or "base:major.minor.patch". The base should correspond to either a stringified Vendor constant or to a stringified Variant constant.

func (Flavor) AlwaysShowCollate added in v1.9.0

func (fl Flavor) AlwaysShowCollate() bool

AlwaysShowCollate returns true if the flavor always puts a COLLATE clause after a CHARACTER SET clause in SHOW CREATE TABLE, for columns as well as the table default. This is true in MariaDB versions released Nov 2022 onwards. Reference: https://jira.mariadb.org/browse/MDEV-29446

func (Flavor) Family

func (fl Flavor) Family() Flavor

Family returns a copy of the receiver with a zeroed-out patch version.

func (Flavor) GeneratedColumns

func (fl Flavor) GeneratedColumns() bool

GeneratedColumns returns true if the flavor supports generated columns using MySQL's native syntax. (Although MariaDB 10.1 has support for generated columns, its syntax is borrowed from other DBMS, so false is returned.)

func (Flavor) HasCheckConstraints

func (fl Flavor) HasCheckConstraints() bool

HasCheckConstraints returns true if the flavor supports check constraints and exposes them in information_schema.

func (Flavor) HasVariant added in v1.7.1

func (fl Flavor) HasVariant(variant Variant) bool

HasVariant returns true if the supplied Variant flag(s) (a single Variant or multiple Variants bitwise-OR'ed together) are all present in the Flavor.

func (Flavor) IsAurora added in v1.11.2

func (fl Flavor) IsAurora(versionParts ...uint16) bool

IsAurora behaves like IsMySQL, with an additional check for VariantAurora.

func (Flavor) IsMariaDB added in v1.7.1

func (fl Flavor) IsMariaDB(versionParts ...uint16) bool

IsMariaDB returns true if the receiver's Vendor is VendorMariaDB and its Version matches any supplied args. Supply 0 args to only check Vendor. Supply 1 arg to check Vendor and major version, 2 args for Vendor and major and minor versions, or 3 args for Vendor and exact major/minor/patch.

func (Flavor) IsMySQL added in v1.7.1

func (fl Flavor) IsMySQL(versionParts ...uint16) bool

IsMySQL returns true if the receiver's Vendor is VendorMySQL and its Version matches any supplied args. Supply 0 args to only check Vendor. Supply 1 arg to check Vendor and major version, 2 args for Vendor and major and minor versions, or 3 args for Vendor and exact major/minor/patch.

func (Flavor) IsPercona added in v1.11.2

func (fl Flavor) IsPercona(versionParts ...uint16) bool

IsPercona behaves like IsMySQL, with an additional check for VariantPercona.

func (Flavor) Known

func (fl Flavor) Known() bool

Known returns true if both the vendor and major version of this flavor were parsed properly, and the version isn't lower than the minimum supported by this package.

func (Flavor) MinMariaDB added in v1.11.2

func (fl Flavor) MinMariaDB(versionParts ...uint16) bool

MinMariaDB returns true if the receiver's Vendor is VendorMariaDB, and the receiver's version is equal to or greater than the supplied version numbers. Supply 1 arg to compare only major version, 2 args to compare major and minor, or 3 args to compare major, minor, and patch. Extra args beyond 3 are silently ignored.

func (Flavor) MinMySQL added in v1.11.2

func (fl Flavor) MinMySQL(versionParts ...uint16) bool

MinMySQL returns true if the receiver's Vendor is VendorMySQL, and the receiver's version is equal to or greater than the supplied version numbers. Supply 1 arg to compare only major version, 2 args to compare major and minor, or 3 args to compare major, minor, and patch. Extra args beyond 3 are silently ignored.

func (Flavor) OmitIntDisplayWidth

func (fl Flavor) OmitIntDisplayWidth() bool

OmitIntDisplayWidth returns true if the flavor omits inclusion of display widths from column types in the int family, aside from special cases like tinyint(1).

func (Flavor) SortedForeignKeys

func (fl Flavor) SortedForeignKeys() bool

SortedForeignKeys returns true if the flavor sorts foreign keys lexicographically in SHOW CREATE TABLE.

func (Flavor) String

func (fl Flavor) String() string

func (Flavor) TooNew added in v1.11.2

func (fl Flavor) TooNew() bool

TooNew returns true if the flavor's major.minor version exceeds the highest- available supported version at the time of this software's release. If the vendor is unknown, this method always returns false.

type ForeignKey

type ForeignKey struct {
	Name                  string   `json:"name"`
	ColumnNames           []string `json:"columnNames"`
	ReferencedSchemaName  string   `json:"referencedSchemaName,omitempty"` // will be empty string if same schema
	ReferencedTableName   string   `json:"referencedTableName"`
	ReferencedColumnNames []string `json:"referencedColumnNames"` // slice length always identical to len(ColumnNames)
	UpdateRule            string   `json:"updateRule"`
	DeleteRule            string   `json:"deleteRule"`
}

ForeignKey represents a single foreign key constraint in a table. Note that the "referenced" side of the FK is tracked as strings, rather than *Schema, *Table, *[]Column to avoid potentially having to introspect multiple schemas in a particular order. Also, the referenced side is not gauranteed to exist, especially if foreign_key_checks=0 has been used at any point in the past.

func (*ForeignKey) Definition

func (fk *ForeignKey) Definition(flavor Flavor) string

Definition returns this ForeignKey's definition clause, for use as part of a DDL statement.

func (*ForeignKey) Equals

func (fk *ForeignKey) Equals(other *ForeignKey) bool

Equals returns true if two ForeignKeys are completely identical (even in terms of cosmetic differences), false otherwise.

func (*ForeignKey) Equivalent

func (fk *ForeignKey) Equivalent(other *ForeignKey) bool

Equivalent returns true if two ForeignKeys are functionally equivalent, regardless of whether or not they have the same names.

type Index

type Index struct {
	Name           string      `json:"name"`
	Parts          []IndexPart `json:"parts"`
	PrimaryKey     bool        `json:"primaryKey,omitempty"`
	Unique         bool        `json:"unique,omitempty"`
	Invisible      bool        `json:"invisible,omitempty"` // MySQL 8+, also used for MariaDB 10.6's IGNORED indexes
	Comment        string      `json:"comment,omitempty"`
	Type           string      `json:"type"`
	FullTextParser string      `json:"parser,omitempty"`
}

Index represents a single index (primary key, unique secondary index, or non- unique secondard index) in a table.

func (*Index) Definition

func (idx *Index) Definition(flavor Flavor) string

Definition returns this index's definition clause, for use as part of a DDL statement.

func (*Index) Equals

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

Equals returns true if two indexes are completely identical, false otherwise.

func (*Index) EqualsIgnoringVisibility

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

EqualsIgnoringVisibility returns true if two indexes are identical, or only differ in visibility.

func (*Index) Equivalent

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

Equivalent returns true if two Indexes are functionally equivalent, regardless of whether or not they have the same names, comments, or visibility.

func (*Index) Functional added in v1.7.0

func (idx *Index) Functional() bool

Functional returns true if at least one IndexPart in idx is an expression rather than a column.

func (*Index) RedundantTo

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

RedundantTo returns true if idx is equivalent to, or a strict subset of, other. Both idx and other should be indexes of the same table. A non-unique index is considered redundant to any other same-type index having the same (or more) columns in the same order, unless its parts have a greater column prefix length. A unique index can only be redundant to the primary key or an exactly equivalent unique index; another unique index with more cols may coexist due to the desired constraint semantics. A primary key is never redundant to another index.

type IndexPart

type IndexPart struct {
	ColumnName   string `json:"columnName,omitempty"`   // name of column, or empty if expression
	Expression   string `json:"expression,omitempty"`   // expression value (MySQL 8+), or empty if column
	PrefixLength uint16 `json:"prefixLength,omitempty"` // nonzero if only a prefix of column is indexed
	Descending   bool   `json:"descending,omitempty"`   // if true, collation is descending (MySQL 8+)
}

IndexPart represents an individual indexed column or expression. Each index has one or more IndexPart values.

func (*IndexPart) Definition

func (part *IndexPart) Definition(_ Flavor) string

Definition returns this index part's definition clause.

type Instance

type Instance struct {
	BaseDSN    string // DSN ending in trailing slash; i.e. no schema name or params
	Driver     string
	User       string
	Password   string
	Host       string
	Port       int
	SocketPath string
	// contains filtered or unexported fields
}

Instance represents a single database server running on a specific host or address.

func NewInstance

func NewInstance(driver, dsn string) (*Instance, error)

NewInstance returns a pointer to a new Instance corresponding to the supplied driver and dsn. Currently only "mysql" driver is supported. dsn should be formatted according to driver specifications. If it contains a schema name, it will be ignored. If it contains any params, they will be applied as default params to all connections (in addition to whatever is supplied in Connect).

func (*Instance) AlterSchema

func (instance *Instance) AlterSchema(schema string, opts SchemaCreationOptions) error

AlterSchema changes the character set and/or collation of the supplied schema on instance. Supply an empty string for opts.DefaultCharSet to only change the collation, or supply an empty string for opts.DefaultCollation to use the default collation of opts.DefaultCharSet. (Supplying an empty string for both is also allowed, but is a no-op.)

func (*Instance) BuildParamString added in v1.10.1

func (instance *Instance) BuildParamString(params string) string

BuildParamString returns a DB connection parameter string, which first takes the instance's default params and then applies overrides on top. The arg should be a URL query string formatted value, for example "foo=bar&fizz=buzz" to apply foo=bar and fizz=buzz on top of any instance default parameters.

func (*Instance) CachedConnectionPool

func (instance *Instance) CachedConnectionPool(defaultSchema, params string) (*sqlx.DB, error)

CachedConnectionPool operates like ConnectionPool, except it caches connection pools for reuse. When multiple requests are made for the same combination of defaultSchema and params, a pre-existing connection pool will be returned. See ConnectionPool for usage of the args for this method.

func (*Instance) CanConnect

func (instance *Instance) CanConnect() (bool, error)

CanConnect returns true if the Instance can currently be connected to, using its configured User and Password. If a new connection cannot be made, the return value will be false, along with an error expressing the reason.

func (*Instance) CanSkipBinlog

func (instance *Instance) CanSkipBinlog() bool

CanSkipBinlog returns true if instance.User has privileges necessary to set sql_log_bin=0. If an error occurs in checking grants, this method returns false as a safe fallback.

func (*Instance) CloseAll

func (instance *Instance) CloseAll()

CloseAll closes all of instance's cached connection pools. This can be useful for graceful shutdown, to avoid aborted-connection counters/logging in some versions of MySQL.

func (*Instance) ConnectionPool

func (instance *Instance) ConnectionPool(defaultSchema, params string) (*sqlx.DB, error)

ConnectionPool returns a new sqlx.DB for this instance's host/port/user/pass with the supplied default schema and params string. A connection attempt is made, and an error will be returned if connection fails. defaultSchema may be "" if it is not relevant. params should be supplied in format "foo=bar&fizz=buzz" with URL escaping already applied. Do not include a prefix of "?". params will be merged with instance.defaultParams, with params supplied here taking precedence. The connection pool's max size, max conn lifetime, and max idle time are all tuned automatically to intelligent defaults based on auto-discovered limits.

func (*Instance) CreateSchema

func (instance *Instance) CreateSchema(name string, opts SchemaCreationOptions) (*Schema, error)

CreateSchema creates a new database schema with the supplied name, and optionally the supplied default CharSet and Collation. (Leave these fields blank to use server defaults.)

func (*Instance) DefaultCharSetAndCollation

func (instance *Instance) DefaultCharSetAndCollation() (serverCharSet, serverCollation string, err error)

DefaultCharSetAndCollation returns the instance's default character set and collation.

func (*Instance) DropRoutinesInSchema

func (instance *Instance) DropRoutinesInSchema(schema string, opts BulkDropOptions) error

DropRoutinesInSchema drops all stored procedures and functions in a schema.

func (*Instance) DropSchema

func (instance *Instance) DropSchema(schema string, opts BulkDropOptions) error

DropSchema first drops all tables in the schema, and then drops the database schema itself. If opts.OnlyIfEmpty==true, returns an error if any of the tables have any rows.

func (*Instance) DropTablesInSchema

func (instance *Instance) DropTablesInSchema(schema string, opts BulkDropOptions) error

DropTablesInSchema drops all tables in a schema. If opts.OnlyIfEmpty==true, returns an error if any of the tables have any rows.

func (*Instance) Flavor

func (instance *Instance) Flavor() Flavor

Flavor returns this instance's flavor value, representing the database distribution/fork/vendor as well as major and minor version. If this is unable to be determined or an error occurs, FlavorUnknown will be returned.

func (*Instance) ForceFlavor

func (instance *Instance) ForceFlavor(flavor Flavor)

ForceFlavor overrides this instance's flavor value. Only tests should call this method directly; all other callers should use SetFlavor instead and check the error return value.

func (*Instance) HasSchema

func (instance *Instance) HasSchema(name string) (bool, error)

HasSchema returns true if this instance has a schema with the supplied name visible to the user, or false otherwise. An error result will only be returned if a connection or query failed entirely and we weren't able to determine whether the schema exists.

func (*Instance) LockWaitTimeout added in v1.8.2

func (instance *Instance) LockWaitTimeout() int

LockWaitTimeout returns the default session lock_wait_timeout for connections to this instance, or 0 if it could not be queried.

func (*Instance) NameCaseMode added in v1.8.0

func (instance *Instance) NameCaseMode() NameCaseMode

NameCaseMode returns a value reflecting this instance's lower_case_table_names, normally a value between 0 and 2 if successfully queryable.

func (*Instance) ProcessList added in v1.11.2

func (instance *Instance) ProcessList() (plist []ServerProcess, err error)

ProcessList returns the current list of connections on instance. This is primarily intended for debugging and test output at this time, and may be disruptive on live production database servers, especially on MySQL 8.0+.

func (*Instance) SQLMode added in v1.10.1

func (instance *Instance) SQLMode() string

SQLMode returns the full session-level sql_mode string for connections using default parameters, or a blank string if it could not be queried.

func (*Instance) Schema

func (instance *Instance) Schema(name string) (*Schema, error)

Schema returns a single schema by name. If the schema does not exist, nil will be returned along with a sql.ErrNoRows error.

func (*Instance) SchemaNames

func (instance *Instance) SchemaNames() ([]string, error)

SchemaNames returns a slice of all schema name strings on the instance visible to the user. System schemas are excluded.

func (*Instance) Schemas

func (instance *Instance) Schemas(onlyNames ...string) ([]*Schema, error)

Schemas returns a slice of schemas on the instance visible to the user. If called with no args, all non-system schemas will be returned. Or pass one or more schema names as args to filter the result to just those schemas. Note that the ordering of the resulting slice is not guaranteed.

func (*Instance) SchemasByName

func (instance *Instance) SchemasByName(onlyNames ...string) (map[string]*Schema, error)

SchemasByName returns a map of schema name string to *Schema. If called with no args, all non-system schemas will be returned. Or pass one or more schema names as args to filter the result to just those schemas.

func (*Instance) SetFlavor

func (instance *Instance) SetFlavor(flavor Flavor) error

SetFlavor attempts to set this instance's flavor value. If the instance's flavor has already been hydrated successfully, the value is not changed and an error is returned.

func (*Instance) ShowCreateTable

func (instance *Instance) ShowCreateTable(schema, table string) (string, error)

ShowCreateTable returns a string with a CREATE TABLE statement, representing how the instance views the specified table as having been created.

func (*Instance) String

func (instance *Instance) String() string

String for an instance returns a "host:port" string (or "localhost:/path/to/socket" if using UNIX domain socket)

func (*Instance) TableHasRows

func (instance *Instance) TableHasRows(schema, table string) (bool, error)

TableHasRows returns true if the table has at least one row. If an error occurs in querying, also returns true (along with the error) since a false positive is generally less dangerous in this case than a false negative.

func (*Instance) TableSize

func (instance *Instance) TableSize(schema, table string) (int64, error)

TableSize returns an estimate of the table's size on-disk, based on data in information_schema. If the table or schema does not exist on this instance, the error will be sql.ErrNoRows. Please note that use of innodb_stats_persistent may negatively impact the accuracy. For example, see https://bugs.mysql.com/bug.php?id=75428.

func (*Instance) Valid

func (instance *Instance) Valid() (bool, error)

Valid returns true if a successful connection can be made to the Instance, or if a successful connection has already been made previously. This method only returns false if no previous successful connection was ever made, and a new attempt to establish one fails.

type IntegrationTestSuite

type IntegrationTestSuite interface {
	Setup(backend string) error
	Teardown(backend string) error
	BeforeTest(backend string) error
}

IntegrationTestSuite is the interface for a suite of test methods. In addition to implementing the 3 methods of the interface, an integration test suite struct should have any number of test methods of form TestFoo(t *testing.T), which will be executed automatically by RunSuite.

type Lexer added in v1.10.0

type Lexer struct {
	// contains filtered or unexported fields
}

Lexer is a simple partial SQL lexical tokenizer. It intentionally does not aim to be a complete solution for use in fully parsing SQL. See comment at the top of parser.go for the purpose of this implementation.

func NewLexer added in v1.10.0

func NewLexer(r io.Reader, delimiter string, bufferSize int) *Lexer

NewLexer returns a lexer which reads from r. The supplied delimiter string will be used initially, but may be changed by calling ChangeDelimiter.

func (*Lexer) ChangeDelimiter added in v1.10.0

func (lex *Lexer) ChangeDelimiter(newDelimiter string)

ChangeDelimiter changes the lexer's delimiter string for all subsequent calls to Scan.

func (*Lexer) Delimiter added in v1.10.0

func (lex *Lexer) Delimiter() string

Delimiter returns the lexer's current delimiter string.

func (*Lexer) Scan added in v1.10.0

func (lex *Lexer) Scan() (data []byte, typ TokenType, err error)

Scan returns the next token data from the reader, returning the raw data and token type. If an error occurs mid-scan (*after* at least one rune was successfully read), it will be suppressed until the next call to Scan. In other words, if the returned data is non-nil, err will always be nil; and likewise if err is non-nil then data will be nil and typ will be TokenNone. Data returned by Scan() is only valid until the subsequent call to Scan().

func (*Lexer) ScanBOM added in v1.10.0

func (lex *Lexer) ScanBOM() bool

ScanBOM peeks at the next 3 bytes of the reader to see if they contain a UTF8 byte-order marker. This method should generally only be called on a new lexer prior to any other Scan().

type MalformedSQLError added in v1.10.0

type MalformedSQLError struct {
	// contains filtered or unexported fields
}

MalformedSQLError represents a fatal problem parsing or lexing SQL: the input contains an unterminated quote or unterminated multi-line comment.

func (*MalformedSQLError) Error added in v1.10.0

func (mse *MalformedSQLError) Error() string

Error satisfies the builtin error interface.

type ModifyColumn

type ModifyColumn struct {
	Table              *Table
	OldColumn          *Column
	NewColumn          *Column
	PositionFirst      bool
	PositionAfter      *Column
	InUniqueConstraint bool // true if column is part of a unique index (or PK) in both old and new version of table
}

ModifyColumn represents a column that exists in both versions of the table, but with a different definition. It satisfies the TableAlterClause interface.

func (ModifyColumn) Clause

func (mc ModifyColumn) Clause(mods StatementModifiers) string

Clause returns a MODIFY COLUMN clause of an ALTER TABLE statement.

func (ModifyColumn) Unsafe

func (mc ModifyColumn) Unsafe(mods StatementModifiers) (unsafe bool, reason string)

Unsafe returns true if this clause is potentially destroys/corrupts existing data, or restricts the range of data that may be stored. (Although the server can also catch the latter case and prevent the ALTER, this only happens if existing data conflicts *in a given environment*, and also depends on strict sql_mode being enabled.) ModifyColumn's safety depends on the nature of the column change; for example, increasing the size of a varchar is safe, but decreasing the size or (in most cases) changing the column type entirely is considered unsafe.

type ModifyPartitions

type ModifyPartitions struct {
	Add          []*Partition
	Drop         []*Partition
	ForDropTable bool
}

ModifyPartitions represents a change to the partition list for a table using RANGE, RANGE COLUMNS, LIST, or LIST COLUMNS partitioning. Generation of this clause is only partially supported at this time.

func (ModifyPartitions) Clause

func (mp ModifyPartitions) Clause(mods StatementModifiers) string

Clause currently returns an empty string when a partition list difference is present in a table that exists in both "from" and "to" sides of the diff; in that situation, ModifyPartitions is just used as a placeholder to indicate that a difference was detected. ModifyPartitions currently returns a non-empty clause string only for the use-case of dropping individual partitions before dropping a table entirely, which reduces the amount of time the dict_sys mutex is held when dropping the table.

func (ModifyPartitions) Unsafe

func (mp ModifyPartitions) Unsafe(_ StatementModifiers) (unsafe bool, reason string)

Unsafe returns true if this clause is potentially destructive of data.

type NameCaseMode added in v1.8.0

type NameCaseMode int

NameCaseMode represents different values of the lower_case_table_names read-only global server variable.

const (
	NameCaseUnknown     NameCaseMode = -1
	NameCaseAsIs        NameCaseMode = 0
	NameCaseLower       NameCaseMode = 1
	NameCaseInsensitive NameCaseMode = 2
)

Constants representing valid NameCaseMode values

type NextAutoIncMode

type NextAutoIncMode uint8

NextAutoIncMode enumerates various ways of handling AUTO_INCREMENT discrepancies between two tables.

const (
	NextAutoIncIgnore      NextAutoIncMode = iota // omit auto-inc value changes in diff
	NextAutoIncIfIncreased                        // only include auto-inc value if the "from" side is less than the "to" side
	NextAutoIncIfAlready                          // only include auto-inc value if the "from" side is already greater than 1
	NextAutoIncAlways                             // always include auto-inc value in diff
)

Constants for how to handle next-auto-inc values in table diffs. Usually these are ignored in diffs entirely, but in some cases they are included.

type ObjectDiff

type ObjectDiff interface {
	ObjectKeyer
	DiffType() DiffType
	Statement(StatementModifiers) (string, error)
}

ObjectDiff is an interface allowing generic handling of differences between two objects.

type ObjectKey

type ObjectKey struct {
	Type ObjectType
	Name string
}

ObjectKey is useful as a map key for indexing database objects within a single schema.

func (ObjectKey) ObjectKey added in v1.7.0

func (key ObjectKey) ObjectKey() ObjectKey

ObjectKey inception as a syntactic sugar hack: this allows keys to be passed directly for any arg expecting an ObjectKeyer interface.

func (ObjectKey) String

func (key ObjectKey) String() string

type ObjectKeyer added in v1.7.0

type ObjectKeyer interface {
	ObjectKey() ObjectKey
}

ObjectKeyer is an interface implemented by each type of database object, providing a generic way of obtaining an object's type and name.

type ObjectPattern added in v1.9.0

type ObjectPattern struct {
	Type    ObjectType
	Pattern *regexp.Regexp
}

ObjectPattern is a regular expression matched against an object name, but only for a specific object type.

func (*ObjectPattern) Match added in v1.9.0

func (p *ObjectPattern) Match(obj ObjectKeyer) bool

Match returns true if p's Type equals obj's ObjectKey.Type and p's Pattern matches obj's ObjectKey.Name.

func (*ObjectPattern) String added in v1.9.0

func (p *ObjectPattern) String() string

type ObjectType

type ObjectType string

ObjectType defines a class of object in a relational database system.

const (
	ObjectTypeNil      ObjectType = ""
	ObjectTypeDatabase ObjectType = "database"
	ObjectTypeTable    ObjectType = "table"
	ObjectTypeProc     ObjectType = "procedure"
	ObjectTypeFunc     ObjectType = "function"
)

Constants enumerating valid object types. Currently we do not define separate types for sub-types such as columns, indexes, foreign keys, etc as these are handled within the table logic.

func (ObjectType) Caps

func (ot ObjectType) Caps() string

Caps returns the object type as an uppercase string.

type Partition

type Partition struct {
	Name    string `json:"name"`
	SubName string `json:"subName,omitempty"` // empty string if no sub-partitioning; not fully supported yet
	Values  string `json:"values,omitempty"`  // only populated for RANGE or LIST
	Comment string `json:"comment,omitempty"`
	Engine  string `json:"engine"`
	DataDir string `json:"dataDir,omitempty"`
}

Partition stores information on a single partition.

func (*Partition) Definition

func (p *Partition) Definition(flavor Flavor, method string) string

Definition returns this partition's definition clause, for use as part of a DDL statement.

type PartitionBy

type PartitionBy struct {
	Partitioning *TablePartitioning
	RePartition  bool // true if changing partitioning on already-partitioned table
}

PartitionBy represents initially partitioning a previously-unpartitioned table, or changing the partitioning method and/or expression on an already- partitioned table. It satisfies the TableAlterClause interface.

func (PartitionBy) Clause

func (pb PartitionBy) Clause(mods StatementModifiers) string

Clause returns a clause of an ALTER TABLE statement that partitions a previously-unpartitioned table.

type PartitionListMode

type PartitionListMode string

PartitionListMode values control edge-cases for how the list of partitions is represented in SHOW CREATE TABLE.

const (
	PartitionListDefault  PartitionListMode = ""          // Default behavior based on partitioning method
	PartitionListExplicit PartitionListMode = "full"      // List each partition individually
	PartitionListCount    PartitionListMode = "countOnly" // Just use a count of partitions
	PartitionListNone     PartitionListMode = "omit"      // Omit partition list and count, implying just 1 partition
)

Constants enumerating valid PartitionListMode values.

type PartitioningMode

type PartitioningMode uint8

PartitioningMode enumerates ways of handling partitioning status -- that is, presence or lack of a PARTITION BY clause.

const (
	PartitioningPermissive PartitioningMode = iota // don't negate any partitioning-related clauses
	PartitioningRemove                             // negate PARTITION BY clauses from DDL
	PartitioningKeep                               // negate REMOVE PARTITIONING clauses from ALTERs
)

Constants for how to handle partitioning status differences.

type RemovePartitioning

type RemovePartitioning struct{}

RemovePartitioning represents de-partitioning a previously-partitioned table. It satisfies the TableAlterClause interface.

func (RemovePartitioning) Clause

Clause returns a clause of an ALTER TABLE statement that partitions a previously-unpartitioned table.

type RenameColumn

type RenameColumn struct {
	OldColumn *Column
	NewName   string
}

RenameColumn represents a column that exists in both versions of the table, but with a different name. It satisfies the TableAlterClause interface.

func (RenameColumn) Clause

func (rc RenameColumn) Clause(_ StatementModifiers) string

Clause returns a CHANGE COLUMN clause of an ALTER TABLE statement.

func (RenameColumn) Unsafe

func (rc RenameColumn) Unsafe(_ StatementModifiers) (unsafe bool, reason string)

Unsafe returns true if this clause is potentially destructive of data. RenameColumn is always considered unsafe, despite it not directly destroying data, because it is high-risk for interfering with application logic that may be continuing to use the old column name.

type Routine

type Routine struct {
	Name              string     `json:"name"`
	Type              ObjectType `json:"type"`                     // Will be ObjectTypeProcedure or ObjectTypeFunction
	Body              string     `json:"body"`                     // Has correct escaping despite I_S mutilating it
	ParamString       string     `json:"paramString"`              // Formatted as per original CREATE
	ReturnDataType    string     `json:"returnDataType,omitempty"` // Includes charset/collation when relevant
	Definer           string     `json:"definer"`
	DatabaseCollation string     `json:"dbCollation"` // from creation time
	Comment           string     `json:"comment,omitempty"`
	Deterministic     bool       `json:"deterministic,omitempty"`
	SQLDataAccess     string     `json:"sqlDataAccess,omitempty"`
	SecurityType      string     `json:"securityType"`
	SQLMode           string     `json:"sqlMode"`    // sql_mode in effect at creation time
	CreateStatement   string     `json:"showCreate"` // complete SHOW CREATE obtained from an instance
}

Routine represents a stored procedure or function.

func (*Routine) Def added in v1.7.0

func (r *Routine) Def() string

Def returns the routine's CREATE statement as a string.

func (*Routine) DefinerClause added in v1.7.0

func (r *Routine) DefinerClause() string

DefinerClause returns the routine's DEFINER, quoted/escaped in a way consistent with SHOW CREATE.

func (*Routine) Definition

func (r *Routine) Definition(flavor Flavor) string

Definition generates and returns a canonical CREATE PROCEDURE or CREATE FUNCTION statement based on the Routine's Go field values.

func (*Routine) DropStatement

func (r *Routine) DropStatement() string

DropStatement returns a SQL statement that, if run, would drop this routine.

func (*Routine) Equals

func (r *Routine) Equals(other *Routine) bool

Equals returns true if two routines are identical, false otherwise.

func (*Routine) ObjectKey added in v1.7.0

func (r *Routine) ObjectKey() ObjectKey

ObjectKey returns a value useful for uniquely refering to a Routine within a single Schema, for example as a map key.

type RoutineDiff

type RoutineDiff struct {
	Type DiffType
	From *Routine
	To   *Routine
}

RoutineDiff represents a difference between two routines. For diffs modifying an existing routine, if it is a characteristic-only change, this will be represented as a single RoutineDiff with DiffTypeAlter. Otherwise a modification including non-characteristic changes will be represented as two separate RoutineDiffs: one DiffTypeDrop and one DiffTypeCreate. This is needed to handle flavors which don't support CREATE OR REPLACE syntax. Flavors that *do* support CREATE OR REPLACE will simply blank-out the DROP portion of the pair.

func (*RoutineDiff) DiffType

func (rd *RoutineDiff) DiffType() DiffType

DiffType returns the type of diff operation.

func (*RoutineDiff) IsCompoundStatement added in v1.10.0

func (rd *RoutineDiff) IsCompoundStatement() bool

IsCompoundStatement returns true if the diff is a compound CREATE statement, requiring special delimiter handling.

func (*RoutineDiff) ObjectKey

func (rd *RoutineDiff) ObjectKey() ObjectKey

ObjectKey returns a value representing the type and name of the routine being diff'ed. The type will be either ObjectTypeFunc or ObjectTypeProc. The name will be the From side routine, unless this is a Create, in which case the To side routine name is used.

func (*RoutineDiff) Statement

func (rd *RoutineDiff) Statement(mods StatementModifiers) (stmt string, err error)

Statement returns the full DDL statement corresponding to the RoutineDiff. A blank string may be returned if the mods indicate the statement should be skipped. If the mods indicate the statement should be disallowed, it will still be returned as-is, but the error will be non-nil. Be sure not to ignore the error value of this method.

type Schema

type Schema struct {
	Name      string     `json:"databaseName"`
	CharSet   string     `json:"defaultCharSet"`
	Collation string     `json:"defaultCollation"`
	Tables    []*Table   `json:"tables,omitempty"`
	Routines  []*Routine `json:"routines,omitempty"`
}

Schema represents a database schema.

func (*Schema) AlterStatement

func (s *Schema) AlterStatement(charSet, collation string) string

AlterStatement returns a SQL statement that, if run, would alter this schema's default charset and/or collation to the supplied values. If charSet is "" and collation isn't, only the collation will be changed. If collation is "" and charSet isn't, the default collation for charSet is used automatically. If both params are "", or if values equal to the schema's current charSet and collation are supplied, an empty string is returned.

func (*Schema) CreateStatement

func (s *Schema) CreateStatement() string

CreateStatement returns a SQL statement that, if run, would create this schema.

func (*Schema) Def added in v1.7.0

func (s *Schema) Def() string

Def returns the schema's CREATE statement as a string.

func (*Schema) Diff

func (s *Schema) Diff(other *Schema) *SchemaDiff

Diff returns the set of differences between this schema and another schema.

func (*Schema) DropStatement

func (s *Schema) DropStatement() string

DropStatement returns a SQL statement that, if run, would drop this schema.

func (*Schema) FunctionsByName

func (s *Schema) FunctionsByName() map[string]*Routine

FunctionsByName returns a mapping of function names to Routine struct pointers, for all functions in the schema.

func (*Schema) HasTable

func (s *Schema) HasTable(name string) bool

HasTable returns true if a table with the given name exists in the schema. Callers should be careful to supply a name that takes into account the server's lower_case_table_names setting.

func (*Schema) ObjectKey added in v1.7.0

func (s *Schema) ObjectKey() ObjectKey

ObjectKey returns a value useful for uniquely refering to a Schema, for example as a map key.

func (*Schema) Objects added in v1.7.0

func (s *Schema) Objects() map[ObjectKey]DefKeyer

Objects returns DefKeyers for all objects in the schema, excluding the schema itself. The result is a map, keyed by ObjectKey (type+name).

func (*Schema) ProceduresByName

func (s *Schema) ProceduresByName() map[string]*Routine

ProceduresByName returns a mapping of stored procedure names to Routine struct pointers, for all stored procedures in the schema.

func (*Schema) StripMatches added in v1.9.0

func (s *Schema) StripMatches(removePatterns []ObjectPattern)

StripMatches removes objects from s if they match any supplied pattern. The in-memory representation of the schema is modified in-place. This does not affect any actual database instances.

func (*Schema) StripTablePartitioning added in v1.11.1

func (s *Schema) StripTablePartitioning(flavor Flavor)

StripTablePartitioning removes partitioning information from all Tables in s. This method only affects the in-memory representation of the schema; it does not actually execute DDL or make any change to a real database Instance.

func (*Schema) Table

func (s *Schema) Table(name string) *Table

Table returns a table by name. Callers should be careful to supply a name that takes into account the server's lower_case_table_names setting.

func (*Schema) TablesByName

func (s *Schema) TablesByName() map[string]*Table

TablesByName returns a mapping of table names to Table struct pointers, for all tables in the schema.

type SchemaCreationOptions

type SchemaCreationOptions struct {
	DefaultCharSet   string
	DefaultCollation string
	SkipBinlog       bool
}

SchemaCreationOptions specifies schema-level metadata when creating or altering a database.

type SchemaDiff

type SchemaDiff struct {
	FromSchema   *Schema
	ToSchema     *Schema
	TableDiffs   []*TableDiff   // a set of statements that, if run, would turn tables in FromSchema into ToSchema
	RoutineDiffs []*RoutineDiff // " but for funcs and procs
}

SchemaDiff represents a set of differences between two database schemas, encapsulating diffs of various different object types.

func NewSchemaDiff

func NewSchemaDiff(from, to *Schema) *SchemaDiff

NewSchemaDiff computes the set of differences between two database schemas.

func (*SchemaDiff) DatabaseDiff

func (sd *SchemaDiff) DatabaseDiff() *DatabaseDiff

DatabaseDiff returns an object representing database-level DDL (CREATE DATABASE, ALTER DATABASE, DROP DATABASE), or nil if no database-level DDL is necessary.

func (*SchemaDiff) ObjectDiffs

func (sd *SchemaDiff) ObjectDiffs() []ObjectDiff

ObjectDiffs returns a slice of all ObjectDiffs in the SchemaDiff. The results are returned in a sorted order, such that the diffs' Statements are legal. For example, if a CREATE DATABASE is present, it will occur in the slice prior to any table-level DDL in that schema.

func (*SchemaDiff) String

func (sd *SchemaDiff) String() string

String returns the set of differences between two schemas as a single string. In building this string representation, note that no statement modifiers are applied, and any errors from Statement() are ignored. This means the returned string may contain destructive statements, and should only be used for display purposes, not for DDL execution.

type ServerProcess added in v1.11.2

type ServerProcess struct {
	ID      int64
	User    string
	Schema  string
	Command string
	Time    float64
	State   string
	Info    string
}

ServerProcess describes the status of a connection on an Instance.

type Statement added in v1.10.0

type Statement struct {
	File            string
	LineNo          int
	CharNo          int
	Text            string // includes trailing Delimiter and newline
	DefaultDatabase string // only populated if an explicit USE command was encountered
	Type            StatementType
	ObjectType      ObjectType
	ObjectName      string
	ObjectQualifier string
	Delimiter       string // delimiter in use at the time of statement; not necessarily present in Text though
	Compound        bool   // if true, this is a compound statement (stored program with a BEGIN block, requiring alternative delimiter)
	// contains filtered or unexported fields
}

Statement represents a logical instruction in a file, consisting of either an SQL statement, a command (e.g. "USE some_database"), or whitespace and/or comments between two separate statements or commands.

func ParseStatementInString added in v1.10.0

func ParseStatementInString(s string) *Statement

ParseStatementInString returns the first Statement that can be found in its input. If the input is an empty string, and/or if an error occurs, then a zero-valued Statement will be returned, rather than a nil Statement. Note that the zero value of its Type field is StatementTypeUnknown. Since leading whitespace and/or comments are considered a separate "statement", be aware that this will mask any subsequent "real" statements later in the string. For situations that require a specific error value, or the ability to detect zero or 2+ statements in the input, use ParseStatementsInString instead. If the statement is a compound statement, the returned Statement.Delimiter will be a blank string; otherwise, it will be the default of ";".

func ParseStatements added in v1.10.0

func ParseStatements(r io.Reader, filePath string) (result []*Statement, err error)

ParseStatements splits the contents of the supplied io.Reader into distinct SQL statements. The filePath is descriptive and only used in error messages.

Statements preserve their whitespace and delimiters; the return value exactly represents the entire input. Some of the returned "statements" may just be comments and/or whitespace, since any comments and/or whitespace between SQL statements gets split into separate Statement values. Other "statements" are actually client commands (USE, DELIMITER).

func ParseStatementsInFile added in v1.10.0

func ParseStatementsInFile(filePath string) (result []*Statement, err error)

ParseStatementsInFile opens the file at filePath and then calls ParseStatements with it as the reader.

func ParseStatementsInString added in v1.10.0

func ParseStatementsInString(s string) (result []*Statement, err error)

ParseStatementsInString uses a strings.Reader to parse statements from the supplied string.

func (*Statement) Body added in v1.10.0

func (stmt *Statement) Body() string

Body returns the Statement's Text, without any trailing delimiter, whitespace, or qualified schema name.

func (*Statement) IsCompoundStatement added in v1.10.0

func (stmt *Statement) IsCompoundStatement() bool

IsCompoundStatement returns true if stmt is a compound statement.

func (*Statement) Location added in v1.10.0

func (stmt *Statement) Location() string

Location returns the file, line number, and character number where the statement was obtained from

func (*Statement) NormalizeTrailer added in v1.10.0

func (stmt *Statement) NormalizeTrailer()

NormalizeTrailer ensures the statement text ends in a delimiter (if required based on the statement type) and newline. This method modifies stmt in-place.

func (*Statement) ObjectKey added in v1.10.0

func (stmt *Statement) ObjectKey() ObjectKey

ObjectKey returns an ObjectKey for the object affected by this statement.

func (*Statement) Schema added in v1.10.0

func (stmt *Statement) Schema() string

Schema returns the schema name that this statement impacts.

func (*Statement) SplitTextBody added in v1.10.0

func (stmt *Statement) SplitTextBody() (body string, suffix string)

SplitTextBody returns Text with its trailing delimiter and whitespace (if any) separated out into a separate string.

type StatementModifiers

type StatementModifiers struct {
	NextAutoInc            NextAutoIncMode  // How to handle differences in next-auto-inc values
	Partitioning           PartitioningMode // How to handle differences in partitioning status
	AllowUnsafe            bool             // Whether to allow potentially-destructive DDL (drop table, drop column, modify col type, etc)
	LockClause             string           // Include a LOCK=[value] clause in generated ALTER TABLE
	AlgorithmClause        string           // Include an ALGORITHM=[value] clause in generated ALTER TABLE
	StrictIndexOrder       bool             // If true, maintain index order even in cases where there is no functional difference
	StrictCheckOrder       bool             // If true, maintain check constraint order even though it never has a functional difference (only affects MariaDB)
	StrictForeignKeyNaming bool             // If true, maintain foreign key definition even if differences are cosmetic (name change, RESTRICT vs NO ACTION, etc)
	StrictColumnDefinition bool             // If true, maintain column properties that are purely cosmetic (only affects MySQL 8)
	LaxColumnOrder         bool             // If true, don't modify columns if they only differ by position
	LaxComments            bool             // If true, don't modify tables/columns/indexes/routines if they only differ by comment clauses
	CompareMetadata        bool             // If true, compare creation-time sql_mode and db collation for funcs, procs (and eventually events, triggers)
	VirtualColValidation   bool             // If true, add WITH VALIDATION clause for ALTER TABLE affecting virtual columns
	SkipPreDropAlters      bool             // If true, skip ALTERs that were only generated to make DROP TABLE faster
	Flavor                 Flavor           // Adjust generated DDL to match vendor/version. Zero value is FlavorUnknown which makes no adjustments.
}

StatementModifiers are options that may be applied to adjust the DDL emitted for a particular table, and/or generate errors if certain clauses are present.

type StatementType added in v1.10.0

type StatementType int

StatementType indicates the type of a SQL statement found in a SQLFile. Parsing of types is very rudimentary, which can be advantageous for linting purposes. Otherwise, SQL errors or typos would prevent type detection.

const (
	StatementTypeUnknown StatementType = iota
	StatementTypeNoop                  // entirely whitespace and/or comments
	StatementTypeCommand               // currently just USE or DELIMITER
	StatementTypeCreate
	StatementTypeCreateUnsupported // edge cases like CREATE...SELECT
	StatementTypeAlter             // not actually ever parsed yet

)

Constants enumerating different types of statements

type Table

type Table struct {
	Name              string             `json:"name"`
	Engine            string             `json:"storageEngine"`
	CharSet           string             `json:"defaultCharSet"`
	Collation         string             `json:"defaultCollation"`
	ShowCollation     bool               `json:"showCollation,omitempty"` // Include default COLLATE in SHOW CREATE TABLE: logic differs by flavor
	CreateOptions     string             `json:"createOptions,omitempty"` // row_format, stats_persistent, stats_auto_recalc, etc
	Columns           []*Column          `json:"columns"`
	PrimaryKey        *Index             `json:"primaryKey,omitempty"`
	SecondaryIndexes  []*Index           `json:"secondaryIndexes,omitempty"`
	ForeignKeys       []*ForeignKey      `json:"foreignKeys,omitempty"`
	Checks            []*Check           `json:"checks,omitempty"`
	Comment           string             `json:"comment,omitempty"`
	Tablespace        string             `json:"tablespace,omitempty"`
	NextAutoIncrement uint64             `json:"nextAutoIncrement,omitempty"`
	Partitioning      *TablePartitioning `json:"partitioning,omitempty"`       // nil if table isn't partitioned
	UnsupportedDDL    bool               `json:"unsupportedForDiff,omitempty"` // If true, tengo cannot diff this table or auto-generate its CREATE TABLE
	CreateStatement   string             `json:"showCreateTable"`              // complete SHOW CREATE TABLE obtained from an instance
}

Table represents a single database table.

func (*Table) AlterStatement

func (t *Table) AlterStatement() string

AlterStatement returns the prefix to a SQL "ALTER TABLE" statement.

func (*Table) ClusteredIndexKey

func (t *Table) ClusteredIndexKey() *Index

ClusteredIndexKey returns which index is used for an InnoDB table's clustered index. This will be the primary key if one exists; otherwise, it will be the first unique key made of only non-nullable, non-expression columns. If there is no such key, or if the table's engine isn't InnoDB, this method returns nil.

func (*Table) ColumnsByName

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

ColumnsByName returns a mapping of column names to Column value pointers, for all columns in the table.

func (*Table) Def added in v1.7.0

func (t *Table) Def() string

Def returns the table's CREATE statement as a string.

func (*Table) Diff

func (t *Table) Diff(to *Table) (clauses []TableAlterClause, supported bool)

Diff returns a set of differences between this table and another table. Some edge cases are not supported, such as sub-partitioning, spatial indexes, MariaDB application time periods, or various non-InnoDB table features; in this case, supported will be false and clauses MAY OR MAY NOT be empty. Any returned clauses in that case must be carefully verified for correctness.

func (*Table) DropStatement

func (t *Table) DropStatement() string

DropStatement returns a SQL statement that, if run, would drop this table.

func (*Table) GeneratedCreateStatement

func (t *Table) GeneratedCreateStatement(flavor Flavor) string

GeneratedCreateStatement generates a CREATE TABLE statement based on the Table's Go field values. If t.UnsupportedDDL is false, this will match the output of MySQL's SHOW CREATE TABLE statement. But if t.UnsupportedDDL is true, this means the table uses MySQL features that Tengo does not yet support, and so the output of this method will differ from MySQL.

func (*Table) HasAutoIncrement

func (t *Table) HasAutoIncrement() bool

HasAutoIncrement returns true if the table contains an auto-increment column, or false otherwise.

func (*Table) ObjectKey added in v1.7.0

func (t *Table) ObjectKey() ObjectKey

ObjectKey returns a value useful for uniquely refering to a Table within a single Schema, for example as a map key.

func (*Table) RowFormatClause

func (t *Table) RowFormatClause() string

RowFormatClause returns the table's ROW_FORMAT clause, if one was explicitly specified in the table's creation options. If no ROW_FORMAT clause was specified, but a KEY_BLOCK_SIZE is, "COMPRESSED" will be returned since MySQL applies this automatically. If no ROW_FORMAT or KEY_BLOCK_SIZE was specified, a blank string is returned. This method does not query an instance to determine if the table's actual ROW_FORMAT differs from what was requested in creation options; nor does it query the default row format if none was specified.

func (*Table) SecondaryIndexesByName

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

SecondaryIndexesByName returns a mapping of index names to Index value pointers, for all secondary indexes in the table.

func (*Table) UniqueConstraintsWithColumn added in v1.11.0

func (t *Table) UniqueConstraintsWithColumn(col *Column) []*Index

UniqueConstraintsWithColumn returns a slice of Indexes which have uniqueness constraints (primary key or unique secondary index) and include col as one of the index parts. If col is not part of any uniqueness constraints, a nil slice is returned.

func (*Table) UnpartitionedCreateStatement

func (t *Table) UnpartitionedCreateStatement(flavor Flavor) string

UnpartitionedCreateStatement returns the table's CREATE statement without its PARTITION BY clause. Supplying an accurate flavor improves performance, but is not required; FlavorUnknown still works correctly.

type TableAlterClause

type TableAlterClause interface {
	Clause(StatementModifiers) string
}

TableAlterClause interface represents a specific single-element difference between two tables. Structs satisfying this interface can generate an ALTER TABLE clause, such as ADD COLUMN, MODIFY COLUMN, ADD KEY, etc.

type TableDiff

type TableDiff struct {
	Type DiffType
	From *Table
	To   *Table
	// contains filtered or unexported fields
}

TableDiff represents a difference between two tables.

func NewAlterTable

func NewAlterTable(from, to *Table) *TableDiff

NewAlterTable returns a *TableDiff representing an ALTER TABLE statement, i.e. a table that exists in the "from" and "to" side schemas but with one or more differences. If the supplied tables are identical, nil will be returned instead of a TableDiff.

func NewCreateTable

func NewCreateTable(table *Table) *TableDiff

NewCreateTable returns a *TableDiff representing a CREATE TABLE statement, i.e. a table that only exists in the "to" side schema in a diff.

func NewDropTable

func NewDropTable(table *Table) *TableDiff

NewDropTable returns a *TableDiff representing a DROP TABLE statement, i.e. a table that only exists in the "from" side schema in a diff.

func PreDropAlters

func PreDropAlters(table *Table) []*TableDiff

PreDropAlters returns a slice of *TableDiff to run prior to dropping a table. For tables partitioned with RANGE or LIST partitioning, this returns ALTERs to drop all partitions but one. In all other cases, this returns nil.

func (*TableDiff) Clauses

func (td *TableDiff) Clauses(mods StatementModifiers) (string, error)

Clauses returns the body of the statement represented by the table diff. For DROP statements, this will be an empty string. For CREATE statements, it will be everything after "CREATE TABLE [name] ". For ALTER statements, it will be everything after "ALTER TABLE [name] ".

func (*TableDiff) DiffType

func (td *TableDiff) DiffType() DiffType

DiffType returns the type of diff operation.

func (*TableDiff) MarkSupported added in v1.10.1

func (td *TableDiff) MarkSupported() error

MarkSupported provides a mechanism for callers to vouch for the correctness of a TableDiff that was automatically marked as unsupported. This should only be used in cases where a table with UnsupportedDDL is being altered in a way which either doesn't interact with the unsupported features, or easily removes those features. It is the caller's responsibility to first verify that the TableDiff's Statement() returns accurate, non-empty SQL.

func (*TableDiff) ObjectKey

func (td *TableDiff) ObjectKey() ObjectKey

ObjectKey returns a value representing the type and name of the table being diff'ed. The name will be the From side table, unless the diffType is DiffTypeCreate, in which case the To side table name is used.

func (*TableDiff) SplitAddForeignKeys

func (td *TableDiff) SplitAddForeignKeys() (*TableDiff, *TableDiff)

SplitAddForeignKeys looks through a TableDiff's alterClauses and pulls out any AddForeignKey clauses into a separate TableDiff. The first returned TableDiff is guaranteed to contain no AddForeignKey clauses, and the second returned value is guaranteed to only consist of AddForeignKey clauses. If the receiver contained no AddForeignKey clauses, the first return value will be the receiver, and the second will be nil. If the receiver contained only AddForeignKey clauses, the first return value will be nil, and the second will be the receiver. This method is useful for several reasons: it is desirable to only add FKs after other alters have been made (since FKs rely on indexes on both sides); it is illegal to drop and re-add an FK with the same name in the same ALTER; some versions of MySQL recommend against dropping and adding FKs in the same ALTER even if they have different names.

func (*TableDiff) SplitConflicts

func (td *TableDiff) SplitConflicts() (result []*TableDiff)

SplitConflicts looks through a TableDiff's alterClauses and pulls out any clauses that need to be placed into a separate TableDiff in order to yield legal or error-free DDL. Currently this only handles attempts to add multiple FULLTEXT indexes in a single ALTER, but may handle additional cases in the future. This method returns a slice of TableDiffs. The first element will be equivalent to the receiver (td) with any conflicting clauses removed; subsequent slice elements, if any, will be separate TableDiffs each consisting of individual conflicting clauses. This method does not interact with AddForeignKey clauses; see dedicated method SplitAddForeignKeys for that logic.

func (*TableDiff) Statement

func (td *TableDiff) Statement(mods StatementModifiers) (string, error)

Statement returns the full DDL statement corresponding to the TableDiff. A blank string may be returned if the mods indicate the statement should be skipped. If the mods indicate the statement should be disallowed, it will still be returned as-is, but the error will be non-nil. Be sure not to ignore the error value of this method.

type TablePartitioning

type TablePartitioning struct {
	Method             string            `json:"method"`              // one of "RANGE", "RANGE COLUMNS", "LIST", "LIST COLUMNS", "HASH", "LINEAR HASH", "KEY", or "LINEAR KEY"
	SubMethod          string            `json:"subMethod,omitempty"` // one of "" (no sub-partitioning), "HASH", "LINEAR HASH", "KEY", or "LINEAR KEY"; not fully supported yet
	Expression         string            `json:"expression"`
	SubExpression      string            `json:"subExpression,omitempty"` // empty string if no sub-partitioning; not fully supported yet
	Partitions         []*Partition      `json:"partitions"`
	ForcePartitionList PartitionListMode `json:"forcePartitionList,omitempty"`
	AlgoClause         string            `json:"algoClause,omitempty"` // full text of optional ALGORITHM clause for KEY or LINEAR KEY
}

TablePartitioning stores partitioning configuration for a partitioned table. Note that despite subpartitioning fields being present and possibly populated, the rest of this package does not fully support subpartitioning yet.

func (*TablePartitioning) Definition

func (tp *TablePartitioning) Definition(flavor Flavor) string

Definition returns the overall partitioning definition for a table.

func (*TablePartitioning) Diff

func (tp *TablePartitioning) Diff(other *TablePartitioning) (clauses []TableAlterClause, supported bool)

Diff returns a set of differences between this TablePartitioning and another TablePartitioning. If supported==true, the returned clauses (if executed) would transform tp into other.

type Token added in v1.10.0

type Token struct {
	// contains filtered or unexported fields
}

Token represents a lexical token in a .sql file.

type TokenType added in v1.10.0

type TokenType uint32

TokenType represents the category of a lexical token.

const (
	TokenNone       TokenType = iota // zero value for TokenType
	TokenWord                        // bare word, either a keyword or an unquoted identifier
	TokenIdent                       // backtick-wrapped identifier
	TokenString                      // string wrapped in either single quotes or double quotes
	TokenNumeric                     // int or float (unsigned; leading - will be treated as symbol by lexer)
	TokenSymbol                      // single operator or other symbol (always just one rune)
	TokenExtComment                  // C-style comment with contents beginning with !, +, or M! TODO not really handled well yet
	TokenDelimiter                   // token equal to current delimiter (whatever that happened to be)
	TokenFiller                      // mix of whitespaces and/or comments (other than tokenExtComment)
)

Constants enumerating TokenType values

type UnsafeDiffError added in v1.11.0

type UnsafeDiffError struct {
	Reason string
}

UnsafeDiffError can be returned by ObjectDiff.Statement when the supplied statement modifiers do not permit the generated ObjectDiff to be used in this situation.

func (*UnsafeDiffError) Error added in v1.11.0

func (e *UnsafeDiffError) Error() string

Error satisfies the builtin error interface.

type Unsafer

type Unsafer interface {
	Unsafe(StatementModifiers) (unsafe bool, reason string)
}

Unsafer interface represents a type of clause that may have the ability to destroy data. Structs satisfying this interface can indicate whether or not this particular clause is unsafe, and if so, the reason why. If a TableAlterClause struct does NOT implement this interface, it is considered to always be safe.

type UnsupportedDiffError

type UnsupportedDiffError struct {
	Reason         string
	ExpectedCreate string
	ExpectedDesc   string
	ActualCreate   string
	ActualDesc     string
	WrappedErr     error // either an UnsafeDiffError or nil
}

UnsupportedDiffError can be returned by ObjectDiff.Statement if Tengo is unable to transform the object due to use of unsupported features.

func (*UnsupportedDiffError) Error

func (e *UnsupportedDiffError) Error() string

Error returns a string with information about why the diff is not supported.

func (*UnsupportedDiffError) Unwrap added in v1.11.1

func (e *UnsupportedDiffError) Unwrap() error

Unwrap returns a wrapped error, if any was set.

type Variant added in v1.7.1

type Variant uint32

Variant represents a database product which tracks an upstream Vendor's codebase and versioning but adds a patch-set of changes on top, rather than being a hard fork or partially-compatible reimplementation. Variants are used as bit flags, so in theory a Flavor may consist of multiple variants, although currently none do. Do NOT use a Variant to represent a completely separate DBMS which just happens to speak the same wire protocol as a Vendor, or provides partial compatibility with a Vendor through a completely separate codebase.

const (
	VariantPercona Variant = 1 << iota
	VariantAurora
)

Constants representing variants. Not all entries here are necessarily supported by this package.

const (
	VariantNone    Variant = 0
	VariantUnknown Variant = 0
)

Variant zero value constants can either express no variant or unknown variants.

func ParseVariant added in v1.7.1

func ParseVariant(s string) (variant Variant)

ParseVariant converts a string to a Variant value, or VariantUnknown if the string does not match a known variant.

func (Variant) String added in v1.7.1

func (variant Variant) String() string

String returns a stringified representation of one or more variant flags.

type Vendor

type Vendor uint16

Vendor represents an upstream DBMS software. Vendors are used for DBMS projects with separate codebases and versioning practices. For projects that track an upstream Vendor's codebase and apply changes as a patch-set, see Variant instead, later in this file.

const (
	VendorUnknown Vendor = iota
	VendorMySQL
	VendorMariaDB
)

Constants representing different supported vendors

func ParseVendor

func ParseVendor(s string) Vendor

ParseVendor converts a string to a Vendor value.

func (Vendor) String

func (v Vendor) String() string

type Version added in v1.7.1

type Version [3]uint16

Version represents a (Major, Minor, Patch) version number tuple.

func ParseVersion

func ParseVersion(s string) (ver Version, err error)

ParseVersion converts the supplied string in dot-separated format into a Version, or returns an error if parsing fails. Any non-digit prefix or suffix is ignored.

func SplitVersionedIdentifier added in v1.7.1

func SplitVersionedIdentifier(s string) (name string, version Version, label string)

SplitVersionedIdentifier takes a string of form "name:major.minor.patch-label" into separate name, version, and label components. The supplied string may omit the label and/or some version components if desired; zero values will be returned for any missing or erroneous component.

func (Version) AtLeast added in v1.7.1

func (ver Version) AtLeast(other Version) bool

AtLeast returns true if this version is greater than or equal to the supplied arg.

func (Version) Below added in v1.7.1

func (ver Version) Below(other Version) bool

Below returns true if this version is strictly less than the supplied arg.

func (Version) Major added in v1.7.1

func (ver Version) Major() uint16

Major returns the major component of the version number.

func (Version) Minor added in v1.7.1

func (ver Version) Minor() uint16

Minor returns the minor component of the version number.

func (Version) Patch added in v1.7.1

func (ver Version) Patch() uint16

Patch returns the patch component of the version number, also known as the point release number.

func (Version) String added in v1.7.1

func (ver Version) String() string

Jump to

Keyboard shortcuts

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