summaryrefslogtreecommitdiff
path: root/vendor/github.com/uptrace/bun/migrate/operations.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/uptrace/bun/migrate/operations.go')
-rw-r--r--vendor/github.com/uptrace/bun/migrate/operations.go340
1 files changed, 340 insertions, 0 deletions
diff --git a/vendor/github.com/uptrace/bun/migrate/operations.go b/vendor/github.com/uptrace/bun/migrate/operations.go
new file mode 100644
index 000000000..7b749c5a0
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/migrate/operations.go
@@ -0,0 +1,340 @@
+package migrate
+
+import (
+ "fmt"
+
+ "github.com/uptrace/bun/migrate/sqlschema"
+)
+
+// Operation encapsulates the request to change a database definition
+// and knowns which operation can revert it.
+//
+// It is useful to define "monolith" Operations whenever possible,
+// even though they a dialect may require several distinct steps to apply them.
+// For example, changing a primary key involves first dropping the old constraint
+// before generating the new one. Yet, this is only an implementation detail and
+// passing a higher-level ChangePrimaryKeyOp will give the dialect more information
+// about the applied change.
+//
+// Some operations might be irreversible due to technical limitations. Returning
+// a *comment from GetReverse() will add an explanatory note to the generate migation file.
+//
+// To declare dependency on another Operation, operations should implement
+// { DependsOn(Operation) bool } interface, which Changeset will use to resolve dependencies.
+type Operation interface {
+ GetReverse() Operation
+}
+
+// CreateTableOp creates a new table in the schema.
+//
+// It does not report dependency on any other migration and may be executed first.
+// Make sure the dialect does not include FOREIGN KEY constraints in the CREATE TABLE
+// statement, as those may potentially reference not-yet-existing columns/tables.
+type CreateTableOp struct {
+ TableName string
+ Model interface{}
+}
+
+var _ Operation = (*CreateTableOp)(nil)
+
+func (op *CreateTableOp) GetReverse() Operation {
+ return &DropTableOp{TableName: op.TableName}
+}
+
+// DropTableOp drops a database table. This operation is not reversible.
+type DropTableOp struct {
+ TableName string
+}
+
+var _ Operation = (*DropTableOp)(nil)
+
+func (op *DropTableOp) DependsOn(another Operation) bool {
+ drop, ok := another.(*DropForeignKeyOp)
+ return ok && drop.ForeignKey.DependsOnTable(op.TableName)
+}
+
+// GetReverse for a DropTable returns a no-op migration. Logically, CreateTable is the reverse,
+// but DropTable does not have the table's definition to create one.
+func (op *DropTableOp) GetReverse() Operation {
+ c := comment(fmt.Sprintf("WARNING: \"DROP TABLE %s\" cannot be reversed automatically because table definition is not available", op.TableName))
+ return &c
+}
+
+// RenameTableOp renames the table. Changing the "schema" part of the table's FQN (moving tables between schemas) is not allowed.
+type RenameTableOp struct {
+ TableName string
+ NewName string
+}
+
+var _ Operation = (*RenameTableOp)(nil)
+
+func (op *RenameTableOp) GetReverse() Operation {
+ return &RenameTableOp{
+ TableName: op.NewName,
+ NewName: op.TableName,
+ }
+}
+
+// RenameColumnOp renames a column in the table. If the changeset includes a rename operation
+// for the column's table, it should be executed first.
+type RenameColumnOp struct {
+ TableName string
+ OldName string
+ NewName string
+}
+
+var _ Operation = (*RenameColumnOp)(nil)
+
+func (op *RenameColumnOp) GetReverse() Operation {
+ return &RenameColumnOp{
+ TableName: op.TableName,
+ OldName: op.NewName,
+ NewName: op.OldName,
+ }
+}
+
+func (op *RenameColumnOp) DependsOn(another Operation) bool {
+ rename, ok := another.(*RenameTableOp)
+ return ok && op.TableName == rename.NewName
+}
+
+// AddColumnOp adds a new column to the table.
+type AddColumnOp struct {
+ TableName string
+ ColumnName string
+ Column sqlschema.Column
+}
+
+var _ Operation = (*AddColumnOp)(nil)
+
+func (op *AddColumnOp) GetReverse() Operation {
+ return &DropColumnOp{
+ TableName: op.TableName,
+ ColumnName: op.ColumnName,
+ Column: op.Column,
+ }
+}
+
+// DropColumnOp drop a column from the table.
+//
+// While some dialects allow DROP CASCADE to drop dependent constraints,
+// explicit handling on constraints is preferred for transparency and debugging.
+// DropColumnOp depends on DropForeignKeyOp, DropPrimaryKeyOp, and ChangePrimaryKeyOp
+// if any of the constraints is defined on this table.
+type DropColumnOp struct {
+ TableName string
+ ColumnName string
+ Column sqlschema.Column
+}
+
+var _ Operation = (*DropColumnOp)(nil)
+
+func (op *DropColumnOp) GetReverse() Operation {
+ return &AddColumnOp{
+ TableName: op.TableName,
+ ColumnName: op.ColumnName,
+ Column: op.Column,
+ }
+}
+
+func (op *DropColumnOp) DependsOn(another Operation) bool {
+ switch drop := another.(type) {
+ case *DropForeignKeyOp:
+ return drop.ForeignKey.DependsOnColumn(op.TableName, op.ColumnName)
+ case *DropPrimaryKeyOp:
+ return op.TableName == drop.TableName && drop.PrimaryKey.Columns.Contains(op.ColumnName)
+ case *ChangePrimaryKeyOp:
+ return op.TableName == drop.TableName && drop.Old.Columns.Contains(op.ColumnName)
+ }
+ return false
+}
+
+// AddForeignKey adds a new FOREIGN KEY constraint.
+type AddForeignKeyOp struct {
+ ForeignKey sqlschema.ForeignKey
+ ConstraintName string
+}
+
+var _ Operation = (*AddForeignKeyOp)(nil)
+
+func (op *AddForeignKeyOp) TableName() string {
+ return op.ForeignKey.From.TableName
+}
+
+func (op *AddForeignKeyOp) DependsOn(another Operation) bool {
+ switch another := another.(type) {
+ case *RenameTableOp:
+ return op.ForeignKey.DependsOnTable(another.TableName) || op.ForeignKey.DependsOnTable(another.NewName)
+ case *CreateTableOp:
+ return op.ForeignKey.DependsOnTable(another.TableName)
+ }
+ return false
+}
+
+func (op *AddForeignKeyOp) GetReverse() Operation {
+ return &DropForeignKeyOp{
+ ForeignKey: op.ForeignKey,
+ ConstraintName: op.ConstraintName,
+ }
+}
+
+// DropForeignKeyOp drops a FOREIGN KEY constraint.
+type DropForeignKeyOp struct {
+ ForeignKey sqlschema.ForeignKey
+ ConstraintName string
+}
+
+var _ Operation = (*DropForeignKeyOp)(nil)
+
+func (op *DropForeignKeyOp) TableName() string {
+ return op.ForeignKey.From.TableName
+}
+
+func (op *DropForeignKeyOp) GetReverse() Operation {
+ return &AddForeignKeyOp{
+ ForeignKey: op.ForeignKey,
+ ConstraintName: op.ConstraintName,
+ }
+}
+
+// AddUniqueConstraintOp adds new UNIQUE constraint to the table.
+type AddUniqueConstraintOp struct {
+ TableName string
+ Unique sqlschema.Unique
+}
+
+var _ Operation = (*AddUniqueConstraintOp)(nil)
+
+func (op *AddUniqueConstraintOp) GetReverse() Operation {
+ return &DropUniqueConstraintOp{
+ TableName: op.TableName,
+ Unique: op.Unique,
+ }
+}
+
+func (op *AddUniqueConstraintOp) DependsOn(another Operation) bool {
+ switch another := another.(type) {
+ case *AddColumnOp:
+ return op.TableName == another.TableName && op.Unique.Columns.Contains(another.ColumnName)
+ case *RenameTableOp:
+ return op.TableName == another.NewName
+ case *DropUniqueConstraintOp:
+ // We want to drop the constraint with the same name before adding this one.
+ return op.TableName == another.TableName && op.Unique.Name == another.Unique.Name
+ default:
+ return false
+ }
+
+}
+
+// DropUniqueConstraintOp drops a UNIQUE constraint.
+type DropUniqueConstraintOp struct {
+ TableName string
+ Unique sqlschema.Unique
+}
+
+var _ Operation = (*DropUniqueConstraintOp)(nil)
+
+func (op *DropUniqueConstraintOp) DependsOn(another Operation) bool {
+ if rename, ok := another.(*RenameTableOp); ok {
+ return op.TableName == rename.NewName
+ }
+ return false
+}
+
+func (op *DropUniqueConstraintOp) GetReverse() Operation {
+ return &AddUniqueConstraintOp{
+ TableName: op.TableName,
+ Unique: op.Unique,
+ }
+}
+
+// ChangeColumnTypeOp set a new data type for the column.
+// The two types should be such that the data can be auto-casted from one to another.
+// E.g. reducing VARCHAR lenght is not possible in most dialects.
+// AutoMigrator does not enforce or validate these rules.
+type ChangeColumnTypeOp struct {
+ TableName string
+ Column string
+ From sqlschema.Column
+ To sqlschema.Column
+}
+
+var _ Operation = (*ChangeColumnTypeOp)(nil)
+
+func (op *ChangeColumnTypeOp) GetReverse() Operation {
+ return &ChangeColumnTypeOp{
+ TableName: op.TableName,
+ Column: op.Column,
+ From: op.To,
+ To: op.From,
+ }
+}
+
+// DropPrimaryKeyOp drops the table's PRIMARY KEY.
+type DropPrimaryKeyOp struct {
+ TableName string
+ PrimaryKey sqlschema.PrimaryKey
+}
+
+var _ Operation = (*DropPrimaryKeyOp)(nil)
+
+func (op *DropPrimaryKeyOp) GetReverse() Operation {
+ return &AddPrimaryKeyOp{
+ TableName: op.TableName,
+ PrimaryKey: op.PrimaryKey,
+ }
+}
+
+// AddPrimaryKeyOp adds a new PRIMARY KEY to the table.
+type AddPrimaryKeyOp struct {
+ TableName string
+ PrimaryKey sqlschema.PrimaryKey
+}
+
+var _ Operation = (*AddPrimaryKeyOp)(nil)
+
+func (op *AddPrimaryKeyOp) GetReverse() Operation {
+ return &DropPrimaryKeyOp{
+ TableName: op.TableName,
+ PrimaryKey: op.PrimaryKey,
+ }
+}
+
+func (op *AddPrimaryKeyOp) DependsOn(another Operation) bool {
+ switch another := another.(type) {
+ case *AddColumnOp:
+ return op.TableName == another.TableName && op.PrimaryKey.Columns.Contains(another.ColumnName)
+ }
+ return false
+}
+
+// ChangePrimaryKeyOp changes the PRIMARY KEY of the table.
+type ChangePrimaryKeyOp struct {
+ TableName string
+ Old sqlschema.PrimaryKey
+ New sqlschema.PrimaryKey
+}
+
+var _ Operation = (*AddPrimaryKeyOp)(nil)
+
+func (op *ChangePrimaryKeyOp) GetReverse() Operation {
+ return &ChangePrimaryKeyOp{
+ TableName: op.TableName,
+ Old: op.New,
+ New: op.Old,
+ }
+}
+
+// comment denotes an Operation that cannot be executed.
+//
+// Operations, which cannot be reversed due to current technical limitations,
+// may return &comment with a helpful message from their GetReverse() method.
+//
+// Chnagelog should skip it when applying operations or output as log message,
+// and write it as an SQL comment when creating migration files.
+type comment string
+
+var _ Operation = (*comment)(nil)
+
+func (c *comment) GetReverse() Operation { return c }