Skip to content

Commit

Permalink
feat: allow in-place renaming of Snowflake schemas (#972)
Browse files Browse the repository at this point in the history
  • Loading branch information
philippeboyd committed Apr 14, 2022
1 parent 1e21100 commit 2a18b96
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 9 deletions.
11 changes: 10 additions & 1 deletion pkg/resources/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ var schemaSchema = map[string]*schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "Specifies the identifier for the schema; must be unique for the database in which the schema is created.",
ForceNew: true,
},
"database": {
Type: schema.TypeString,
Expand Down Expand Up @@ -272,6 +271,16 @@ func UpdateSchema(d *schema.ResourceData, meta interface{}) error {
builder := snowflake.Schema(schema).WithDB(dbName)

db := meta.(*sql.DB)
if d.HasChange("name") {
name := d.Get("name")
q := builder.Rename(name.(string))
err := snowflake.Exec(db, q)
if err != nil {
return errors.Wrapf(err, "error updating schema name on %v", d.Id())
}
d.SetId(fmt.Sprintf("%v|%v", dbName, name.(string)))
}

if d.HasChange("comment") {
comment := d.Get("comment")
q := builder.ChangeComment(comment.(string))
Expand Down
45 changes: 39 additions & 6 deletions pkg/resources/schema_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ import (
)

func TestAcc_Schema(t *testing.T) {
accName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
schemaName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))

resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
Steps: []resource.TestStep{
{
Config: schemaConfig(accName),
Config: schemaConfig(databaseName, schemaName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("snowflake_schema.test", "name", accName),
resource.TestCheckResourceAttr("snowflake_schema.test", "database", accName),
resource.TestCheckResourceAttr("snowflake_schema.test", "name", schemaName),
resource.TestCheckResourceAttr("snowflake_schema.test", "database", databaseName),
resource.TestCheckResourceAttr("snowflake_schema.test", "comment", "Terraform acceptance test"),
checkBool("snowflake_schema.test", "is_transient", false), // this is from user_acceptance_test.go
checkBool("snowflake_schema.test", "is_managed", false),
Expand All @@ -29,7 +30,39 @@ func TestAcc_Schema(t *testing.T) {
})
}

func schemaConfig(n string) string {
func TestAcc_SchemaRename(t *testing.T) {
databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
oldSchemaName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
newSchemaName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))

resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
Steps: []resource.TestStep{
{
Config: schemaConfig(databaseName, oldSchemaName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("snowflake_schema.test", "name", oldSchemaName),
resource.TestCheckResourceAttr("snowflake_schema.test", "database", databaseName),
resource.TestCheckResourceAttr("snowflake_schema.test", "comment", "Terraform acceptance test"),
checkBool("snowflake_schema.test", "is_transient", false), // this is from user_acceptance_test.go
checkBool("snowflake_schema.test", "is_managed", false),
),
},
{
Config: schemaConfig(databaseName, newSchemaName),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("snowflake_schema.test", "name", newSchemaName),
resource.TestCheckResourceAttr("snowflake_schema.test", "database", databaseName),
resource.TestCheckResourceAttr("snowflake_schema.test", "comment", "Terraform acceptance test"),
checkBool("snowflake_schema.test", "is_transient", false), // this is from user_acceptance_test.go
checkBool("snowflake_schema.test", "is_managed", false),
),
},
},
})
}

func schemaConfig(databaseName string, schemaName string) string {
return fmt.Sprintf(`
resource "snowflake_database" "test" {
name = "%v"
Expand All @@ -41,5 +74,5 @@ resource "snowflake_schema" "test" {
database = snowflake_database.test.name
comment = "Terraform acceptance test"
}
`, n, n)
`, databaseName, schemaName)
}
8 changes: 6 additions & 2 deletions pkg/snowflake/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,17 @@ func (sb *SchemaBuilder) Create() string {

// Rename returns the SQL query that will rename the schema.
func (sb *SchemaBuilder) Rename(newName string) string {
return fmt.Sprintf(`ALTER SCHEMA %v RENAME TO "%v"`, sb.QualifiedName(), newName)
oldName := sb.QualifiedName()
sb.name = newName
return fmt.Sprintf(`ALTER SCHEMA %v RENAME TO %v`, oldName, sb.QualifiedName())
}

// Swap returns the SQL query that Swaps all objects (tables, views, etc.) and
// metadata, including identifiers, between the two specified schemas.
func (sb *SchemaBuilder) Swap(targetSchema string) string {
return fmt.Sprintf(`ALTER SCHEMA %v SWAP WITH "%v"`, sb.QualifiedName(), targetSchema)
sourceSchema := sb.QualifiedName()
sb.name = targetSchema
return fmt.Sprintf(`ALTER SCHEMA %v SWAP WITH %v`, sourceSchema, sb.QualifiedName())
}

// ChangeComment returns the SQL query that will update the comment on the schema.
Expand Down

0 comments on commit 2a18b96

Please sign in to comment.