diff --git a/pkg/sdk/application_packages_def.go b/pkg/sdk/application_packages_def.go new file mode 100644 index 0000000000..0c7bba0c8a --- /dev/null +++ b/pkg/sdk/application_packages_def.go @@ -0,0 +1,160 @@ +package sdk + +import g "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/poc/generator" + +//go:generate go run ./poc/main.go + +// https://medium.com/snowflake/hello-world-snowflake-native-apps-76e1ce82e1be + +var applicationPackageModifyReleaseDirective = g.NewQueryStruct("ModifyReleaseDirective"). + Text("ReleaseDirective", g.KeywordOptions().NoQuotes().Required()). + TextAssignment("VERSION", g.ParameterOptions().NoQuotes().Required()). + NumberAssignment("PATCH", g.ParameterOptions().NoQuotes().Required()) + +var applicationPackageSetReleaseDirective = g.NewQueryStruct("SetReleaseDirective"). + Text("ReleaseDirective", g.KeywordOptions().NoQuotes().Required()). + PredefinedQueryStructField("Accounts", "[]string", g.ParameterOptions().MustParentheses().NoQuotes().Required().SQL("ACCOUNTS")). + TextAssignment("VERSION", g.ParameterOptions().NoQuotes().Required()). + NumberAssignment("PATCH", g.ParameterOptions().NoQuotes().Required()) + +var applicationPackageUnsetReleaseDirective = g.NewQueryStruct("UnsetReleaseDirective"). + Text("ReleaseDirective", g.KeywordOptions().NoQuotes().Required()) + +var applicationPackageSetDefaultReleaseDirective = g.NewQueryStruct("SetDefaultReleaseDirective"). + TextAssignment("VERSION", g.ParameterOptions().NoQuotes().Required()). + NumberAssignment("PATCH", g.ParameterOptions().NoQuotes().Required()) + +var applicationPackageAddVersion = g.NewQueryStruct("AddVersion"). + OptionalText("VersionIdentifier", g.KeywordOptions().NoQuotes()). + TextAssignment("USING", g.ParameterOptions().NoEquals().SingleQuotes().Required()). + OptionalTextAssignment("Label", g.ParameterOptions().SingleQuotes()) + +var applicationPackageDropVersion = g.NewQueryStruct("DropVersion"). + Text("VersionIdentifier", g.KeywordOptions().NoQuotes().Required()) + +var applicationPackageAddPatchForVersion = g.NewQueryStruct("AddPatchForVersion"). + OptionalText("VersionIdentifier", g.KeywordOptions().NoQuotes().Required()). + TextAssignment("USING", g.ParameterOptions().NoEquals().SingleQuotes().Required()). + OptionalTextAssignment("Label", g.ParameterOptions().SingleQuotes()) + +var applicationPackageSet = g.NewQueryStruct("ApplicationPackageSet"). + OptionalNumberAssignment("DATA_RETENTION_TIME_IN_DAYS", g.ParameterOptions().NoQuotes()). + OptionalNumberAssignment("MAX_DATA_EXTENSION_TIME_IN_DAYS", g.ParameterOptions().NoQuotes()). + OptionalTextAssignment("DEFAULT_DDL_COLLATION", g.ParameterOptions().SingleQuotes()). + OptionalTextAssignment("COMMENT", g.ParameterOptions().SingleQuotes()). + PredefinedQueryStructField("Distribution", "*Distribution", g.ParameterOptions().SQL("DISTRIBUTION")) + +var ApplicationPackagesDef = g.NewInterface( + "ApplicationPackages", + "ApplicationPackage", + g.KindOfT[AccountObjectIdentifier](), +).CreateOperation( + "https://docs.snowflake.com/en/sql-reference/sql/create-application-package", + g.NewQueryStruct("CreateApplicationPackage"). + Create(). + SQL("APPLICATION PACKAGE"). + IfNotExists(). + Name(). + OptionalNumberAssignment("DATA_RETENTION_TIME_IN_DAYS", g.ParameterOptions().NoQuotes()). + OptionalNumberAssignment("MAX_DATA_EXTENSION_TIME_IN_DAYS", g.ParameterOptions().NoQuotes()). + OptionalTextAssignment("DEFAULT_DDL_COLLATION", g.ParameterOptions().SingleQuotes()). + OptionalTextAssignment("COMMENT", g.ParameterOptions().SingleQuotes()). + PredefinedQueryStructField("Distribution", "*Distribution", g.ParameterOptions().SQL("DISTRIBUTION")). + OptionalTags(). + WithValidation(g.ValidIdentifier, "name"), +).AlterOperation( + "https://docs.snowflake.com/en/sql-reference/sql/alter-application-package", + g.NewQueryStruct("AlterApplicationPackage"). + Alter(). + SQL("APPLICATION PACKAGE"). + IfExists(). + Name(). + OptionalQueryStructField( + "Set", + applicationPackageSet, + g.KeywordOptions().SQL("SET"), + ). + OptionalSQL("UNSET DATA_RETENTION_TIME_IN_DAYS"). + OptionalSQL("UNSET MAX_DATA_EXTENSION_TIME_IN_DAYS"). + OptionalSQL("UNSET DEFAULT_DDL_COLLATION"). + OptionalSQL("UNSET COMMENT"). + OptionalSQL("UNSET DISTRIBUTION"). + OptionalQueryStructField( + "ModifyReleaseDirective", + applicationPackageModifyReleaseDirective, + g.KeywordOptions().SQL("MODIFY RELEASE DIRECTIVE"), + ). + OptionalQueryStructField( + "SetDefaultReleaseDirective", + applicationPackageSetDefaultReleaseDirective, + g.KeywordOptions().SQL("SET DEFAULT RELEASE DIRECTIVE"), + ). + OptionalQueryStructField( + "SetReleaseDirective", + applicationPackageSetReleaseDirective, + g.KeywordOptions().SQL("SET RELEASE DIRECTIVE"), + ). + OptionalQueryStructField( + "UnsetReleaseDirective", + applicationPackageUnsetReleaseDirective, + g.KeywordOptions().SQL("UNSET RELEASE DIRECTIVE"), + ). + OptionalQueryStructField( + "AddVersion", + applicationPackageAddVersion, + g.KeywordOptions().SQL("ADD VERSION"), + ). + OptionalQueryStructField( + "DropVersion", + applicationPackageDropVersion, + g.KeywordOptions().SQL("DROP VERSION"), + ). + OptionalQueryStructField( + "AddPatchForVersion", + applicationPackageAddPatchForVersion, + g.KeywordOptions().SQL("ADD PATCH FOR VERSION"), + ). + OptionalSetTags(). + OptionalUnsetTags(). + WithValidation(g.ValidIdentifier, "name"). + WithValidation(g.ExactlyOneValueSet, "Set", "UnsetDataRetentionTimeInDays", "UnsetMaxDataExtensionTimeInDays", "UnsetDefaultDdlCollation", "UnsetComment", "UnsetDistribution", "ModifyReleaseDirective", "SetDefaultReleaseDirective", "SetReleaseDirective", "UnsetReleaseDirective", "AddVersion", "DropVersion", "AddPatchForVersion", "SetTags", "UnsetTags"), +).DropOperation( + "https://docs.snowflake.com/en/sql-reference/sql/drop-application-package", + g.NewQueryStruct("DropApplicationPackage"). + Drop(). + SQL("APPLICATION PACKAGE"). + Name(). + WithValidation(g.ValidIdentifier, "name"), +).ShowOperation( + "https://docs.snowflake.com/en/sql-reference/sql/show-application-packages", + g.DbStruct("applicationPackageRow"). + Field("created_on", "string"). + Field("name", "string"). + Field("is_default", "string"). + Field("is_current", "string"). + Field("distribution", "string"). + Field("owner", "string"). + Field("comment", "string"). + Field("retention_time", "int"). + Field("options", "string"). + Field("dropped_on", "sql.NullString"). + Field("application_class", "sql.NullString"), + g.PlainStruct("ApplicationPackage"). + Field("CreatedOn", "string"). + Field("Name", "string"). + Field("IsDefault", "bool"). + Field("IsCurrent", "bool"). + Field("Distribution", "string"). + Field("Owner", "string"). + Field("Comment", "string"). + Field("RetentionTime", "int"). + Field("Options", "string"). + Field("DroppedOn", "string"). + Field("ApplicationClass", "string"), + g.NewQueryStruct("ShowApplicationPackages"). + Show(). + SQL("APPLICATION PACKAGES"). + OptionalLike(). + OptionalStartsWith(). + OptionalLimit(), +).ShowByIdOperation() diff --git a/pkg/sdk/application_packages_dto_builders_gen.go b/pkg/sdk/application_packages_dto_builders_gen.go new file mode 100644 index 0000000000..032e7b61ba --- /dev/null +++ b/pkg/sdk/application_packages_dto_builders_gen.go @@ -0,0 +1,277 @@ +// Code generated by dto builder generator; DO NOT EDIT. + +package sdk + +import () + +func NewCreateApplicationPackageRequest( + name AccountObjectIdentifier, +) *CreateApplicationPackageRequest { + s := CreateApplicationPackageRequest{} + s.name = name + return &s +} + +func (s *CreateApplicationPackageRequest) WithIfNotExists(IfNotExists *bool) *CreateApplicationPackageRequest { + s.IfNotExists = IfNotExists + return s +} + +func (s *CreateApplicationPackageRequest) WithDataRetentionTimeInDays(DataRetentionTimeInDays *int) *CreateApplicationPackageRequest { + s.DataRetentionTimeInDays = DataRetentionTimeInDays + return s +} + +func (s *CreateApplicationPackageRequest) WithMaxDataExtensionTimeInDays(MaxDataExtensionTimeInDays *int) *CreateApplicationPackageRequest { + s.MaxDataExtensionTimeInDays = MaxDataExtensionTimeInDays + return s +} + +func (s *CreateApplicationPackageRequest) WithDefaultDdlCollation(DefaultDdlCollation *string) *CreateApplicationPackageRequest { + s.DefaultDdlCollation = DefaultDdlCollation + return s +} + +func (s *CreateApplicationPackageRequest) WithComment(Comment *string) *CreateApplicationPackageRequest { + s.Comment = Comment + return s +} + +func (s *CreateApplicationPackageRequest) WithDistribution(Distribution *Distribution) *CreateApplicationPackageRequest { + s.Distribution = Distribution + return s +} + +func (s *CreateApplicationPackageRequest) WithTag(Tag []TagAssociation) *CreateApplicationPackageRequest { + s.Tag = Tag + return s +} + +func NewAlterApplicationPackageRequest( + name AccountObjectIdentifier, +) *AlterApplicationPackageRequest { + s := AlterApplicationPackageRequest{} + s.name = name + return &s +} + +func (s *AlterApplicationPackageRequest) WithIfExists(IfExists *bool) *AlterApplicationPackageRequest { + s.IfExists = IfExists + return s +} + +func (s *AlterApplicationPackageRequest) WithSet(Set *ApplicationPackageSetRequest) *AlterApplicationPackageRequest { + s.Set = Set + return s +} + +func (s *AlterApplicationPackageRequest) WithUnsetDataRetentionTimeInDays(UnsetDataRetentionTimeInDays *bool) *AlterApplicationPackageRequest { + s.UnsetDataRetentionTimeInDays = UnsetDataRetentionTimeInDays + return s +} + +func (s *AlterApplicationPackageRequest) WithUnsetMaxDataExtensionTimeInDays(UnsetMaxDataExtensionTimeInDays *bool) *AlterApplicationPackageRequest { + s.UnsetMaxDataExtensionTimeInDays = UnsetMaxDataExtensionTimeInDays + return s +} + +func (s *AlterApplicationPackageRequest) WithUnsetDefaultDdlCollation(UnsetDefaultDdlCollation *bool) *AlterApplicationPackageRequest { + s.UnsetDefaultDdlCollation = UnsetDefaultDdlCollation + return s +} + +func (s *AlterApplicationPackageRequest) WithUnsetComment(UnsetComment *bool) *AlterApplicationPackageRequest { + s.UnsetComment = UnsetComment + return s +} + +func (s *AlterApplicationPackageRequest) WithUnsetDistribution(UnsetDistribution *bool) *AlterApplicationPackageRequest { + s.UnsetDistribution = UnsetDistribution + return s +} + +func (s *AlterApplicationPackageRequest) WithModifyReleaseDirective(ModifyReleaseDirective *ModifyReleaseDirectiveRequest) *AlterApplicationPackageRequest { + s.ModifyReleaseDirective = ModifyReleaseDirective + return s +} + +func (s *AlterApplicationPackageRequest) WithSetDefaultReleaseDirective(SetDefaultReleaseDirective *SetDefaultReleaseDirectiveRequest) *AlterApplicationPackageRequest { + s.SetDefaultReleaseDirective = SetDefaultReleaseDirective + return s +} + +func (s *AlterApplicationPackageRequest) WithSetReleaseDirective(SetReleaseDirective *SetReleaseDirectiveRequest) *AlterApplicationPackageRequest { + s.SetReleaseDirective = SetReleaseDirective + return s +} + +func (s *AlterApplicationPackageRequest) WithUnsetReleaseDirective(UnsetReleaseDirective *UnsetReleaseDirectiveRequest) *AlterApplicationPackageRequest { + s.UnsetReleaseDirective = UnsetReleaseDirective + return s +} + +func (s *AlterApplicationPackageRequest) WithAddVersion(AddVersion *AddVersionRequest) *AlterApplicationPackageRequest { + s.AddVersion = AddVersion + return s +} + +func (s *AlterApplicationPackageRequest) WithDropVersion(DropVersion *DropVersionRequest) *AlterApplicationPackageRequest { + s.DropVersion = DropVersion + return s +} + +func (s *AlterApplicationPackageRequest) WithAddPatchForVersion(AddPatchForVersion *AddPatchForVersionRequest) *AlterApplicationPackageRequest { + s.AddPatchForVersion = AddPatchForVersion + return s +} + +func (s *AlterApplicationPackageRequest) WithSetTags(SetTags []TagAssociation) *AlterApplicationPackageRequest { + s.SetTags = SetTags + return s +} + +func (s *AlterApplicationPackageRequest) WithUnsetTags(UnsetTags []ObjectIdentifier) *AlterApplicationPackageRequest { + s.UnsetTags = UnsetTags + return s +} + +func NewApplicationPackageSetRequest() *ApplicationPackageSetRequest { + return &ApplicationPackageSetRequest{} +} + +func (s *ApplicationPackageSetRequest) WithDataRetentionTimeInDays(DataRetentionTimeInDays *int) *ApplicationPackageSetRequest { + s.DataRetentionTimeInDays = DataRetentionTimeInDays + return s +} + +func (s *ApplicationPackageSetRequest) WithMaxDataExtensionTimeInDays(MaxDataExtensionTimeInDays *int) *ApplicationPackageSetRequest { + s.MaxDataExtensionTimeInDays = MaxDataExtensionTimeInDays + return s +} + +func (s *ApplicationPackageSetRequest) WithDefaultDdlCollation(DefaultDdlCollation *string) *ApplicationPackageSetRequest { + s.DefaultDdlCollation = DefaultDdlCollation + return s +} + +func (s *ApplicationPackageSetRequest) WithComment(Comment *string) *ApplicationPackageSetRequest { + s.Comment = Comment + return s +} + +func (s *ApplicationPackageSetRequest) WithDistribution(Distribution *Distribution) *ApplicationPackageSetRequest { + s.Distribution = Distribution + return s +} + +func NewModifyReleaseDirectiveRequest( + ReleaseDirective string, + Version string, + Patch int, +) *ModifyReleaseDirectiveRequest { + s := ModifyReleaseDirectiveRequest{} + s.ReleaseDirective = ReleaseDirective + s.Version = Version + s.Patch = Patch + return &s +} + +func NewSetDefaultReleaseDirectiveRequest( + Version string, + Patch int, +) *SetDefaultReleaseDirectiveRequest { + s := SetDefaultReleaseDirectiveRequest{} + s.Version = Version + s.Patch = Patch + return &s +} + +func NewSetReleaseDirectiveRequest( + ReleaseDirective string, + Accounts []string, + Version string, + Patch int, +) *SetReleaseDirectiveRequest { + s := SetReleaseDirectiveRequest{} + s.ReleaseDirective = ReleaseDirective + s.Accounts = Accounts + s.Version = Version + s.Patch = Patch + return &s +} + +func NewUnsetReleaseDirectiveRequest( + ReleaseDirective string, +) *UnsetReleaseDirectiveRequest { + s := UnsetReleaseDirectiveRequest{} + s.ReleaseDirective = ReleaseDirective + return &s +} + +func NewAddVersionRequest( + Using string, +) *AddVersionRequest { + s := AddVersionRequest{} + s.Using = Using + return &s +} + +func (s *AddVersionRequest) WithVersionIdentifier(VersionIdentifier *string) *AddVersionRequest { + s.VersionIdentifier = VersionIdentifier + return s +} + +func (s *AddVersionRequest) WithLabel(Label *string) *AddVersionRequest { + s.Label = Label + return s +} + +func NewDropVersionRequest( + VersionIdentifier string, +) *DropVersionRequest { + s := DropVersionRequest{} + s.VersionIdentifier = VersionIdentifier + return &s +} + +func NewAddPatchForVersionRequest( + VersionIdentifier *string, + Using string, +) *AddPatchForVersionRequest { + s := AddPatchForVersionRequest{} + s.VersionIdentifier = VersionIdentifier + s.Using = Using + return &s +} + +func (s *AddPatchForVersionRequest) WithLabel(Label *string) *AddPatchForVersionRequest { + s.Label = Label + return s +} + +func NewDropApplicationPackageRequest( + name AccountObjectIdentifier, +) *DropApplicationPackageRequest { + s := DropApplicationPackageRequest{} + s.name = name + return &s +} + +func NewShowApplicationPackageRequest() *ShowApplicationPackageRequest { + return &ShowApplicationPackageRequest{} +} + +func (s *ShowApplicationPackageRequest) WithLike(Like *Like) *ShowApplicationPackageRequest { + s.Like = Like + return s +} + +func (s *ShowApplicationPackageRequest) WithStartsWith(StartsWith *string) *ShowApplicationPackageRequest { + s.StartsWith = StartsWith + return s +} + +func (s *ShowApplicationPackageRequest) WithLimit(Limit *LimitFrom) *ShowApplicationPackageRequest { + s.Limit = Limit + return s +} diff --git a/pkg/sdk/application_packages_dto_gen.go b/pkg/sdk/application_packages_dto_gen.go new file mode 100644 index 0000000000..5c23b0dbab --- /dev/null +++ b/pkg/sdk/application_packages_dto_gen.go @@ -0,0 +1,97 @@ +package sdk + +//go:generate go run ./dto-builder-generator/main.go + +var ( + _ optionsProvider[CreateApplicationPackageOptions] = new(CreateApplicationPackageRequest) + _ optionsProvider[AlterApplicationPackageOptions] = new(AlterApplicationPackageRequest) + _ optionsProvider[DropApplicationPackageOptions] = new(DropApplicationPackageRequest) + _ optionsProvider[ShowApplicationPackageOptions] = new(ShowApplicationPackageRequest) +) + +type CreateApplicationPackageRequest struct { + IfNotExists *bool + name AccountObjectIdentifier // required + DataRetentionTimeInDays *int + MaxDataExtensionTimeInDays *int + DefaultDdlCollation *string + Comment *string + Distribution *Distribution + Tag []TagAssociation +} + +type AlterApplicationPackageRequest struct { + IfExists *bool + name AccountObjectIdentifier // required + Set *ApplicationPackageSetRequest + UnsetDataRetentionTimeInDays *bool + UnsetMaxDataExtensionTimeInDays *bool + UnsetDefaultDdlCollation *bool + UnsetComment *bool + UnsetDistribution *bool + ModifyReleaseDirective *ModifyReleaseDirectiveRequest + SetDefaultReleaseDirective *SetDefaultReleaseDirectiveRequest + SetReleaseDirective *SetReleaseDirectiveRequest + UnsetReleaseDirective *UnsetReleaseDirectiveRequest + AddVersion *AddVersionRequest + DropVersion *DropVersionRequest + AddPatchForVersion *AddPatchForVersionRequest + SetTags []TagAssociation + UnsetTags []ObjectIdentifier +} + +type ApplicationPackageSetRequest struct { + DataRetentionTimeInDays *int + MaxDataExtensionTimeInDays *int + DefaultDdlCollation *string + Comment *string + Distribution *Distribution +} + +type ModifyReleaseDirectiveRequest struct { + ReleaseDirective string // required + Version string // required + Patch int // required +} + +type SetDefaultReleaseDirectiveRequest struct { + Version string // required + Patch int // required +} + +type SetReleaseDirectiveRequest struct { + ReleaseDirective string // required + Accounts []string // required + Version string // required + Patch int // required +} + +type UnsetReleaseDirectiveRequest struct { + ReleaseDirective string // required +} + +type AddVersionRequest struct { + VersionIdentifier *string + Using string // required + Label *string +} + +type DropVersionRequest struct { + VersionIdentifier string // required +} + +type AddPatchForVersionRequest struct { + VersionIdentifier *string // required + Using string // required + Label *string +} + +type DropApplicationPackageRequest struct { + name AccountObjectIdentifier // required +} + +type ShowApplicationPackageRequest struct { + Like *Like + StartsWith *string + Limit *LimitFrom +} diff --git a/pkg/sdk/application_packages_gen.go b/pkg/sdk/application_packages_gen.go new file mode 100644 index 0000000000..d46f2898b2 --- /dev/null +++ b/pkg/sdk/application_packages_gen.go @@ -0,0 +1,141 @@ +package sdk + +import ( + "context" + "database/sql" +) + +type ApplicationPackages interface { + Create(ctx context.Context, request *CreateApplicationPackageRequest) error + Alter(ctx context.Context, request *AlterApplicationPackageRequest) error + Drop(ctx context.Context, request *DropApplicationPackageRequest) error + Show(ctx context.Context, request *ShowApplicationPackageRequest) ([]ApplicationPackage, error) + ShowByID(ctx context.Context, id AccountObjectIdentifier) (*ApplicationPackage, error) +} + +// CreateApplicationPackageOptions is based on https://docs.snowflake.com/en/sql-reference/sql/create-application-package. +type CreateApplicationPackageOptions struct { + create bool `ddl:"static" sql:"CREATE"` + applicationPackage bool `ddl:"static" sql:"APPLICATION PACKAGE"` + IfNotExists *bool `ddl:"keyword" sql:"IF NOT EXISTS"` + name AccountObjectIdentifier `ddl:"identifier"` + DataRetentionTimeInDays *int `ddl:"parameter,no_quotes" sql:"DATA_RETENTION_TIME_IN_DAYS"` + MaxDataExtensionTimeInDays *int `ddl:"parameter,no_quotes" sql:"MAX_DATA_EXTENSION_TIME_IN_DAYS"` + DefaultDdlCollation *string `ddl:"parameter,single_quotes" sql:"DEFAULT_DDL_COLLATION"` + Comment *string `ddl:"parameter,single_quotes" sql:"COMMENT"` + Distribution *Distribution `ddl:"parameter" sql:"DISTRIBUTION"` + Tag []TagAssociation `ddl:"keyword,parentheses" sql:"TAG"` +} + +// AlterApplicationPackageOptions is based on https://docs.snowflake.com/en/sql-reference/sql/alter-application-package. +type AlterApplicationPackageOptions struct { + alter bool `ddl:"static" sql:"ALTER"` + applicationPackage bool `ddl:"static" sql:"APPLICATION PACKAGE"` + IfExists *bool `ddl:"keyword" sql:"IF EXISTS"` + name AccountObjectIdentifier `ddl:"identifier"` + Set *ApplicationPackageSet `ddl:"keyword" sql:"SET"` + UnsetDataRetentionTimeInDays *bool `ddl:"keyword" sql:"UNSET DATA_RETENTION_TIME_IN_DAYS"` + UnsetMaxDataExtensionTimeInDays *bool `ddl:"keyword" sql:"UNSET MAX_DATA_EXTENSION_TIME_IN_DAYS"` + UnsetDefaultDdlCollation *bool `ddl:"keyword" sql:"UNSET DEFAULT_DDL_COLLATION"` + UnsetComment *bool `ddl:"keyword" sql:"UNSET COMMENT"` + UnsetDistribution *bool `ddl:"keyword" sql:"UNSET DISTRIBUTION"` + ModifyReleaseDirective *ModifyReleaseDirective `ddl:"keyword" sql:"MODIFY RELEASE DIRECTIVE"` + SetDefaultReleaseDirective *SetDefaultReleaseDirective `ddl:"keyword" sql:"SET DEFAULT RELEASE DIRECTIVE"` + SetReleaseDirective *SetReleaseDirective `ddl:"keyword" sql:"SET RELEASE DIRECTIVE"` + UnsetReleaseDirective *UnsetReleaseDirective `ddl:"keyword" sql:"UNSET RELEASE DIRECTIVE"` + AddVersion *AddVersion `ddl:"keyword" sql:"ADD VERSION"` + DropVersion *DropVersion `ddl:"keyword" sql:"DROP VERSION"` + AddPatchForVersion *AddPatchForVersion `ddl:"keyword" sql:"ADD PATCH FOR VERSION"` + SetTags []TagAssociation `ddl:"keyword" sql:"SET TAG"` + UnsetTags []ObjectIdentifier `ddl:"keyword" sql:"UNSET TAG"` +} + +type ApplicationPackageSet struct { + DataRetentionTimeInDays *int `ddl:"parameter,no_quotes" sql:"DATA_RETENTION_TIME_IN_DAYS"` + MaxDataExtensionTimeInDays *int `ddl:"parameter,no_quotes" sql:"MAX_DATA_EXTENSION_TIME_IN_DAYS"` + DefaultDdlCollation *string `ddl:"parameter,single_quotes" sql:"DEFAULT_DDL_COLLATION"` + Comment *string `ddl:"parameter,single_quotes" sql:"COMMENT"` + Distribution *Distribution `ddl:"parameter" sql:"DISTRIBUTION"` +} + +type ModifyReleaseDirective struct { + ReleaseDirective string `ddl:"keyword,no_quotes"` + Version string `ddl:"parameter,no_quotes" sql:"VERSION"` + Patch int `ddl:"parameter,no_quotes" sql:"PATCH"` +} + +type SetDefaultReleaseDirective struct { + Version string `ddl:"parameter,no_quotes" sql:"VERSION"` + Patch int `ddl:"parameter,no_quotes" sql:"PATCH"` +} + +type SetReleaseDirective struct { + ReleaseDirective string `ddl:"keyword,no_quotes"` + Accounts []string `ddl:"parameter,no_quotes,must_parentheses" sql:"ACCOUNTS"` + Version string `ddl:"parameter,no_quotes" sql:"VERSION"` + Patch int `ddl:"parameter,no_quotes" sql:"PATCH"` +} + +type UnsetReleaseDirective struct { + ReleaseDirective string `ddl:"keyword,no_quotes"` +} + +type AddVersion struct { + VersionIdentifier *string `ddl:"keyword,no_quotes"` + Using string `ddl:"parameter,single_quotes,no_equals" sql:"USING"` + Label *string `ddl:"parameter,single_quotes" sql:"Label"` +} + +type DropVersion struct { + VersionIdentifier string `ddl:"keyword,no_quotes"` +} + +type AddPatchForVersion struct { + VersionIdentifier *string `ddl:"keyword,no_quotes"` + Using string `ddl:"parameter,single_quotes,no_equals" sql:"USING"` + Label *string `ddl:"parameter,single_quotes" sql:"Label"` +} + +// DropApplicationPackageOptions is based on https://docs.snowflake.com/en/sql-reference/sql/drop-application-package. +type DropApplicationPackageOptions struct { + drop bool `ddl:"static" sql:"DROP"` + applicationPackage bool `ddl:"static" sql:"APPLICATION PACKAGE"` + name AccountObjectIdentifier `ddl:"identifier"` +} + +// ShowApplicationPackageOptions is based on https://docs.snowflake.com/en/sql-reference/sql/show-application-packages. +type ShowApplicationPackageOptions struct { + show bool `ddl:"static" sql:"SHOW"` + applicationPackages bool `ddl:"static" sql:"APPLICATION PACKAGES"` + Like *Like `ddl:"keyword" sql:"LIKE"` + StartsWith *string `ddl:"parameter,single_quotes,no_equals" sql:"STARTS WITH"` + Limit *LimitFrom `ddl:"keyword" sql:"LIMIT"` +} + +type applicationPackageRow struct { + CreatedOn string `db:"created_on"` + Name string `db:"name"` + IsDefault string `db:"is_default"` + IsCurrent string `db:"is_current"` + Distribution string `db:"distribution"` + Owner string `db:"owner"` + Comment string `db:"comment"` + RetentionTime int `db:"retention_time"` + Options string `db:"options"` + DroppedOn sql.NullString `db:"dropped_on"` + ApplicationClass sql.NullString `db:"application_class"` +} + +type ApplicationPackage struct { + CreatedOn string + Name string + IsDefault bool + IsCurrent bool + Distribution string + Owner string + Comment string + RetentionTime int + Options string + DroppedOn string + ApplicationClass string +} diff --git a/pkg/sdk/application_packages_gen_test.go b/pkg/sdk/application_packages_gen_test.go new file mode 100644 index 0000000000..f21c74a20a --- /dev/null +++ b/pkg/sdk/application_packages_gen_test.go @@ -0,0 +1,269 @@ +package sdk + +import "testing" + +func TestApplicationPackages_Create(t *testing.T) { + id := RandomAccountObjectIdentifier() + + defaultOpts := func() *CreateApplicationPackageOptions { + return &CreateApplicationPackageOptions{ + name: id, + } + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *CreateApplicationPackageOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("validation: incorrect identifier", func(t *testing.T) { + opts := defaultOpts() + opts.name = NewAccountObjectIdentifier("") + assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) + }) + + t.Run("all options", func(t *testing.T) { + opts := defaultOpts() + opts.IfNotExists = Bool(true) + opts.DataRetentionTimeInDays = Int(1) + opts.MaxDataExtensionTimeInDays = Int(1) + opts.DefaultDdlCollation = String("en_US") + opts.Comment = String("comment") + opts.Distribution = DistributionPointer(DistributionInternal) + t1 := RandomSchemaObjectIdentifier() + opts.Tag = []TagAssociation{ + { + Name: t1, + Value: "v1", + }, + } + assertOptsValidAndSQLEquals(t, opts, "CREATE APPLICATION PACKAGE IF NOT EXISTS %s DATA_RETENTION_TIME_IN_DAYS = 1 MAX_DATA_EXTENSION_TIME_IN_DAYS = 1 DEFAULT_DDL_COLLATION = 'en_US' COMMENT = 'comment' DISTRIBUTION = INTERNAL TAG (%s = 'v1')", id.FullyQualifiedName(), t1.FullyQualifiedName()) + }) +} + +func TestApplicationPackages_Alter(t *testing.T) { + id := RandomAccountObjectIdentifier() + + defaultOpts := func() *AlterApplicationPackageOptions { + return &AlterApplicationPackageOptions{ + IfExists: Bool(true), + name: id, + } + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *AlterApplicationPackageOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("validation: incorrect identifier", func(t *testing.T) { + opts := defaultOpts() + opts.name = NewAccountObjectIdentifier("") + assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) + }) + + t.Run("validation: exactly one field should be present", func(t *testing.T) { + opts := defaultOpts() + assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AlterApplicationPackageOptions", "Set", "UnsetDataRetentionTimeInDays", "UnsetMaxDataExtensionTimeInDays", "UnsetDefaultDdlCollation", "UnsetComment", "UnsetDistribution", "ModifyReleaseDirective", "SetDefaultReleaseDirective", "SetReleaseDirective", "UnsetReleaseDirective", "AddVersion", "DropVersion", "AddPatchForVersion", "SetTags", "UnsetTags")) + }) + + t.Run("validation: exactly one field should be present", func(t *testing.T) { + opts := defaultOpts() + opts.SetDefaultReleaseDirective = &SetDefaultReleaseDirective{ + Version: "v1", + Patch: 1, + } + opts.UnsetReleaseDirective = &UnsetReleaseDirective{ + ReleaseDirective: "DEFAULT", + } + assertOptsInvalidJoinedErrors(t, opts, errExactlyOneOf("AlterApplicationPackageOptions", "Set", "UnsetDataRetentionTimeInDays", "UnsetMaxDataExtensionTimeInDays", "UnsetDefaultDdlCollation", "UnsetComment", "UnsetDistribution", "ModifyReleaseDirective", "SetDefaultReleaseDirective", "SetReleaseDirective", "UnsetReleaseDirective", "AddVersion", "DropVersion", "AddPatchForVersion", "SetTags", "UnsetTags")) + }) + + t.Run("alter: set options", func(t *testing.T) { + opts := defaultOpts() + opts.Set = &ApplicationPackageSet{ + DataRetentionTimeInDays: Int(1), + MaxDataExtensionTimeInDays: Int(1), + DefaultDdlCollation: String("en_US"), + Comment: String("comment"), + Distribution: DistributionPointer(DistributionInternal), + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s SET DATA_RETENTION_TIME_IN_DAYS = 1 MAX_DATA_EXTENSION_TIME_IN_DAYS = 1 DEFAULT_DDL_COLLATION = 'en_US' COMMENT = 'comment' DISTRIBUTION = INTERNAL`, id.FullyQualifiedName()) + }) + + t.Run("alter: unset options", func(t *testing.T) { + opts := defaultOpts() + opts.UnsetComment = Bool(true) + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s UNSET COMMENT`, id.FullyQualifiedName()) + + opts = defaultOpts() + opts.UnsetDataRetentionTimeInDays = Bool(true) + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s UNSET DATA_RETENTION_TIME_IN_DAYS`, id.FullyQualifiedName()) + + opts = defaultOpts() + opts.UnsetMaxDataExtensionTimeInDays = Bool(true) + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s UNSET MAX_DATA_EXTENSION_TIME_IN_DAYS`, id.FullyQualifiedName()) + + opts = defaultOpts() + opts.UnsetDefaultDdlCollation = Bool(true) + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s UNSET DEFAULT_DDL_COLLATION`, id.FullyQualifiedName()) + + opts = defaultOpts() + opts.UnsetDistribution = Bool(true) + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s UNSET DISTRIBUTION`, id.FullyQualifiedName()) + }) + + t.Run("alter: set tags", func(t *testing.T) { + opts := defaultOpts() + opts.SetTags = []TagAssociation{ + { + Name: NewAccountObjectIdentifier("tag1"), + Value: "value1", + }, + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s SET TAG "tag1" = 'value1'`, id.FullyQualifiedName()) + }) + + t.Run("alter: unset tags", func(t *testing.T) { + opts := defaultOpts() + opts.UnsetTags = []ObjectIdentifier{ + NewAccountObjectIdentifier("tag1"), + NewAccountObjectIdentifier("tag2"), + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s UNSET TAG "tag1", "tag2"`, id.FullyQualifiedName()) + }) + + t.Run("alter: modify release directive", func(t *testing.T) { + opts := defaultOpts() + opts.ModifyReleaseDirective = &ModifyReleaseDirective{ + ReleaseDirective: "DEFAULT", + Version: "V1", + Patch: 1, + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s MODIFY RELEASE DIRECTIVE DEFAULT VERSION = V1 PATCH = 1`, id.FullyQualifiedName()) + }) + + t.Run("alter: set default release directive", func(t *testing.T) { + opts := defaultOpts() + opts.SetDefaultReleaseDirective = &SetDefaultReleaseDirective{ + Version: "V1", + Patch: 1, + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s SET DEFAULT RELEASE DIRECTIVE VERSION = V1 PATCH = 1`, id.FullyQualifiedName()) + }) + + t.Run("alter: set release directive", func(t *testing.T) { + opts := defaultOpts() + opts.SetReleaseDirective = &SetReleaseDirective{ + ReleaseDirective: "DEFAULT", + Accounts: []string{ + "org1.acc1", + "org2.acc2", + }, + Version: "V1", + Patch: 1, + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s SET RELEASE DIRECTIVE DEFAULT ACCOUNTS = (org1.acc1, org2.acc2) VERSION = V1 PATCH = 1`, id.FullyQualifiedName()) + }) + + t.Run("alter: set release directive with no accounts", func(t *testing.T) { + opts := defaultOpts() + opts.SetReleaseDirective = &SetReleaseDirective{ + ReleaseDirective: "DEFAULT", + Version: "V1", + Patch: 1, + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s SET RELEASE DIRECTIVE DEFAULT ACCOUNTS = () VERSION = V1 PATCH = 1`, id.FullyQualifiedName()) + }) + + t.Run("alter: unset release directive", func(t *testing.T) { + opts := defaultOpts() + opts.UnsetReleaseDirective = &UnsetReleaseDirective{ + ReleaseDirective: "DEFAULT", + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s UNSET RELEASE DIRECTIVE DEFAULT`, id.FullyQualifiedName()) + }) + + t.Run("alter: add version", func(t *testing.T) { + opts := defaultOpts() + opts.AddVersion = &AddVersion{ + VersionIdentifier: String("v1_1"), + Using: "@hello_snowflake_code.core.hello_snowflake_stage", + Label: String("test"), + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s ADD VERSION v1_1 USING '@hello_snowflake_code.core.hello_snowflake_stage' Label = 'test'`, id.FullyQualifiedName()) + }) + + t.Run("alter: drop version", func(t *testing.T) { + opts := defaultOpts() + opts.DropVersion = &DropVersion{ + VersionIdentifier: "v1_1", + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s DROP VERSION v1_1`, id.FullyQualifiedName()) + }) + + t.Run("alter: add patch for version", func(t *testing.T) { + opts := defaultOpts() + opts.AddPatchForVersion = &AddPatchForVersion{ + VersionIdentifier: String("v1_1"), + Using: "@hello_snowflake_code.core.hello_snowflake_stage", + Label: String("test"), + } + assertOptsValidAndSQLEquals(t, opts, `ALTER APPLICATION PACKAGE IF EXISTS %s ADD PATCH FOR VERSION v1_1 USING '@hello_snowflake_code.core.hello_snowflake_stage' Label = 'test'`, id.FullyQualifiedName()) + }) +} + +func TestApplicationPackages_Drop(t *testing.T) { + id := RandomAccountObjectIdentifier() + + defaultOpts := func() *DropApplicationPackageOptions { + return &DropApplicationPackageOptions{ + name: id, + } + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *DropApplicationPackageOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("validation: incorrect identifier", func(t *testing.T) { + opts := defaultOpts() + opts.name = NewAccountObjectIdentifier("") + assertOptsInvalidJoinedErrors(t, opts, ErrInvalidObjectIdentifier) + }) + + t.Run("all options", func(t *testing.T) { + opts := defaultOpts() + assertOptsValidAndSQLEquals(t, opts, `DROP APPLICATION PACKAGE %s`, id.FullyQualifiedName()) + }) +} + +func TestApplicationPackages_Show(t *testing.T) { + defaultOpts := func() *ShowApplicationPackageOptions { + return &ShowApplicationPackageOptions{} + } + + t.Run("validation: nil options", func(t *testing.T) { + var opts *ShowApplicationPackageOptions = nil + assertOptsInvalidJoinedErrors(t, opts, ErrNilOptions) + }) + + t.Run("basic", func(t *testing.T) { + opts := defaultOpts() + assertOptsValidAndSQLEquals(t, opts, `SHOW APPLICATION PACKAGES`) + }) + + t.Run("all options", func(t *testing.T) { + opts := defaultOpts() + opts.Like = &Like{ + Pattern: String("pattern"), + } + opts.StartsWith = String("A") + opts.Limit = &LimitFrom{ + Rows: Int(1), + From: String("B"), + } + assertOptsValidAndSQLEquals(t, opts, `SHOW APPLICATION PACKAGES LIKE 'pattern' STARTS WITH 'A' LIMIT 1 FROM 'B'`) + }) +} diff --git a/pkg/sdk/application_packages_impl_gen.go b/pkg/sdk/application_packages_impl_gen.go new file mode 100644 index 0000000000..becae6598d --- /dev/null +++ b/pkg/sdk/application_packages_impl_gen.go @@ -0,0 +1,169 @@ +package sdk + +import ( + "context" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/internal/collections" +) + +var _ ApplicationPackages = (*applicationPackages)(nil) + +type applicationPackages struct { + client *Client +} + +func (v *applicationPackages) Create(ctx context.Context, request *CreateApplicationPackageRequest) error { + opts := request.toOpts() + return validateAndExec(v.client, ctx, opts) +} + +func (v *applicationPackages) Alter(ctx context.Context, request *AlterApplicationPackageRequest) error { + opts := request.toOpts() + return validateAndExec(v.client, ctx, opts) +} + +func (v *applicationPackages) Drop(ctx context.Context, request *DropApplicationPackageRequest) error { + opts := request.toOpts() + return validateAndExec(v.client, ctx, opts) +} + +func (v *applicationPackages) Show(ctx context.Context, request *ShowApplicationPackageRequest) ([]ApplicationPackage, error) { + opts := request.toOpts() + dbRows, err := validateAndQuery[applicationPackageRow](v.client, ctx, opts) + if err != nil { + return nil, err + } + resultList := convertRows[applicationPackageRow, ApplicationPackage](dbRows) + return resultList, nil +} + +func (v *applicationPackages) ShowByID(ctx context.Context, id AccountObjectIdentifier) (*ApplicationPackage, error) { + request := NewShowApplicationPackageRequest().WithLike(&Like{String(id.Name())}) + applicationPackages, err := v.Show(ctx, request) + if err != nil { + return nil, err + } + return collections.FindOne(applicationPackages, func(r ApplicationPackage) bool { return r.Name == id.Name() }) +} + +func (r *CreateApplicationPackageRequest) toOpts() *CreateApplicationPackageOptions { + opts := &CreateApplicationPackageOptions{ + IfNotExists: r.IfNotExists, + name: r.name, + DataRetentionTimeInDays: r.DataRetentionTimeInDays, + MaxDataExtensionTimeInDays: r.MaxDataExtensionTimeInDays, + DefaultDdlCollation: r.DefaultDdlCollation, + Comment: r.Comment, + Distribution: r.Distribution, + Tag: r.Tag, + } + return opts +} + +func (r *AlterApplicationPackageRequest) toOpts() *AlterApplicationPackageOptions { + opts := &AlterApplicationPackageOptions{ + IfExists: r.IfExists, + name: r.name, + + UnsetDataRetentionTimeInDays: r.UnsetDataRetentionTimeInDays, + UnsetMaxDataExtensionTimeInDays: r.UnsetMaxDataExtensionTimeInDays, + UnsetDefaultDdlCollation: r.UnsetDefaultDdlCollation, + UnsetComment: r.UnsetComment, + UnsetDistribution: r.UnsetDistribution, + + SetTags: r.SetTags, + UnsetTags: r.UnsetTags, + } + if r.Set != nil { + opts.Set = &ApplicationPackageSet{ + DataRetentionTimeInDays: r.Set.DataRetentionTimeInDays, + MaxDataExtensionTimeInDays: r.Set.MaxDataExtensionTimeInDays, + DefaultDdlCollation: r.Set.DefaultDdlCollation, + Comment: r.Set.Comment, + Distribution: r.Set.Distribution, + } + } + if r.ModifyReleaseDirective != nil { + opts.ModifyReleaseDirective = &ModifyReleaseDirective{ + ReleaseDirective: r.ModifyReleaseDirective.ReleaseDirective, + Version: r.ModifyReleaseDirective.Version, + Patch: r.ModifyReleaseDirective.Patch, + } + } + if r.SetDefaultReleaseDirective != nil { + opts.SetDefaultReleaseDirective = &SetDefaultReleaseDirective{ + Version: r.SetDefaultReleaseDirective.Version, + Patch: r.SetDefaultReleaseDirective.Patch, + } + } + if r.SetReleaseDirective != nil { + opts.SetReleaseDirective = &SetReleaseDirective{ + ReleaseDirective: r.SetReleaseDirective.ReleaseDirective, + Accounts: r.SetReleaseDirective.Accounts, + Version: r.SetReleaseDirective.Version, + Patch: r.SetReleaseDirective.Patch, + } + } + if r.UnsetReleaseDirective != nil { + opts.UnsetReleaseDirective = &UnsetReleaseDirective{ + ReleaseDirective: r.UnsetReleaseDirective.ReleaseDirective, + } + } + if r.AddVersion != nil { + opts.AddVersion = &AddVersion{ + VersionIdentifier: r.AddVersion.VersionIdentifier, + Using: r.AddVersion.Using, + Label: r.AddVersion.Label, + } + } + if r.DropVersion != nil { + opts.DropVersion = &DropVersion{ + VersionIdentifier: r.DropVersion.VersionIdentifier, + } + } + if r.AddPatchForVersion != nil { + opts.AddPatchForVersion = &AddPatchForVersion{ + VersionIdentifier: r.AddPatchForVersion.VersionIdentifier, + Using: r.AddPatchForVersion.Using, + Label: r.AddPatchForVersion.Label, + } + } + return opts +} + +func (r *DropApplicationPackageRequest) toOpts() *DropApplicationPackageOptions { + opts := &DropApplicationPackageOptions{ + name: r.name, + } + return opts +} + +func (r *ShowApplicationPackageRequest) toOpts() *ShowApplicationPackageOptions { + opts := &ShowApplicationPackageOptions{ + Like: r.Like, + StartsWith: r.StartsWith, + Limit: r.Limit, + } + return opts +} + +func (r applicationPackageRow) convert() *ApplicationPackage { + e := &ApplicationPackage{ + CreatedOn: r.CreatedOn, + Name: r.Name, + IsDefault: r.IsDefault == "Y", + IsCurrent: r.IsCurrent == "Y", + Distribution: r.Distribution, + Owner: r.Owner, + Comment: r.Comment, + RetentionTime: r.RetentionTime, + Options: r.Options, + } + if r.DroppedOn.Valid { + e.DroppedOn = r.DroppedOn.String + } + if r.ApplicationClass.Valid { + e.ApplicationClass = r.ApplicationClass.String + } + return e +} diff --git a/pkg/sdk/application_packages_validations_gen.go b/pkg/sdk/application_packages_validations_gen.go new file mode 100644 index 0000000000..e781aef63c --- /dev/null +++ b/pkg/sdk/application_packages_validations_gen.go @@ -0,0 +1,52 @@ +package sdk + +var ( + _ validatable = new(CreateApplicationPackageOptions) + _ validatable = new(AlterApplicationPackageOptions) + _ validatable = new(DropApplicationPackageOptions) + _ validatable = new(ShowApplicationPackageOptions) +) + +func (opts *CreateApplicationPackageOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + if !ValidObjectIdentifier(opts.name) { + errs = append(errs, ErrInvalidObjectIdentifier) + } + return JoinErrors(errs...) +} + +func (opts *AlterApplicationPackageOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + if !ValidObjectIdentifier(opts.name) { + errs = append(errs, ErrInvalidObjectIdentifier) + } + if !exactlyOneValueSet(opts.Set, opts.UnsetDataRetentionTimeInDays, opts.UnsetMaxDataExtensionTimeInDays, opts.UnsetDefaultDdlCollation, opts.UnsetComment, opts.UnsetDistribution, opts.ModifyReleaseDirective, opts.SetDefaultReleaseDirective, opts.SetReleaseDirective, opts.UnsetReleaseDirective, opts.AddVersion, opts.DropVersion, opts.AddPatchForVersion, opts.SetTags, opts.UnsetTags) { + errs = append(errs, errExactlyOneOf("AlterApplicationPackageOptions", "Set", "UnsetDataRetentionTimeInDays", "UnsetMaxDataExtensionTimeInDays", "UnsetDefaultDdlCollation", "UnsetComment", "UnsetDistribution", "ModifyReleaseDirective", "SetDefaultReleaseDirective", "SetReleaseDirective", "UnsetReleaseDirective", "AddVersion", "DropVersion", "AddPatchForVersion", "SetTags", "UnsetTags")) + } + return JoinErrors(errs...) +} + +func (opts *DropApplicationPackageOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + if !ValidObjectIdentifier(opts.name) { + errs = append(errs, ErrInvalidObjectIdentifier) + } + return JoinErrors(errs...) +} + +func (opts *ShowApplicationPackageOptions) validate() error { + if opts == nil { + return ErrNilOptions + } + var errs []error + return JoinErrors(errs...) +} diff --git a/pkg/sdk/client.go b/pkg/sdk/client.go index b8170d81e8..3d0c5c97ee 100644 --- a/pkg/sdk/client.go +++ b/pkg/sdk/client.go @@ -38,39 +38,40 @@ type Client struct { ReplicationFunctions ReplicationFunctions // DDL Commands - Accounts Accounts - Alerts Alerts - ApplicationRoles ApplicationRoles - Comments Comments - DatabaseRoles DatabaseRoles - Databases Databases - DynamicTables DynamicTables - ExternalTables ExternalTables - EventTables EventTables - FailoverGroups FailoverGroups - FileFormats FileFormats - Functions Functions - Grants Grants - MaskingPolicies MaskingPolicies - NetworkPolicies NetworkPolicies - Parameters Parameters - PasswordPolicies PasswordPolicies - Pipes Pipes - Procedures Procedures - ResourceMonitors ResourceMonitors - Roles Roles - Schemas Schemas - SessionPolicies SessionPolicies - Sessions Sessions - Shares Shares - Stages Stages - Streams Streams - Tables Tables - Tags Tags - Tasks Tasks - Users Users - Views Views - Warehouses Warehouses + Accounts Accounts + Alerts Alerts + ApplicationPackages ApplicationPackages + ApplicationRoles ApplicationRoles + Comments Comments + DatabaseRoles DatabaseRoles + Databases Databases + DynamicTables DynamicTables + ExternalTables ExternalTables + EventTables EventTables + FailoverGroups FailoverGroups + FileFormats FileFormats + Functions Functions + Grants Grants + MaskingPolicies MaskingPolicies + NetworkPolicies NetworkPolicies + Parameters Parameters + PasswordPolicies PasswordPolicies + Pipes Pipes + Procedures Procedures + ResourceMonitors ResourceMonitors + Roles Roles + Schemas Schemas + SessionPolicies SessionPolicies + Sessions Sessions + Shares Shares + Stages Stages + Streams Streams + Tables Tables + Tags Tags + Tasks Tasks + Users Users + Views Views + Warehouses Warehouses } func (c *Client) GetAccountLocator() string { @@ -179,6 +180,7 @@ func NewClientFromDB(db *sql.DB) *Client { func (c *Client) initialize() { c.Accounts = &accounts{client: c} c.Alerts = &alerts{client: c} + c.ApplicationPackages = &applicationPackages{client: c} c.ApplicationRoles = &applicationRoles{client: c} c.Comments = &comments{client: c} c.ContextFunctions = &contextFunctions{client: c} diff --git a/pkg/sdk/common_types.go b/pkg/sdk/common_types.go index 4a93ac05bc..517ace65ed 100644 --- a/pkg/sdk/common_types.go +++ b/pkg/sdk/common_types.go @@ -198,3 +198,14 @@ type Secret struct { VariableName string `ddl:"keyword,single_quotes"` Name string `ddl:"parameter,no_quotes"` } + +type Distribution string + +var ( + DistributionInternal Distribution = "INTERNAL" + DistributionExternal Distribution = "EXTERNAL" +) + +func DistributionPointer(v Distribution) *Distribution { + return &v +} diff --git a/pkg/sdk/poc/generator/field_transformers.go b/pkg/sdk/poc/generator/field_transformers.go index f0a3be6513..3c7f460233 100644 --- a/pkg/sdk/poc/generator/field_transformers.go +++ b/pkg/sdk/poc/generator/field_transformers.go @@ -125,6 +125,11 @@ func (v *ParameterTransformer) Parentheses() *ParameterTransformer { return v } +func (v *ParameterTransformer) MustParentheses() *ParameterTransformer { + v.parentheses = "must_parentheses" + return v +} + func (v *ParameterTransformer) Transform(f *Field) *Field { addTagIfMissing(f.Tags, "ddl", "parameter") if v.required { diff --git a/pkg/sdk/poc/main.go b/pkg/sdk/poc/main.go index 0d9ebbb5fe..acb572a984 100644 --- a/pkg/sdk/poc/main.go +++ b/pkg/sdk/poc/main.go @@ -16,17 +16,18 @@ import ( ) var definitionMapping = map[string]*generator.Interface{ - "database_role_def.go": example.DatabaseRole, - "network_policies_def.go": sdk.NetworkPoliciesDef, - "session_policies_def.go": sdk.SessionPoliciesDef, - "tasks_def.go": sdk.TasksDef, - "streams_def.go": sdk.StreamsDef, - "application_roles_def.go": sdk.ApplicationRolesDef, - "views_def.go": sdk.ViewsDef, - "stages_def.go": sdk.StagesDef, - "functions_def.go": sdk.FunctionsDef, - "procedures_def.go": sdk.ProceduresDef, - "event_tables_def.go": sdk.EventTablesDef, + "database_role_def.go": example.DatabaseRole, + "network_policies_def.go": sdk.NetworkPoliciesDef, + "session_policies_def.go": sdk.SessionPoliciesDef, + "tasks_def.go": sdk.TasksDef, + "streams_def.go": sdk.StreamsDef, + "application_roles_def.go": sdk.ApplicationRolesDef, + "views_def.go": sdk.ViewsDef, + "stages_def.go": sdk.StagesDef, + "functions_def.go": sdk.FunctionsDef, + "procedures_def.go": sdk.ProceduresDef, + "event_tables_def.go": sdk.EventTablesDef, + "application_packages_def.go": sdk.ApplicationPackagesDef, } func main() { diff --git a/pkg/sdk/testint/application_packages_integration_test.go b/pkg/sdk/testint/application_packages_integration_test.go new file mode 100644 index 0000000000..328447f619 --- /dev/null +++ b/pkg/sdk/testint/application_packages_integration_test.go @@ -0,0 +1,325 @@ +package testint + +import ( + "context" + "errors" + "fmt" + "os" + "testing" + + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk" + "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk/internal/random" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +/* +todo: add tests for: + - Creates a custom release directive for the specified accounts : https://docs.snowflake.com/en/sql-reference/sql/alter-application-package-release-directive +*/ + +func TestInt_ApplicationPackages(t *testing.T) { + client := testClient(t) + ctx := testContext(t) + + databaseTest, schemaTest := testDb(t), testSchema(t) + tagTest, tagCleanup := createTag(t, client, databaseTest, schemaTest) + t.Cleanup(tagCleanup) + + cleanupApplicationPackageHandle := func(id sdk.AccountObjectIdentifier) func() { + return func() { + err := client.ApplicationPackages.Drop(ctx, sdk.NewDropApplicationPackageRequest(id)) + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + return + } + require.NoError(t, err) + } + } + + createApplicationPackageHandle := func(t *testing.T) *sdk.ApplicationPackage { + t.Helper() + + id := sdk.NewAccountObjectIdentifier(random.StringN(4)) + request := sdk.NewCreateApplicationPackageRequest(id).WithDistribution(sdk.DistributionPointer(sdk.DistributionInternal)) + err := client.ApplicationPackages.Create(ctx, request) + require.NoError(t, err) + t.Cleanup(cleanupApplicationPackageHandle(id)) + + e, err := client.ApplicationPackages.ShowByID(ctx, id) + require.NoError(t, err) + return e + } + + assertApplicationPackage := func(t *testing.T, id sdk.AccountObjectIdentifier) { + t.Helper() + + e, err := client.ApplicationPackages.ShowByID(ctx, id) + require.NoError(t, err) + + assert.NotEmpty(t, e.CreatedOn) + assert.Equal(t, id.Name(), e.Name) + assert.Equal(t, false, e.IsDefault) + assert.Equal(t, true, e.IsCurrent) + assert.Equal(t, sdk.DistributionInternal, sdk.Distribution(e.Distribution)) + assert.Equal(t, "ACCOUNTADMIN", e.Owner) + assert.Empty(t, e.Comment) + assert.Equal(t, 1, e.RetentionTime) + assert.Empty(t, e.Options) + assert.Empty(t, e.DroppedOn) + assert.Empty(t, e.ApplicationClass) + } + + t.Run("create application package", func(t *testing.T) { + id := sdk.NewAccountObjectIdentifier(random.StringN(4)) + comment := random.StringN(4) + request := sdk.NewCreateApplicationPackageRequest(id). + WithComment(&comment). + // todo: insufficient privileges for the following three fields + // WithDataRetentionTimeInDays(sdk.Int(1)). + // WithMaxDataExtensionTimeInDays(sdk.Int(1)). + // WithDefaultDdlCollation(sdk.String("en_US")). + WithTag([]sdk.TagAssociation{ + { + Name: tagTest.ID(), + Value: "v1", + }, + }). + WithDistribution(sdk.DistributionPointer(sdk.DistributionExternal)) + err := client.ApplicationPackages.Create(ctx, request) + require.NoError(t, err) + t.Cleanup(cleanupApplicationPackageHandle(id)) + + e, err := client.ApplicationPackages.ShowByID(ctx, id) + require.NoError(t, err) + require.Equal(t, id.Name(), e.Name) + require.Equal(t, sdk.DistributionExternal, sdk.Distribution(e.Distribution)) + require.Equal(t, "ACCOUNTADMIN", e.Owner) + require.Equal(t, comment, e.Comment) + require.Equal(t, 1, e.RetentionTime) + }) + + t.Run("alter application package: set", func(t *testing.T) { + e := createApplicationPackageHandle(t) + id := sdk.NewAccountObjectIdentifier(e.Name) + + distribution := sdk.DistributionPointer(sdk.DistributionExternal) + set := sdk.NewApplicationPackageSetRequest(). + WithDistribution(distribution). + WithComment(sdk.String("test")). + WithDataRetentionTimeInDays(sdk.Int(2)). + WithMaxDataExtensionTimeInDays(sdk.Int(2)). + WithDefaultDdlCollation(sdk.String("utf8mb4_0900_ai_ci")) + err := client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithSet(set)) + require.NoError(t, err) + + o, err := client.ApplicationPackages.ShowByID(ctx, id) + require.NoError(t, err) + assert.Equal(t, *distribution, sdk.Distribution(o.Distribution)) + assert.Equal(t, 2, o.RetentionTime) + assert.Equal(t, "test", o.Comment) + }) + + t.Run("alter application package: unset", func(t *testing.T) { + e := createApplicationPackageHandle(t) + id := sdk.NewAccountObjectIdentifier(e.Name) + + // unset comment + err := client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithUnsetComment(sdk.Bool(true))) + require.NoError(t, err) + o, err := client.ApplicationPackages.ShowByID(ctx, id) + require.NoError(t, err) + require.Empty(t, o.Comment) + + // unset distribution + err = client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithUnsetDistribution(sdk.Bool(true))) + require.NoError(t, err) + o, err = client.ApplicationPackages.ShowByID(ctx, id) + require.NoError(t, err) + require.Equal(t, sdk.DistributionInternal, sdk.Distribution(o.Distribution)) + }) + + t.Run("alter application package: set and unset tags", func(t *testing.T) { + e := createApplicationPackageHandle(t) + id := sdk.NewAccountObjectIdentifier(e.Name) + + setTags := []sdk.TagAssociation{ + { + Name: tagTest.ID(), + Value: "v1", + }, + } + err := client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithSetTags(setTags)) + require.NoError(t, err) + assertApplicationPackage(t, id) + + unsetTags := []sdk.ObjectIdentifier{ + tagTest.ID(), + } + err = client.ApplicationPackages.Alter(ctx, sdk.NewAlterApplicationPackageRequest(id).WithUnsetTags(unsetTags)) + require.NoError(t, err) + assertApplicationPackage(t, id) + }) + + t.Run("show application package for SQL: with like", func(t *testing.T) { + e := createApplicationPackageHandle(t) + + packages, err := client.ApplicationPackages.Show(ctx, sdk.NewShowApplicationPackageRequest().WithLike(&sdk.Like{Pattern: &e.Name})) + require.NoError(t, err) + require.Equal(t, 1, len(packages)) + require.Equal(t, *e, packages[0]) + }) +} + +type StagedFile struct { + Name string `json:"name"` + Size int `json:"size"` +} + +type ApplicationPackageVersion struct { + Version string `json:"version"` + Patch int `json:"patch"` +} + +func TestInt_ApplicationPackagesVersionAndReleaseDirective(t *testing.T) { + client := testClient(t) + ctx := context.Background() + + databaseTest, schemaTest := testDb(t), testSchema(t) + + cleanupApplicationPackageHandle := func(id sdk.AccountObjectIdentifier) func() { + return func() { + err := client.ApplicationPackages.Drop(ctx, sdk.NewDropApplicationPackageRequest(id)) + if errors.Is(err, sdk.ErrObjectNotExistOrAuthorized) { + return + } + require.NoError(t, err) + } + } + + createApplicationPackageHandle := func(t *testing.T) *sdk.ApplicationPackage { + t.Helper() + + id := sdk.NewAccountObjectIdentifier("snowflake_package_test") + request := sdk.NewCreateApplicationPackageRequest(id).WithDistribution(sdk.DistributionPointer(sdk.DistributionInternal)) + err := client.ApplicationPackages.Create(ctx, request) + require.NoError(t, err) + t.Cleanup(cleanupApplicationPackageHandle(id)) + + // grant role "ACCOUNTADMIN" on application package + _, err = client.ExecForTests(ctx, fmt.Sprintf(`GRANT MANAGE VERSIONS ON APPLICATION PACKAGE "%s" TO ROLE ACCOUNTADMIN;`, id.Name())) + require.NoError(t, err) + + e, err := client.ApplicationPackages.ShowByID(ctx, id) + require.NoError(t, err) + return e + } + + createStageHandle := func(t *testing.T) *sdk.Stage { + t.Helper() + + id := sdk.NewSchemaObjectIdentifier(databaseTest.Name, schemaTest.Name, "stage_test") + co := sdk.NewStageCopyOptionsRequest().WithOnError(sdk.NewStageCopyOnErrorOptionsRequest().WithSkipFile()) + cr := sdk.NewCreateInternalStageRequest(id).WithCopyOptions(co) + err := client.Stages.CreateInternal(ctx, cr) + require.NoError(t, err) + t.Cleanup(func() { + err = client.Stages.Drop(ctx, sdk.NewDropStageRequest(id)) + require.NoError(t, err) + }) + + e, err := client.Stages.ShowByID(ctx, id) + require.NoError(t, err) + return e + } + + uploadFileForStageHandle := func(t *testing.T, id sdk.SchemaObjectIdentifier, name string) { + t.Helper() + + tempFile := fmt.Sprintf("/tmp/%s", name) + f, err := os.Create(tempFile) + require.NoError(t, err) + f.Close() + defer os.Remove(name) + + _, err = client.ExecForTests(ctx, fmt.Sprintf(`PUT file://%s @%s AUTO_COMPRESS = FALSE OVERWRITE = TRUE`, tempFile, id.FullyQualifiedName())) + require.NoError(t, err) + t.Cleanup(func() { + _, err = client.ExecForTests(ctx, fmt.Sprintf(`REMOVE @%s/%s`, id.FullyQualifiedName(), name)) + require.NoError(t, err) + }) + } + + showApplicationPackageVersion := func(t *testing.T, name string) []ApplicationPackageVersion { + t.Helper() + + var versions []ApplicationPackageVersion + err := client.QueryForTests(ctx, &versions, fmt.Sprintf(`SHOW VERSIONS IN APPLICATION PACKAGE "%s"`, name)) + require.NoError(t, err) + return versions + } + + t.Run("alter application package: add, patch and drop version", func(t *testing.T) { + e := createApplicationPackageHandle(t) + s := createStageHandle(t) + uploadFileForStageHandle(t, s.ID(), "manifest.yml") + uploadFileForStageHandle(t, s.ID(), "setup.sql") + + version := "V001" + using := "@" + s.ID().FullyQualifiedName() + // add version to application package + id := sdk.NewAccountObjectIdentifier(e.Name) + vr := sdk.NewAddVersionRequest(using).WithVersionIdentifier(&version).WithLabel(sdk.String("add version V001")) + r1 := sdk.NewAlterApplicationPackageRequest(id).WithAddVersion(vr) + err := client.ApplicationPackages.Alter(ctx, r1) + require.NoError(t, err) + versions := showApplicationPackageVersion(t, e.Name) + require.Equal(t, 1, len(versions)) + require.Equal(t, version, versions[0].Version) + require.Equal(t, 0, versions[0].Patch) + + // add patch for application package version + pr := sdk.NewAddPatchForVersionRequest(&version, using).WithLabel(sdk.String("patch version V001")) + r2 := sdk.NewAlterApplicationPackageRequest(id).WithAddPatchForVersion(pr) + err = client.ApplicationPackages.Alter(ctx, r2) + require.NoError(t, err) + versions = showApplicationPackageVersion(t, e.Name) + require.Equal(t, 2, len(versions)) + require.Equal(t, version, versions[0].Version) + require.Equal(t, 0, versions[0].Patch) + require.Equal(t, version, versions[1].Version) + require.Equal(t, 1, versions[1].Patch) + + // drop version from application package + r3 := sdk.NewAlterApplicationPackageRequest(id).WithDropVersion(sdk.NewDropVersionRequest(version)) + err = client.ApplicationPackages.Alter(ctx, r3) + require.NoError(t, err) + versions = showApplicationPackageVersion(t, e.Name) + require.Equal(t, 0, len(versions)) + }) + + t.Run("alter application package: set default release directive", func(t *testing.T) { + e := createApplicationPackageHandle(t) + s := createStageHandle(t) + uploadFileForStageHandle(t, s.ID(), "manifest.yml") + uploadFileForStageHandle(t, s.ID(), "setup.sql") + + version := "V001" + using := "@" + s.ID().FullyQualifiedName() + // add version to application package + id := sdk.NewAccountObjectIdentifier(e.Name) + vr := sdk.NewAddVersionRequest(using).WithVersionIdentifier(&version).WithLabel(sdk.String("add version V001")) + r1 := sdk.NewAlterApplicationPackageRequest(id).WithAddVersion(vr) + err := client.ApplicationPackages.Alter(ctx, r1) + require.NoError(t, err) + versions := showApplicationPackageVersion(t, e.Name) + require.Equal(t, 1, len(versions)) + require.Equal(t, version, versions[0].Version) + require.Equal(t, 0, versions[0].Patch) + + // set default release directive + rr := sdk.NewSetDefaultReleaseDirectiveRequest(version, 0) + r2 := sdk.NewAlterApplicationPackageRequest(id).WithSetDefaultReleaseDirective(rr) + err = client.ApplicationPackages.Alter(ctx, r2) + require.NoError(t, err) + }) +}