Store schema name in pg-roll's internal schema representation (#67)

Change the representation of a schema in `pg-roll`s state store from:

```go
type Schema struct {
	// Tables is a map of virtual table name -> table mapping
	Tables map[string]Table `json:"tables"`
}
```

to:

```go
type Schema struct {
	// Name is the name of the schema
	Name string `json:"name"`
	// Tables is a map of virtual table name -> table mapping
	Tables map[string]Table `json:"tables"`
}
```

ie, store the schema's name.

This allows the signature of `Start` to be simplified, removing the
`schemaName` parameter; the name can be retrieved from the
`schema.Schema` struct that is already provided.
This commit is contained in:
Andrew Farries 2023-08-29 14:58:24 +01:00 committed by GitHub
parent a1e8b458b3
commit a18dab932f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 19 additions and 16 deletions

View File

@ -12,7 +12,7 @@ type Operation interface {
// Start will apply the required changes to enable supporting the new schema
// version in the database (through a view)
// update the given views to expose the new schema version
Start(ctx context.Context, conn *sql.DB, schemaName, stateSchema string, s *schema.Schema) error
Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error
// Complete will update the database schema to match the current version
// after calling Start.

View File

@ -18,7 +18,7 @@ type OpAddColumn struct {
var _ Operation = (*OpAddColumn)(nil)
func (o *OpAddColumn) Start(ctx context.Context, conn *sql.DB, schemaName, stateSchema string, s *schema.Schema) error {
func (o *OpAddColumn) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
table := s.GetTable(o.Table)
if err := addColumn(ctx, conn, *o, table); err != nil {
@ -36,7 +36,7 @@ func (o *OpAddColumn) Start(ctx context.Context, conn *sql.DB, schemaName, state
Name: TriggerName(o.Table, o.Column.Name),
Direction: TriggerDirectionUp,
Columns: s.GetTable(o.Table).Columns,
SchemaName: schemaName,
SchemaName: s.Name,
TableName: o.Table,
PhysicalColumn: TemporaryName(o.Column.Name),
StateSchema: stateSchema,

View File

@ -18,7 +18,7 @@ type OpCreateIndex struct {
var _ Operation = (*OpCreateIndex)(nil)
func (o *OpCreateIndex) Start(ctx context.Context, conn *sql.DB, schemaName string, stateSchema string, s *schema.Schema) error {
func (o *OpCreateIndex) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
// create index concurrently
_, err := conn.ExecContext(ctx, fmt.Sprintf("CREATE INDEX CONCURRENTLY IF NOT EXISTS %s ON %s (%s)",
pq.QuoteIdentifier(o.Name),

View File

@ -25,7 +25,7 @@ type Column struct {
Default *string `json:"default"`
}
func (o *OpCreateTable) Start(ctx context.Context, conn *sql.DB, schemaName, stateSchema string, s *schema.Schema) error {
func (o *OpCreateTable) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
tempName := TemporaryName(o.Name)
_, err := conn.ExecContext(ctx, fmt.Sprintf("CREATE TABLE %s (%s)",
pq.QuoteIdentifier(tempName),

View File

@ -17,13 +17,13 @@ type OpDropColumn struct {
var _ Operation = (*OpDropColumn)(nil)
func (o *OpDropColumn) Start(ctx context.Context, conn *sql.DB, schemaName string, stateSchema string, s *schema.Schema) error {
func (o *OpDropColumn) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
if o.Down != nil {
err := createTrigger(ctx, conn, triggerConfig{
Name: TriggerName(o.Table, o.Column),
Direction: TriggerDirectionDown,
Columns: s.GetTable(o.Table).Columns,
SchemaName: schemaName,
SchemaName: s.Name,
TableName: o.Table,
PhysicalColumn: o.Column,
StateSchema: stateSchema,

View File

@ -14,7 +14,7 @@ type OpDropIndex struct {
var _ Operation = (*OpDropIndex)(nil)
func (o *OpDropIndex) Start(ctx context.Context, conn *sql.DB, schemaName string, stateSchema string, s *schema.Schema) error {
func (o *OpDropIndex) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
// no-op
return nil
}

View File

@ -15,7 +15,7 @@ type OpDropTable struct {
var _ Operation = (*OpDropTable)(nil)
func (o *OpDropTable) Start(ctx context.Context, conn *sql.DB, schemaName, stateSchema string, s *schema.Schema) error {
func (o *OpDropTable) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
s.RemoveTable(o.Name)
return nil
}

View File

@ -17,7 +17,7 @@ type OpRenameColumn struct {
var _ Operation = (*OpRenameColumn)(nil)
func (o *OpRenameColumn) Start(ctx context.Context, conn *sql.DB, schemaName string, stateSchema string, s *schema.Schema) error {
func (o *OpRenameColumn) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
table := s.GetTable(o.Table)
table.RenameColumn(o.From, o.To)
return nil

View File

@ -16,7 +16,7 @@ type OpRenameTable struct {
To string `json:"to"`
}
func (o *OpRenameTable) Start(ctx context.Context, conn *sql.DB, schemaName, stateSchema string, s *schema.Schema) error {
func (o *OpRenameTable) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
return s.RenameTable(o.From, o.To)
}

View File

@ -17,7 +17,7 @@ type OpSetNotNull struct {
var _ Operation = (*OpSetNotNull)(nil)
func (o *OpSetNotNull) Start(ctx context.Context, conn *sql.DB, schemaName string, stateSchema string, s *schema.Schema) error {
func (o *OpSetNotNull) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
table := s.GetTable(o.Table)
column := table.GetColumn(o.Column)
@ -36,7 +36,7 @@ func (o *OpSetNotNull) Start(ctx context.Context, conn *sql.DB, schemaName strin
Name: TriggerName(o.Table, o.Column),
Direction: TriggerDirectionUp,
Columns: table.Columns,
SchemaName: schemaName,
SchemaName: s.Name,
TableName: o.Table,
PhysicalColumn: TemporaryName(o.Column),
StateSchema: stateSchema,
@ -60,7 +60,7 @@ func (o *OpSetNotNull) Start(ctx context.Context, conn *sql.DB, schemaName strin
Name: TriggerName(o.Table, TemporaryName(o.Column)),
Direction: TriggerDirectionDown,
Columns: table.Columns,
SchemaName: schemaName,
SchemaName: s.Name,
TableName: o.Table,
PhysicalColumn: o.Column,
StateSchema: stateSchema,

View File

@ -18,7 +18,7 @@ type OpSetUnique struct {
var _ Operation = (*OpSetUnique)(nil)
func (o *OpSetUnique) Start(ctx context.Context, conn *sql.DB, schemaName string, stateSchema string, s *schema.Schema) error {
func (o *OpSetUnique) Start(ctx context.Context, conn *sql.DB, stateSchema string, s *schema.Schema) error {
// create unique index concurrently
_, err := conn.ExecContext(ctx, fmt.Sprintf("CREATE UNIQUE INDEX CONCURRENTLY IF NOT EXISTS %s ON %s (%s)",
pq.QuoteIdentifier(o.Name),

View File

@ -38,7 +38,7 @@ func (m *Roll) Start(ctx context.Context, migration *migrations.Migration) error
// execute operations
for _, op := range migration.Operations {
err := op.Start(ctx, m.pgConn, m.schema, m.state.Schema(), newSchema)
err := op.Start(ctx, m.pgConn, m.state.Schema(), newSchema)
if err != nil {
return fmt.Errorf("unable to execute start operation: %w", err)
}

View File

@ -15,6 +15,8 @@ func New() *Schema {
}
type Schema struct {
// Name is the name of the schema
Name string `json:"name"`
// Tables is a map of virtual table name -> table mapping
Tables map[string]Table `json:"tables"`
}

View File

@ -73,6 +73,7 @@ DECLARE
tables jsonb;
BEGIN
SELECT json_build_object(
'name', schemaname,
'tables', (
SELECT json_object_agg(t.relname, jsonb_build_object(
'name', t.relname,