mirror of
https://github.com/xataio/pgroll.git
synced 2024-10-26 05:46:27 +03:00
Move logic for the status
command into the state
and migrations
packages (#205)
Move the logic for the `pgroll status` command out of the CLI and into the `migrations` and `state` package and add tests for it. This makes it possible to consume migration status information from packages using `pgroll` as a module.
This commit is contained in:
parent
34bbb24919
commit
763dabcf2c
@ -3,7 +3,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
@ -13,12 +12,6 @@ import (
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type statusLine struct {
|
||||
Schema string
|
||||
Version string
|
||||
Status string
|
||||
}
|
||||
|
||||
var statusCmd = &cobra.Command{
|
||||
Use: "status",
|
||||
Short: "Show pgroll status",
|
||||
@ -30,12 +23,12 @@ var statusCmd = &cobra.Command{
|
||||
}
|
||||
defer state.Close()
|
||||
|
||||
statusLine, err := statusForSchema(ctx, state, flags.Schema())
|
||||
status, err := state.Status(ctx, flags.Schema())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
statusJSON, err := json.MarshalIndent(statusLine, "", " ")
|
||||
statusJSON, err := json.MarshalIndent(status, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -44,33 +37,3 @@ var statusCmd = &cobra.Command{
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
func statusForSchema(ctx context.Context, st *state.State, schema string) (*statusLine, error) {
|
||||
latestVersion, err := st.LatestVersion(ctx, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if latestVersion == nil {
|
||||
latestVersion = new(string)
|
||||
}
|
||||
|
||||
isActive, err := st.IsActiveMigrationPeriod(ctx, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var status string
|
||||
if *latestVersion == "" {
|
||||
status = "No migrations"
|
||||
} else if isActive {
|
||||
status = "In Progress"
|
||||
} else {
|
||||
status = "Complete"
|
||||
}
|
||||
|
||||
return &statusLine{
|
||||
Schema: schema,
|
||||
Version: *latestVersion,
|
||||
Status: status,
|
||||
}, nil
|
||||
}
|
||||
|
@ -389,6 +389,78 @@ func TestViewsAreCreatedWithSecurityInvokerTrue(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestStatusMethodReturnsCorrectStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
withMigratorAndConnectionToContainer(t, func(mig *roll.Roll, db *sql.DB) {
|
||||
ctx := context.Background()
|
||||
|
||||
// Get the initial migration status before any migrations are run
|
||||
status, err := mig.Status(ctx, "public")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Ensure that the status shows "No migrations"
|
||||
assert.Equal(t, &state.Status{
|
||||
Schema: "public",
|
||||
Version: "",
|
||||
Status: state.NoneMigrationStatus,
|
||||
}, status)
|
||||
|
||||
// Start a migration
|
||||
err = mig.Start(ctx, &migrations.Migration{
|
||||
Name: "01_create_table",
|
||||
Operations: []migrations.Operation{createTableOp("table1")},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get the migration status
|
||||
status, err = mig.Status(ctx, "public")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Ensure that the status shows "In progress"
|
||||
assert.Equal(t, &state.Status{
|
||||
Schema: "public",
|
||||
Version: "01_create_table",
|
||||
Status: state.InProgressMigrationStatus,
|
||||
}, status)
|
||||
|
||||
// Rollback the migration
|
||||
err = mig.Rollback(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get the migration status
|
||||
status, err = mig.Status(ctx, "public")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Ensure that the status shows "No migrations"
|
||||
assert.Equal(t, &state.Status{
|
||||
Schema: "public",
|
||||
Version: "",
|
||||
Status: state.NoneMigrationStatus,
|
||||
}, status)
|
||||
|
||||
// Start and complete a migration
|
||||
err = mig.Start(ctx, &migrations.Migration{
|
||||
Name: "01_create_table",
|
||||
Operations: []migrations.Operation{createTableOp("table1")},
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
err = mig.Complete(ctx)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Get the migration status
|
||||
status, err = mig.Status(ctx, "public")
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Ensure that the status shows "Complete"
|
||||
assert.Equal(t, &state.Status{
|
||||
Schema: "public",
|
||||
Version: "01_create_table",
|
||||
Status: state.CompleteMigrationStatus,
|
||||
}, status)
|
||||
})
|
||||
}
|
||||
|
||||
func createTableOp(tableName string) *migrations.OpCreateTable {
|
||||
return &migrations.OpCreateTable{
|
||||
Name: tableName,
|
||||
|
@ -75,6 +75,10 @@ func (m *Roll) PGVersion() PGVersion {
|
||||
return m.pgVersion
|
||||
}
|
||||
|
||||
func (m *Roll) Status(ctx context.Context, schema string) (*state.Status, error) {
|
||||
return m.state.Status(ctx, schema)
|
||||
}
|
||||
|
||||
func (m *Roll) Close() error {
|
||||
err := m.state.Close()
|
||||
if err != nil {
|
||||
|
@ -334,6 +334,37 @@ func (s *State) PreviousVersion(ctx context.Context, schema string) (*string, er
|
||||
return parent, nil
|
||||
}
|
||||
|
||||
// Status returns the current migration status of the specified schema
|
||||
func (s *State) Status(ctx context.Context, schema string) (*Status, error) {
|
||||
latestVersion, err := s.LatestVersion(ctx, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if latestVersion == nil {
|
||||
latestVersion = new(string)
|
||||
}
|
||||
|
||||
isActive, err := s.IsActiveMigrationPeriod(ctx, schema)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var status MigrationStatus
|
||||
if *latestVersion == "" {
|
||||
status = NoneMigrationStatus
|
||||
} else if isActive {
|
||||
status = InProgressMigrationStatus
|
||||
} else {
|
||||
status = CompleteMigrationStatus
|
||||
}
|
||||
|
||||
return &Status{
|
||||
Schema: schema,
|
||||
Version: *latestVersion,
|
||||
Status: status,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ReadSchema reads & returns the current schema from postgres
|
||||
func ReadSchema(ctx context.Context, conn *sql.DB, stateSchema, schemaname string) (*schema.Schema, error) {
|
||||
var res schema.Schema
|
||||
|
23
pkg/state/status.go
Normal file
23
pkg/state/status.go
Normal file
@ -0,0 +1,23 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package state
|
||||
|
||||
type MigrationStatus string
|
||||
|
||||
const (
|
||||
NoneMigrationStatus MigrationStatus = "No migrations"
|
||||
InProgressMigrationStatus MigrationStatus = "In progress"
|
||||
CompleteMigrationStatus MigrationStatus = "Complete"
|
||||
)
|
||||
|
||||
// Status describes the current migration status of a database schema.
|
||||
type Status struct {
|
||||
// The schema name.
|
||||
Schema string `json:"schema"`
|
||||
|
||||
// The name of the latest version schema.
|
||||
Version string `json:"version"`
|
||||
|
||||
// The status of the most recent migration.
|
||||
Status MigrationStatus `json:"status"`
|
||||
}
|
Loading…
Reference in New Issue
Block a user