Documentation
¶
Overview ¶
Package migrate checks a schema-change draft, .aicoded/migration.sql, and applies an app's migrations to its database as the database's owner.
A draft holds at most 64 KiB of UTF-8 and 100 statements. Check splits it into statements and allows only those that add to the schema of the app's own database (Classify): CREATE TABLE, CREATE INDEX, and ALTER TABLE with only ADD clauses, where a new NOT NULL column has a DEFAULT. Destructive statements are refused with E-MIG-003 and everything else with E-MIG-002. Each publish adds its draft's statements to the app's list of steps, and Apply runs the steps that the database's journal, the table aicoded_migrations, lacks.
The aicoded CLI and the platform import it. App code may not: E-LINT-001 refuses the import.
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Check ¶
Check splits a draft into its statements and classifies each. It returns the statements and one error that joins every problem, each at the line of the draft its statement starts on.
Example ¶
package main
import (
"fmt"
"aicoded.dev/framework/migrate"
)
func main() {
statements, err := migrate.Check([]byte("CREATE TABLE notes (id BIGINT AUTO_INCREMENT PRIMARY KEY, body TEXT);\n" +
"ALTER TABLE notes ADD COLUMN author VARCHAR(100) NULL;\n"))
fmt.Println(len(statements), err)
}
Output: 2 <nil>
func Extends ¶
Extends returns E-MIG-004 unless ran, the steps a database's journal holds, starts steps, or steps starts ran (a rollback). Steps match by Seq, Publish, Index and SHA256.
func IsJournal ¶
IsJournal reports whether name, a table name without quotes, names the journal of migrations, aicoded_migrations, under any case folding MySQL may apply to table names: Unicode simple folding, and İ and ı to i. Lint uses it to keep app code away from the journal.
func Normalize ¶
Normalize returns the form of stmt, a statement as Split returns it, in which two statements that MySQL reads alike are the same: its tokens with one space between each two, without comments or a final ;, and each word outside quotes in upper case, but for a table's name, after TABLE, ON or REFERENCES, and a word that starts with a digit, such as 0x1f. MySQL reads keywords and the names of columns and indexes in any case, while a table's name keeps its case. Strings and names in backquotes are kept as they are. Text the checks cannot read is returned without surrounding space.
Types ¶
type Kind ¶
type Kind int
Kind is the kind of a statement that Classify allows.
const Expand Kind = 1
Expand is a statement that adds to the schema and changes or removes nothing in it.
func Classify ¶
Classify returns Expand for a statement that only adds to the schema of the app's own database: CREATE TABLE, CREATE INDEX, and ALTER TABLE with only ADD clauses. It refuses a destructive statement with E-MIG-003, and every other statement, and any it cannot read, with E-MIG-002.
Example ¶
package main
import (
"fmt"
"aicoded.dev/framework/internal/errs"
"aicoded.dev/framework/migrate"
)
func main() {
_, err := migrate.Classify("ALTER TABLE notes DROP COLUMN author")
fmt.Println(errs.Code(err))
}
Output: E-MIG-003
type Step ¶
type Step struct {
// Seq is the step's place in the app's list, from 1.
Seq int `json:"seq"`
// Publish is the id of the publish that added the step, or "draft" locally.
Publish string `json:"publish"`
// Index is the step's place within its publish, from 1.
Index int `json:"index"`
// SHA256 is the lower-case hex SHA-256 of Statement.
SHA256 string `json:"sha256"`
// Statement is the SQL statement.
Statement string `json:"statement"`
}
Step is one statement of an app's migrations.
func Apply ¶
Apply runs on db the steps that its journal, the table aicoded_migrations, lacks, in order, and returns them. It holds the database's migration lock meanwhile, a named lock of aicoded_migrations: and the hex SHA-256 of the database's name cut to 64 characters, on one connection with lock_wait_timeout 30, and runs each step under a 5-minute context, then adds its row to the journal.
It refuses, before running anything, a list whose steps are not numbered from 1 or whose hash does not match its statement (E-MIG-004), a list the journal does not agree with (E-MIG-004, see Extends) and a step to run that Classify refuses. A step that fails stops Apply with E-MIG-005; the journal keeps the steps that ran. So does a step that ran but whose row could not be added to the journal, even on a new connection; its message says it ran but was not recorded.