Skip to content

Commit

Permalink
ref
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-fbudzynski committed Dec 18, 2024
1 parent 268e2d8 commit c60dec5
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 49 deletions.
26 changes: 26 additions & 0 deletions pkg/sdk/poc/generator/interface.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
package generator

import "fmt"

type objectIdentifier string

const (
AccountObjectIdentifier objectIdentifier = "AccountObjectIdentifier"
DatabaseObjectIdentifier objectIdentifier = "DatabaseObjectIdentifier"
SchemaObjectIdentifier objectIdentifier = "SchemaObjectIdentifier"
SchemaObjectIdentifierWithArguments objectIdentifier = "SchemaObjectIdentifierWithArguments"
)

func identifierStringToObjectIdentifier(s string) (objectIdentifier, error) {
switch s {
case "AccountObjectIdentifier":
return AccountObjectIdentifier, nil
case "DatabaseObjectIdentifier":
return DatabaseObjectIdentifier, nil
case "SchemaObjectIdentifier":
return SchemaObjectIdentifier, nil
case "SchemaObjectIdentifierWithArguments":
return SchemaObjectIdentifierWithArguments, nil
default:
return "", fmt.Errorf("invalid string identifier type: %s", s)
}
}

// Interface groups operations for particular object or objects family (e.g. DATABASE ROLE)
type Interface struct {
// Name is the interface's name, e.g. "DatabaseRoles"
Expand Down
8 changes: 4 additions & 4 deletions pkg/sdk/poc/generator/operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ func (i *Interface) newOperationWithDBMapping(
resourceRepresentation *plainStruct,
queryStruct *QueryStruct,
addMappingFunc func(op *Operation, from, to *Field),
resourceHelperMethods ...ShowObjectMethodKind,
showObjectMethods ...ShowObjectMethodType,
) *Operation {
db := dbRepresentation.IntoField()
res := resourceRepresentation.IntoField()
Expand All @@ -136,7 +136,7 @@ func (i *Interface) newOperationWithDBMapping(
withHelperStruct(res).
withOptionsStruct(queryStruct.IntoField()).
withObjectInterface(i).
withShowObjectMethods(res.Name, resourceHelperMethods...)
withShowObjectMethods(res.Name, showObjectMethods...)

addMappingFunc(op, db, res)
i.Operations = append(i.Operations, op)
Expand Down Expand Up @@ -167,8 +167,8 @@ func (i *Interface) RevokeOperation(doc string, queryStruct *QueryStruct) *Inter
return i.newSimpleOperation(string(OperationKindRevoke), doc, queryStruct)
}

func (i *Interface) ShowOperation(doc string, dbRepresentation *dbStruct, resourceRepresentation *plainStruct, queryStruct *QueryStruct, helperMethods ...ShowObjectMethodKind) *Interface {
i.newOperationWithDBMapping(string(OperationKindShow), doc, dbRepresentation, resourceRepresentation, queryStruct, addShowMapping, helperMethods...)
func (i *Interface) ShowOperation(doc string, dbRepresentation *dbStruct, resourceRepresentation *plainStruct, queryStruct *QueryStruct, showObjectMethods ...ShowObjectMethodType) *Interface {
i.newOperationWithDBMapping(string(OperationKindShow), doc, dbRepresentation, resourceRepresentation, queryStruct, addShowMapping, showObjectMethods...)
return i
}

Expand Down
68 changes: 23 additions & 45 deletions pkg/sdk/poc/generator/show_object_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,10 @@ import (
"slices"
)

type objectIdentifier string
type ShowObjectMethodType uint

const (
AccountObjectIdentifier objectIdentifier = "AccountObjectIdentifier"
DatabaseObjectIdentifier objectIdentifier = "DatabaseObjectIdentifier"
SchemaObjectIdentifier objectIdentifier = "SchemaObjectIdentifier"
SchemaObjectIdentifierWithArguments objectIdentifier = "SchemaObjectIdentifierWithArguments"
)

func identifierStringToObjectIdentifier(s string) objectIdentifier {
switch s {
case "AccountObjectIdentifier":
return AccountObjectIdentifier
case "DatabaseObjectIdentifier":
return DatabaseObjectIdentifier
case "SchemaObjectIdentifier":
return SchemaObjectIdentifier
case "SchemaObjectIdentifierWithArguments":
return SchemaObjectIdentifierWithArguments
default:
return ""
}
}

type ShowObjectMethodKind uint

const (
ShowObjectIdMethod ShowObjectMethodKind = iota
ShowObjectIdMethod ShowObjectMethodType = iota
ShowObjectTypeMethod
)

Expand All @@ -59,12 +35,15 @@ var idTypeParts map[objectIdentifier][]string = map[objectIdentifier][]string{
SchemaObjectIdentifier: {"DatabaseName", "SchemaName", "Name"},
}

func hasRequiredFieldsForIDMethod(structName string, helperStructs []*Field, requiredFields ...string) bool {
for _, field := range helperStructs {
if field.Name == structName {
return containsFieldNames(field.Fields, requiredFields...)
func hasRequiredFieldsForIDMethod(structName string, helperStructs []*Field, idType objectIdentifier) bool {
if requiredFields, ok := idTypeParts[idType]; ok {
for _, field := range helperStructs {
if field.Name == structName {
return containsFieldNames(field.Fields, requiredFields...)
}
}
}
log.Printf("[WARN]: No required fields mapping defined for identifier %s", idType)
return false
}

Expand All @@ -82,11 +61,16 @@ func containsFieldNames(fields []*Field, names ...string) bool {
return true
}

func (s *Operation) withShowObjectMethods(structName string, showObjectMethodsKind ...ShowObjectMethodKind) *Operation {
func (s *Operation) withShowObjectMethods(structName string, showObjectMethodsKind ...ShowObjectMethodType) *Operation {
for _, methodKind := range showObjectMethodsKind {
switch methodKind {
case ShowObjectIdMethod:
s.ShowObjectMethods = append(s.ShowObjectMethods, newShowObjectIDMethod(structName, s.HelperStructs, s.ObjectInterface.IdentifierKind))
id, err := identifierStringToObjectIdentifier(s.ObjectInterface.IdentifierKind)
if err != nil {
log.Printf("[WARN]: %v, for showObjectIdMethod", err)
continue
}
s.ShowObjectMethods = append(s.ShowObjectMethods, newShowObjectIDMethod(structName, s.HelperStructs, id))
case ShowObjectTypeMethod:
s.ShowObjectMethods = append(s.ShowObjectMethods, newShowObjectTypeMethod(structName))
default:
Expand All @@ -96,25 +80,19 @@ func (s *Operation) withShowObjectMethods(structName string, showObjectMethodsKi
return s
}

func newShowObjectIDMethod(structName string, helperStructs []*Field, identifierString string) *ShowObjectMethod {
objectIdentifier := identifierStringToObjectIdentifier(identifierString)
requiredFields, ok := idTypeParts[objectIdentifier]
if !ok {
log.Printf("[WARN]: No required fields mapping defined for identifier %s", objectIdentifier)
return nil
}
if !hasRequiredFieldsForIDMethod(structName, helperStructs, requiredFields...) {
log.Printf("[WARN]: Struct '%s' does not contain needed fields to build ID() helper method. Create the method manually in _ext file or add missing one of required fields: %v.\n", structName, requiredFields)
func newShowObjectIDMethod(structName string, helperStructs []*Field, idType objectIdentifier) *ShowObjectMethod {
if !hasRequiredFieldsForIDMethod(structName, helperStructs, idType) {
log.Printf("[WARN]: Struct '%s' does not contain needed fields to build ID() helper method. Create the method manually in _ext file or add missing fields: %v.\n", structName, idTypeParts[idType])
return nil
}

fields := idTypeParts[idType]
var args string
for _, field := range requiredFields {
for _, field := range fields {
args += fmt.Sprintf("v.%v, ", field)
}

returnValue := fmt.Sprintf("New%v(%v)", objectIdentifier, args)
return newShowObjectMethod("ID", structName, returnValue, string(objectIdentifier))
returnValue := fmt.Sprintf("New%v(%v)", idType, args)
return newShowObjectMethod("ID", structName, returnValue, string(idType))
}

func newShowObjectTypeMethod(structName string) *ShowObjectMethod {
Expand Down
50 changes: 50 additions & 0 deletions pkg/sdk/poc/generator/show_object_methods_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package generator

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestIdentifierStringToObjectIdentifier(t *testing.T) {
tests := []struct {
input string
expected objectIdentifier
}{
{"AccountObjectIdentifier", AccountObjectIdentifier},
{"DatabaseObjectIdentifier", DatabaseObjectIdentifier},
{"SchemaObjectIdentifier", SchemaObjectIdentifier},
{"SchemaObjectIdentifierWithArguments", SchemaObjectIdentifierWithArguments},
}

for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
result, err := identifierStringToObjectIdentifier(test.input)
require.NoError(t, err)
require.Equal(t, test.expected, result)
})
}
}

func TestIdentifierStringToObjectIdentifier_Invalid(t *testing.T) {
tests := []struct {
input string
err string
}{
{"accountobjectidentifier", "invalid string identifier type: accountobjectidentifier"},
{"Account", "invalid string identifier type: Account"},
{"databaseobjectidentifier", "invalid string identifier type: databaseobjectidentifier"},
{"Database", "invalid string identifier type: Database"},
{"schemaobjectidentifier", "invalid string identifier type: schemaobjectidentifier"},
{"Schema", "invalid string identifier type: Schema"},
{"schemaobjectidentifierwitharguments", "invalid string identifier type: schemaobjectidentifierwitharguments"},
{"schemawitharguemnts", "invalid string identifier type: schemawitharguemnts"},
}

for _, tc := range tests {
t.Run(tc.input, func(t *testing.T) {
_, err := identifierStringToObjectIdentifier(tc.input)
require.ErrorContains(t, err, tc.err)
})
}
}

0 comments on commit c60dec5

Please sign in to comment.