Skip to content

Commit

Permalink
tags sdk refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-swinkler committed Sep 28, 2023
1 parent 922358a commit 7060e2d
Show file tree
Hide file tree
Showing 9 changed files with 783 additions and 13 deletions.
10 changes: 6 additions & 4 deletions pkg/sdk/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ type Client struct {
Accounts Accounts
Alerts Alerts
Comments Comments
Databases Databases
DatabaseRoles DatabaseRoles
Databases Databases
ExternalTables ExternalTables
FailoverGroups FailoverGroups
FileFormats FileFormats
Expand All @@ -42,11 +42,12 @@ type Client struct {
Pipes Pipes
ResourceMonitors ResourceMonitors
Roles Roles
Schemas Schemas
SessionPolicies SessionPolicies
Sessions Sessions
Shares Shares
Tags Tags
Users Users
Schemas Schemas
Warehouses Warehouses
}

Expand Down Expand Up @@ -128,8 +129,8 @@ func (c *Client) initialize() {
c.Comments = &comments{client: c}
c.ContextFunctions = &contextFunctions{client: c}
c.ConversionFunctions = &conversionFunctions{client: c}
c.Databases = &databases{client: c}
c.DatabaseRoles = &databaseRoles{client: c}
c.Databases = &databases{client: c}
c.ExternalTables = &externalTables{client: c}
c.FailoverGroups = &failoverGroups{client: c}
c.FileFormats = &fileFormats{client: c}
Expand All @@ -142,11 +143,12 @@ func (c *Client) initialize() {
c.ReplicationFunctions = &replicationFunctions{client: c}
c.ResourceMonitors = &resourceMonitors{client: c}
c.Roles = &roles{client: c}
c.Schemas = &schemas{client: c}
c.SessionPolicies = &sessionPolicies{client: c}
c.Sessions = &sessions{client: c}
c.Shares = &shares{client: c}
c.Schemas = &schemas{client: c}
c.SystemFunctions = &systemFunctions{client: c}
c.Tags = &tags{client: c}
c.Users = &users{client: c}
c.Warehouses = &warehouses{client: c}
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/sdk/helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,13 +388,14 @@ func createTable(t *testing.T, client *Client, database *Database, schema *Schem

func createTag(t *testing.T, client *Client, database *Database, schema *Schema) (*Tag, func()) {
t.Helper()
return createTagWithOptions(t, client, database, schema, &TagCreateOptions{})
return createTagWithOptions(t, client, database, schema)
}

func createTagWithOptions(t *testing.T, client *Client, database *Database, schema *Schema, _ *TagCreateOptions) (*Tag, func()) {
func createTagWithOptions(t *testing.T, client *Client, database *Database, schema *Schema) (*Tag, func()) {
t.Helper()
name := randomStringRange(t, 8, 28)
ctx := context.Background()

_, err := client.exec(ctx, fmt.Sprintf("CREATE TAG \"%s\".\"%s\".\"%s\"", database.Name, schema.Name, name))
require.NoError(t, err)
return &Tag{
Expand Down
148 changes: 141 additions & 7 deletions pkg/sdk/tags.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,152 @@
package sdk

// placeholder for the real implementation.
type TagCreateOptions struct{}
import (
"context"
"database/sql"
"strings"
"time"
)

type Tags interface {
Create(ctx context.Context, request *CreateTagRequest) error
Show(ctx context.Context, opts *ShowTagRequest) ([]Tag, error)
ShowByID(ctx context.Context, id AccountObjectIdentifier) (*Tag, error)
Drop(ctx context.Context, request *DropTagRequest) error
Undrop(ctx context.Context, request *UndropTagRequest) error
}

// createTagOptions is based on https://docs.snowflake.com/en/sql-reference/sql/create-tag
type createTagOptions struct {
create bool `ddl:"static" sql:"CREATE"`
OrReplace *bool `ddl:"keyword" sql:"OR REPLACE"`
tag string `ddl:"static" sql:"TAG"`
IfNotExists *bool `ddl:"keyword" sql:"IF NOT EXISTS"`
name AccountObjectIdentifier `ddl:"identifier"`
Comment *string `ddl:"parameter,single_quotes" sql:"COMMENT"`
AllowedValues *AllowedValues `ddl:"keyword" sql:"ALLOWED_VALUES"`
}

type AllowedValues struct {
Values []AllowedValue `ddl:"list,comma"`
}

type AllowedValue struct {
Value string `ddl:"keyword,single_quotes"`
}

// showTagOptions is based on https://docs.snowflake.com/en/sql-reference/sql/show-tags
type showTagOptions struct {
show bool `ddl:"static" sql:"SHOW"`
tag bool `ddl:"static" sql:"TAGS"`
Like *Like `ddl:"keyword" sql:"LIKE"`
In *In `ddl:"keyword" sql:"IN"`
}

type Tag struct {
DatabaseName string
SchemaName string
Name string
CreatedOn time.Time
Name string
DatabaseName string
SchemaName string
Owner string
Comment string
AllowedValues []string
OwnerRole string
}

func (v *Tag) ID() SchemaObjectIdentifier {
return NewSchemaObjectIdentifier(v.DatabaseName, v.SchemaName, v.Name)
}

func (v *Tag) ObjectType() ObjectType {
return ObjectTypeTag
type tagRow struct {
CreatedOn time.Time `db:"created_on"`
Name string `db:"name"`
DatabaseName string `db:"database_name"`
SchemaName string `db:"schema_name"`
Owner string `db:"owner"`
Comment string `db:"comment"`
AllowedValues sql.NullString `db:"allowed_values"`
OwnerRoleType string `db:"owner_role_type"`
}

func (tr tagRow) convert() *Tag {
t := &Tag{
CreatedOn: tr.CreatedOn,
Name: tr.Name,
DatabaseName: tr.DatabaseName,
SchemaName: tr.SchemaName,
Owner: tr.Owner,
Comment: tr.Comment,
OwnerRole: tr.OwnerRoleType,
}
if tr.AllowedValues.Valid {
s := strings.Trim(tr.AllowedValues.String, "[]") // remove brackets
items := strings.Split(s, ",")
values := make([]string, len(items))
for i, item := range items {
values[i] = strings.Trim(item, `"`) // remove quotes
}
t.AllowedValues = values
}
return t
}

type TagSetMaskingPolicies struct {
MaskingPolicies []TagMaskingPolicy `ddl:"list,comma"`
Force *bool `ddl:"keyword" sql:"FORCE"`
}

type TagUnsetMaskingPolicies struct {
MaskingPolicies []TagMaskingPolicy `ddl:"list,comma"`
}

type TagMaskingPolicy struct {
Name string `ddl:"parameter,no_equals" sql:"MASKING POLICY"`
}

type TagSet struct {
MaskingPolicies *TagSetMaskingPolicies `ddl:"keyword"`
Comment *string `ddl:"parameter,single_quotes" sql:"COMMENT"`
}

type TagUnset struct {
MaskingPolicies *TagUnsetMaskingPolicies `ddl:"keyword"`
AllowedValues *bool `ddl:"keyword" sql:"ALLOWED_VALUES"`
Comment *bool `ddl:"keyword" sql:"COMMENT"`
}

type TagAdd struct {
AllowedValues *AllowedValues `ddl:"keyword" sql:"ALLOWED_VALUES"`
}

type TagDrop struct {
AllowedValues *AllowedValues `ddl:"keyword" sql:"ALLOWED_VALUES"`
}

// alterTagOptions is based on https://docs.snowflake.com/en/sql-reference/sql/alter-tag
type alterTagOptions struct {
alter bool `ddl:"static" sql:"ALTER"`
tag string `ddl:"static" sql:"TAG"`
name AccountObjectIdentifier `ddl:"identifier"`

// One of
Add *TagAdd `ddl:"keyword" sql:"ADD"`
Drop *TagDrop `ddl:"keyword" sql:"DROP"`
Set *TagSet `ddl:"keyword" sql:"SET"`
Unset *TagUnset `ddl:"keyword" sql:"UNSET"`
RenameTo *string `ddl:"parameter,no_equals" sql:"RENAME TO"`
}

// dropTagOptions is based on https://docs.snowflake.com/en/sql-reference/sql/drop-tag
type dropTagOptions struct {
drop bool `ddl:"static" sql:"DROP"`
tag string `ddl:"static" sql:"TAG"`
IfNotExists *bool `ddl:"keyword" sql:"IF NOT EXISTS"`
name AccountObjectIdentifier `ddl:"identifier"`
}

// undropTagOptions is based on https://docs.snowflake.com/en/sql-reference/sql/undrop-tag
type undropTagOptions struct {
undrop bool `ddl:"static" sql:"UNDROP"`
tag string `ddl:"static" sql:"TAG"`
name AccountObjectIdentifier `ddl:"identifier"`
}
34 changes: 34 additions & 0 deletions pkg/sdk/tags_dto.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package sdk

var (
_ optionsProvider[createTagOptions] = new(CreateTagRequest)
_ optionsProvider[showTagOptions] = new(ShowTagRequest)
_ optionsProvider[dropTagOptions] = new(DropTagRequest)
_ optionsProvider[undropTagOptions] = new(UndropTagRequest)
)

type CreateTagRequest struct {
orReplace bool
ifNotExists bool

name AccountObjectIdentifier // required

// One of
comment *string
allowedValues *AllowedValues
}

type ShowTagRequest struct {
like *Like
in *In
}

type DropTagRequest struct {
ifNotExists bool

name AccountObjectIdentifier // required
}

type UndropTagRequest struct {
name AccountObjectIdentifier // required
}
69 changes: 69 additions & 0 deletions pkg/sdk/tags_dto_builders.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package sdk

func NewCreateTagRequest(name AccountObjectIdentifier) *CreateTagRequest {
s := CreateTagRequest{}
s.name = name
return &s
}

func (s *CreateTagRequest) WithOrReplace(orReplace bool) *CreateTagRequest {
s.orReplace = orReplace
return s
}

func (s *CreateTagRequest) WithIfNotExists(ifNotExists bool) *CreateTagRequest {
s.ifNotExists = ifNotExists
return s
}

func (s *CreateTagRequest) WithComment(comment *string) *CreateTagRequest {
s.comment = comment
return s
}

func (s *CreateTagRequest) WithAllowedValues(values []string) *CreateTagRequest {
if len(values) > 0 {
s.allowedValues = &AllowedValues{
Values: make([]AllowedValue, 0, len(values)),
}
for _, value := range values {
s.allowedValues.Values = append(s.allowedValues.Values, AllowedValue{
Value: value,
})
}
}
return s
}

func NewShowTagRequest() *ShowTagRequest {
return &ShowTagRequest{}
}

func (s *ShowTagRequest) WithLike(pattern string) *ShowTagRequest {
s.like = &Like{
Pattern: String(pattern),
}
return s
}

func (s *ShowTagRequest) WithIn(in *In) *ShowTagRequest {
s.in = in
return s
}

func NewDropTagRequest(name AccountObjectIdentifier) *DropTagRequest {
s := DropTagRequest{}
s.name = name
return &s
}

func (s *DropTagRequest) WithIfNotExists(ifNotExists bool) *DropTagRequest {
s.ifNotExists = ifNotExists
return s
}

func NewUndropTagRequest(name AccountObjectIdentifier) *UndropTagRequest {
s := UndropTagRequest{}
s.name = name
return &s
}
Loading

0 comments on commit 7060e2d

Please sign in to comment.