Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Use materialized views and views from SDK #2448

Merged
merged 22 commits into from
Feb 1, 2024
Merged
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9f18404
Use SDK for materialized views datasource
sfc-gh-asawicki Jan 29, 2024
300e1cc
Use SDK for views datasource
sfc-gh-asawicki Jan 29, 2024
2aae3e3
Use SDK for drop views and materialized views
sfc-gh-asawicki Jan 29, 2024
2130221
Use SDK for create views and materialized views
sfc-gh-asawicki Jan 29, 2024
922af6b
Use SDK for read views and materialized views
sfc-gh-asawicki Jan 29, 2024
f294fea
Use SDK for update views and materialized views
sfc-gh-asawicki Jan 29, 2024
802d42b
Set/unset tags for materialized view
sfc-gh-asawicki Jan 30, 2024
7c95cf2
Update TODO comments with issue numbers
sfc-gh-asawicki Jan 30, 2024
434ee81
Migrate existing tests (WIP)
sfc-gh-asawicki Jan 30, 2024
0caefe0
Pass view tests
sfc-gh-asawicki Jan 30, 2024
ca7b868
Pass materialized view tests
sfc-gh-asawicki Jan 30, 2024
9ed83b6
Test changing the query externally
sfc-gh-asawicki Jan 30, 2024
b010534
Test set/unset tags for materialized view
sfc-gh-asawicki Jan 30, 2024
ea6a992
Test rename for materialized view
sfc-gh-asawicki Jan 30, 2024
0528f7a
Add tests for rename and tags to view
sfc-gh-asawicki Jan 30, 2024
b3447ab
Add conflicts with to notification integration
sfc-gh-asawicki Jan 30, 2024
986b644
Remove test and add test for #2085
sfc-gh-asawicki Jan 30, 2024
a9454d1
Fix test
sfc-gh-asawicki Jan 30, 2024
c4f4b88
Add tests to SDK
sfc-gh-asawicki Jan 31, 2024
9dfb9dd
Fixed after reviews
sfc-gh-asawicki Jan 31, 2024
3ef3f37
Merge branch 'main' into use-materialized-views-and-views-from-sdk
sfc-gh-asawicki Jan 31, 2024
7d556fd
Use acceptance test warehouse
sfc-gh-asawicki Jan 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 21 additions & 23 deletions pkg/datasources/materialized_views.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package datasources

import (
"context"
"database/sql"
"errors"
"fmt"
"log"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

@@ -58,34 +58,32 @@ func MaterializedViews() *schema.Resource {

func ReadMaterializedViews(d *schema.ResourceData, meta interface{}) error {
db := meta.(*sql.DB)
ctx := context.Background()
client := sdk.NewClientFromDB(db)
databaseName := d.Get("database").(string)
schemaName := d.Get("schema").(string)

currentViews, err := snowflake.ListMaterializedViews(databaseName, schemaName, db)
if errors.Is(err, sql.ErrNoRows) {
// If not found, mark resource to be removed from state file during apply or refresh
log.Printf("[DEBUG] materialized views in schema (%s) not found", d.Id())
d.SetId("")
return nil
} else if err != nil {
log.Printf("[DEBUG] materialized unable to parse views in schema (%s)", d.Id())
schemaId := sdk.NewDatabaseObjectIdentifier(databaseName, schemaName)
extractedMaterializedViews, err := client.MaterializedViews.Show(ctx, sdk.NewShowMaterializedViewRequest().WithIn(
&sdk.In{Schema: schemaId},
))
if err != nil {
log.Printf("[DEBUG] failed when searching materialized views in schema (%s), err = %s", schemaId.FullyQualifiedName(), err.Error())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this throw an error if no materialized views are found?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, but it can fail for other reasons (e.g. not existing schema - added test to SDK to show that).

d.SetId("")
return nil
}

views := []map[string]interface{}{}

for _, view := range currentViews {
viewMap := map[string]interface{}{}

viewMap["name"] = view.Name.String
viewMap["database"] = view.DatabaseName.String
viewMap["schema"] = view.SchemaName.String
viewMap["comment"] = view.Comment.String
materializedViews := make([]map[string]any, len(extractedMaterializedViews))

views = append(views, viewMap)
for i, materializedView := range extractedMaterializedViews {
materializedViews[i] = map[string]any{
"name": materializedView.Name,
"database": materializedView.DatabaseName,
"schema": materializedView.SchemaName,
"comment": materializedView.Comment,
}
}

d.SetId(fmt.Sprintf(`%v|%v`, databaseName, schemaName))
return d.Set("materialized_views", views)
d.SetId(helpers.EncodeSnowflakeID(databaseName, schemaName))
return d.Set("materialized_views", materializedViews)
}
11 changes: 9 additions & 2 deletions pkg/datasources/materialized_views_acceptance_test.go
Original file line number Diff line number Diff line change
@@ -5,8 +5,11 @@ import (
"strings"
"testing"

acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/tfversion"
)

func TestAcc_MaterializedViews(t *testing.T) {
@@ -15,8 +18,12 @@ func TestAcc_MaterializedViews(t *testing.T) {
schemaName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
tableName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
viewName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
PreCheck: func() { acc.TestAccPreCheck(t) },
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.RequireAbove(tfversion.Version1_5_0),
},
CheckDestroy: nil,
Steps: []resource.TestStep{
{
42 changes: 20 additions & 22 deletions pkg/datasources/views.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package datasources

import (
"context"
"database/sql"
"errors"
"fmt"
"log"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/snowflake"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

@@ -58,34 +58,32 @@ func Views() *schema.Resource {

func ReadViews(d *schema.ResourceData, meta interface{}) error {
db := meta.(*sql.DB)
ctx := context.Background()
client := sdk.NewClientFromDB(db)
databaseName := d.Get("database").(string)
schemaName := d.Get("schema").(string)

currentViews, err := snowflake.ListViews(databaseName, schemaName, db)
if errors.Is(err, sql.ErrNoRows) {
// If not found, mark resource to be removed from state file during apply or refresh
log.Printf("[DEBUG] views in schema (%s) not found", d.Id())
d.SetId("")
return nil
} else if err != nil {
log.Printf("[DEBUG] unable to parse views in schema (%s)", d.Id())
schemaId := sdk.NewDatabaseObjectIdentifier(databaseName, schemaName)
extractedViews, err := client.Views.Show(ctx, sdk.NewShowViewRequest().WithIn(
&sdk.In{Schema: schemaId},
))
if err != nil {
log.Printf("[DEBUG] failed when searching views in schema (%s), err = %s", schemaId.FullyQualifiedName(), err.Error())
d.SetId("")
return nil
}

views := []map[string]interface{}{}

for _, view := range currentViews {
viewMap := map[string]interface{}{}

viewMap["name"] = view.Name.String
viewMap["database"] = view.DatabaseName.String
viewMap["schema"] = view.SchemaName.String
viewMap["comment"] = view.Comment.String
views := make([]map[string]any, len(extractedViews))

views = append(views, viewMap)
for i, view := range extractedViews {
views[i] = map[string]any{
"name": view.Name,
"database": view.DatabaseName,
"schema": view.SchemaName,
"comment": view.Comment,
}
}

d.SetId(fmt.Sprintf(`%v|%v`, databaseName, schemaName))
d.SetId(helpers.EncodeSnowflakeID(databaseName, schemaName))
return d.Set("views", views)
}
9 changes: 8 additions & 1 deletion pkg/datasources/views_acceptance_test.go
Original file line number Diff line number Diff line change
@@ -5,16 +5,23 @@ import (
"strings"
"testing"

acc "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance"

"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/tfversion"
)

func TestAcc_Views(t *testing.T) {
databaseName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
schemaName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
viewName := strings.ToUpper(acctest.RandStringFromCharSet(10, acctest.CharSetAlpha))
resource.ParallelTest(t, resource.TestCase{
Providers: providers(),
ProtoV6ProviderFactories: acc.TestAccProtoV6ProviderFactories,
PreCheck: func() { acc.TestAccPreCheck(t) },
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
tfversion.RequireAbove(tfversion.Version1_5_0),
},
CheckDestroy: nil,
Steps: []resource.TestStep{
{
25 changes: 14 additions & 11 deletions pkg/resources/helpers.go
Original file line number Diff line number Diff line change
@@ -74,27 +74,30 @@ func getTagObjectIdentifier(v map[string]any) sdk.ObjectIdentifier {

func getPropertyTags(d *schema.ResourceData, key string) []sdk.TagAssociation {
if from, ok := d.GetOk(key); ok {
tags := from.([]any)
to := make([]sdk.TagAssociation, len(tags))
for i, t := range tags {
v := t.(map[string]any)
to[i] = sdk.TagAssociation{
Name: getTagObjectIdentifier(v),
Value: v["value"].(string),
}
}
return to
return getTagsFromList(from.([]any))
}
return nil
}

func getTagsFromList(tags []any) []sdk.TagAssociation {
to := make([]sdk.TagAssociation, len(tags))
for i, t := range tags {
v := t.(map[string]any)
to[i] = sdk.TagAssociation{
Name: getTagObjectIdentifier(v),
Value: v["value"].(string),
}
}
return to
}

func GetTagsDiff(d *schema.ResourceData, key string) (unsetTags []sdk.ObjectIdentifier, setTags []sdk.TagAssociation) {
o, n := d.GetChange(key)
removed, added, changed := getTags(o).diffs(getTags(n))

unsetTags = make([]sdk.ObjectIdentifier, len(removed))
for i, t := range removed {
unsetTags[i] = sdk.NewDatabaseObjectIdentifier(t.database, t.name)
unsetTags[i] = sdk.NewSchemaObjectIdentifier(t.database, t.schema, t.name)
}

setTags = make([]sdk.TagAssociation, len(added)+len(changed))
Loading