Skip to content

Commit

Permalink
Add roll.WithSearchPath option (#380)
Browse files Browse the repository at this point in the history
Add a `roll.WithSearchPath` option to allow widening of the search path
during migration execution.

By default, the session that executes a migration has its search path
restricted to the schema in which the migration is applied. By using
`WithSearchPath` the search path can include arbitrarily many other
schema.
  • Loading branch information
andrew-farries authored Jul 31, 2024
1 parent c2635b3 commit 092313a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 1 deletion.
36 changes: 36 additions & 0 deletions pkg/roll/execute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,42 @@ func TestSQLTransformerOptionIsUsedWhenCreatingTriggers(t *testing.T) {
})
}

func TestWithSearchPathOptionIsRespected(t *testing.T) {
t.Parallel()

opts := []roll.Option{roll.WithSearchPath("public")}

testutils.WithMigratorInSchemaAndConnectionToContainerWithOptions(t, "foo", opts, func(mig *roll.Roll, db *sql.DB) {
ctx := context.Background()

// Create a function in the public schema
_, err := db.ExecContext(ctx, `CREATE OR REPLACE FUNCTION say_hello()
RETURNS TEXT AS $$
SELECT 'hello world';
$$ LANGUAGE sql;
`)
require.NoError(t, err)

// Apply a migration in the foo schema that references the function in the public schema
err = mig.Start(ctx, &migrations.Migration{
Name: "01_raw_sql",
Operations: migrations.Operations{
&migrations.OpRawSQL{
Up: "SELECT say_hello()",
},
},
})
require.NoError(t, err)

// Complete the migration
err = mig.Complete(ctx)
require.NoError(t, err)

// No assertions required as the migration would have failed if the
// function reference was not found
})
}

func createTableOp(tableName string) *migrations.OpCreateTable {
return &migrations.OpCreateTable{
Name: tableName,
Expand Down
12 changes: 12 additions & 0 deletions pkg/roll/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ type options struct {
// disable creation of version schema for raw SQL migrations
noVersionSchemaForRawSQL bool

// additional entries to add to the search_path during migration execution
searchPath []string

migrationHooks MigrationHooks
}

Expand Down Expand Up @@ -86,3 +89,12 @@ func WithSQLTransformer(transformer migrations.SQLTransformer) Option {
o.sqlTransformer = transformer
}
}

// WithSearchPath sets the search_path to use during migration execution. The
// schema in which the migration is run is always included in the search path,
// regardless of this setting.
func WithSearchPath(schemas ...string) Option {
return func(o *options) {
o.searchPath = schemas
}
}
4 changes: 3 additions & 1 deletion pkg/roll/roll.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"database/sql"
"fmt"
"strings"

"github.com/lib/pq"

Expand Down Expand Up @@ -78,7 +79,8 @@ func setupConn(ctx context.Context, pgURL, schema string, options options) (*sql
dsn = pgURL
}

dsn += " search_path=" + schema
searchPath := append([]string{schema}, options.searchPath...)
dsn += " search_path=" + strings.Join(searchPath, ",")

conn, err := sql.Open("postgres", dsn)
if err != nil {
Expand Down

0 comments on commit 092313a

Please sign in to comment.