mirror of
https://github.com/xataio/pgroll.git
synced 2024-09-11 05:45:48 +03:00
Implement 'drop index' migrations (#51)
Add support for **drop index** migrations. A drop index migration looks like this: ```json { "name": "11_drop_index", "operations": [ { "drop_index": { "name": "_pgroll_idx_users_name" } } ] } ``` * `Start` is a no-op. * On `Complete` the index is removed from the underlying table. * `Rollback` is a no-op.
This commit is contained in:
parent
a44b475f0b
commit
9d6ad24fb1
10
examples/11_drop_index.json
Normal file
10
examples/11_drop_index.json
Normal file
@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "11_drop_index",
|
||||
"operations": [
|
||||
{
|
||||
"drop_index": {
|
||||
"name": "_pgroll_idx_fruits_name"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
@ -43,3 +43,11 @@ type IndexAlreadyExistsError struct {
|
||||
func (e IndexAlreadyExistsError) Error() string {
|
||||
return fmt.Sprintf("index %q already exists", e.Name)
|
||||
}
|
||||
|
||||
type IndexDoesNotExistError struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
func (e IndexDoesNotExistError) Error() string {
|
||||
return fmt.Sprintf("index %q does not exist", e.Name)
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ const (
|
||||
OpNameAddColumn OpName = "add_column"
|
||||
OpNameDropColumn OpName = "drop_column"
|
||||
OpNameCreateIndex OpName = "create_index"
|
||||
OpNameDropIndex OpName = "drop_index"
|
||||
)
|
||||
|
||||
func TemporaryName(name string) string {
|
||||
@ -90,6 +91,9 @@ func (v *Operations) UnmarshalJSON(data []byte) error {
|
||||
case OpNameCreateIndex:
|
||||
item = &OpCreateIndex{}
|
||||
|
||||
case OpNameDropIndex:
|
||||
item = &OpDropIndex{}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unknown migration type: %v", opName)
|
||||
}
|
||||
@ -140,6 +144,9 @@ func (v Operations) MarshalJSON() ([]byte, error) {
|
||||
case *OpCreateIndex:
|
||||
opName = OpNameCreateIndex
|
||||
|
||||
case *OpDropIndex:
|
||||
opName = OpNameDropIndex
|
||||
|
||||
default:
|
||||
panic(fmt.Errorf("unknown operation for %T", op))
|
||||
}
|
||||
|
42
pkg/migrations/op_drop_index.go
Normal file
42
pkg/migrations/op_drop_index.go
Normal file
@ -0,0 +1,42 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
"pg-roll/pkg/schema"
|
||||
)
|
||||
|
||||
type OpDropIndex struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
var _ Operation = (*OpDropIndex)(nil)
|
||||
|
||||
func (o *OpDropIndex) Start(ctx context.Context, conn *sql.DB, schemaName string, stateSchema string, s *schema.Schema) error {
|
||||
// no-op
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OpDropIndex) Complete(ctx context.Context, conn *sql.DB) error {
|
||||
// drop the index concurrently
|
||||
_, err := conn.ExecContext(ctx, fmt.Sprintf("DROP INDEX CONCURRENTLY IF EXISTS %s", o.Name))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (o *OpDropIndex) Rollback(ctx context.Context, conn *sql.DB) error {
|
||||
// no-op
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *OpDropIndex) Validate(ctx context.Context, s *schema.Schema) error {
|
||||
for _, table := range s.Tables {
|
||||
_, ok := table.Indexes[o.Name]
|
||||
if ok {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return IndexDoesNotExistError{Name: o.Name}
|
||||
}
|
68
pkg/migrations/op_drop_index_test.go
Normal file
68
pkg/migrations/op_drop_index_test.go
Normal file
@ -0,0 +1,68 @@
|
||||
package migrations_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"testing"
|
||||
|
||||
"pg-roll/pkg/migrations"
|
||||
)
|
||||
|
||||
func TestDropIndex(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
idxName := migrations.GenerateIndexName("users", []string{"name"})
|
||||
|
||||
ExecuteTests(t, TestCases{{
|
||||
name: "drop index",
|
||||
migrations: []migrations.Migration{
|
||||
{
|
||||
Name: "01_add_table",
|
||||
Operations: migrations.Operations{
|
||||
&migrations.OpCreateTable{
|
||||
Name: "users",
|
||||
Columns: []migrations.Column{
|
||||
{
|
||||
Name: "id",
|
||||
Type: "serial",
|
||||
PrimaryKey: true,
|
||||
},
|
||||
{
|
||||
Name: "name",
|
||||
Type: "varchar(255)",
|
||||
Nullable: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "02_create_index",
|
||||
Operations: migrations.Operations{
|
||||
&migrations.OpCreateIndex{
|
||||
Table: "users",
|
||||
Columns: []string{"name"},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "03_drop_index",
|
||||
Operations: migrations.Operations{
|
||||
&migrations.OpDropIndex{
|
||||
Name: idxName,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
afterStart: func(t *testing.T, db *sql.DB) {
|
||||
// The index has not yet been dropped.
|
||||
IndexMustExist(t, db, "public", "users", idxName)
|
||||
},
|
||||
afterRollback: func(t *testing.T, db *sql.DB) {
|
||||
// Rollback is a no-op.
|
||||
},
|
||||
afterComplete: func(t *testing.T, db *sql.DB) {
|
||||
// The index has been removed from the underlying table.
|
||||
IndexMustNotExist(t, db, "public", "users", idxName)
|
||||
},
|
||||
}})
|
||||
}
|
Loading…
Reference in New Issue
Block a user