Skip to content

Commit

Permalink
add enum support for modelgen
Browse files Browse the repository at this point in the history
Fix #133
  • Loading branch information
halfcrazy committed Jun 9, 2021
1 parent b105494 commit 22eafef
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 32 deletions.
76 changes: 72 additions & 4 deletions modelgen/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,24 @@ const BASE_TABLE_TEMPLATE = `{{ template "header" . }}
package {{ index . "PackageName" }}
{{ if .Enums }}
type (
{{ range .Enums }}
{{ $e := . }}
{{ $e.Alias }} {{ $e.Type }}
{{- end }}
)
const (
{{ range .Enums }}
{{ $e := . }}
{{ range .Sets }}
{{ $e.Alias }}{{ camelCase . }} {{ $e.Alias }} = {{ printVal . $e.Type }}
{{- end }}
{{- end }}
)
{{ end }}
{{ template "preStructDefinitions" }}
{{ template "structComment" . }}
type {{ index . "StructName" }} struct {
Expand Down Expand Up @@ -53,6 +71,13 @@ const DEFAULT_EXTRA_FIELDS_TEMPLATE = `{{ define "extraFields" }}{{ end }}`
// DEFAULT_POST_TABLE_TEMPLATE is the default template for "postStructDefinitions"
const DEFAULT_POST_TABLE_TEMPLATE = `{{ define "postStructDefinitions" }}{{ end }}`

// Enum represents the enum schema type
type Enum struct {
Type string
Alias string
Sets []interface{}
}

// Field represents the field information
type Field struct {
Column string
Expand All @@ -72,6 +97,7 @@ func GetTableTemplateData(pkg, name string, table *ovsdb.TableSchema) map[string
data["PackageName"] = pkg
data["StructName"] = StructName(name)
Fields := []Field{}
Enums := []Enum{}

// First, add UUID
Fields = append(Fields,
Expand All @@ -95,18 +121,26 @@ func GetTableTemplateData(pkg, name string, table *ovsdb.TableSchema) map[string
Fields = append(Fields, Field{
Column: columnName,
Name: FieldName(columnName),
Type: FieldType(columnSchema),
Type: FieldType(name, columnName, columnSchema),
Tag: Tag(columnName),
})
if enum := FieldEnum(name, columnName, columnSchema); enum != nil {
Enums = append(Enums, *enum)
}
}
data["Fields"] = Fields
data["Enums"] = Enums
return data
}

// NewTableTemplate returns a new TableTemplate and the TableTemplate data map
// See BASE_TABLE_TEMPLATE to a detailed explanation of the possible ways this template can be expanded
func NewTableTemplate(pkg string, name string, table *ovsdb.TableSchema) (*template.Template, map[string]interface{}) {
main, err := template.New(name).Parse(BASE_TABLE_TEMPLATE)
funcMap := template.FuncMap{
"printVal": printVal,
"camelCase": camelCase,
}
main, err := template.New(name).Funcs(funcMap).Parse(BASE_TABLE_TEMPLATE)
if err != nil {
panic(err)
}
Expand Down Expand Up @@ -148,20 +182,34 @@ func StructName(tableName string) string {
}

// FieldType returns the string representation of a column type
func FieldType(column *ovsdb.ColumnSchema) string {
func FieldType(tableName, columnName string, column *ovsdb.ColumnSchema) string {
switch column.Type {
case ovsdb.TypeEnum:
return AtomicType(column.TypeObj.Key.Type)
return strings.Title(StructName(tableName)) + camelCase(columnName)
case ovsdb.TypeMap:
return fmt.Sprintf("map[%s]%s", AtomicType(column.TypeObj.Key.Type),
AtomicType(column.TypeObj.Value.Type))
case ovsdb.TypeSet:
if FieldEnum(tableName, columnName, column) != nil {
return fmt.Sprintf("[]%s%s", strings.Title(StructName(tableName)), camelCase(columnName))
}
return fmt.Sprintf("[]%s", AtomicType(column.TypeObj.Key.Type))
default:
return AtomicType(column.Type)
}
}

func FieldEnum(tableName, columnName string, column *ovsdb.ColumnSchema) *Enum {
if column.TypeObj.Key.Enum == nil {
return nil
}
return &Enum{
Type: column.TypeObj.Key.Type,
Alias: strings.Title(StructName(tableName)) + camelCase(columnName),
Sets: column.TypeObj.Key.Enum,
}
}

// BasicType returns the string type of an AtomicType
func AtomicType(atype string) string {
switch atype {
Expand Down Expand Up @@ -211,9 +259,15 @@ var initialisms = map[string]bool{
"SSL": true,
"STP": true,
"TCP": true,
"SCTP": true,
"UDP": true,
"UUID": true,
"VLAN": true,
"STT": true,
"DNAT": true,
"SNAT": true,
"ICMP": true,
"SLB": true,
}

func camelCase(field string) string {
Expand Down Expand Up @@ -246,3 +300,17 @@ func expandInitilaisms(s string) string {
}
return s
}

func printVal(v interface{}, t string) string {
switch t {
case "int":
return fmt.Sprintf(`%d`, v)
case "float64":
return fmt.Sprintf(`%f`, v)
case "bool":
return fmt.Sprintf(`%t`, v)
case "string":
return fmt.Sprintf(`"%s"`, v)
}
return ""
}
113 changes: 85 additions & 28 deletions modelgen/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func TestNewTableTemplate(t *testing.T) {
"name": "AtomicDB",
"version": "0.0.0",
"tables": {
"atomicTable": {
"AtomicTable": {
"columns": {
"str": {
"type": "string"
Expand All @@ -26,7 +26,13 @@ func TestNewTableTemplate(t *testing.T) {
},
"float": {
"type": "real"
}
},
"protocol": {
"type": {"key": {"type": "string",
"enum": ["set", ["tcp", "udp", "sctp"]]},
"min": 0, "max": 1}},
"event_type": {"type": {"key": {"type": "string",
"enum": ["set", ["empty_lb_backends"]]}}}
}
}
}
Expand All @@ -46,12 +52,28 @@ func TestNewTableTemplate(t *testing.T) {
package test
// test defines an object in test table
type test struct {
UUID string ` + "`" + `ovs:"_uuid"` + "`" + `
Float float64 ` + "`" + `ovs:"float"` + "`" + `
Int int ` + "`" + `ovs:"int"` + "`" + `
Str string ` + "`" + `ovs:"str"` + "`" + `
type (
AtomicTableEventType string
AtomicTableProtocol string
)
const (
AtomicTableEventTypeEmptyLbBackends AtomicTableEventType = "empty_lb_backends"
AtomicTableProtocolTCP AtomicTableProtocol = "tcp"
AtomicTableProtocolUDP AtomicTableProtocol = "udp"
AtomicTableProtocolSCTP AtomicTableProtocol = "sctp"
)
// AtomicTable defines an object in AtomicTable table
type AtomicTable struct {
UUID string ` + "`" + `ovs:"_uuid"` + "`" + `
EventType AtomicTableEventType ` + "`" + `ovs:"event_type"` + "`" + `
Float float64 ` + "`" + `ovs:"float"` + "`" + `
Int int ` + "`" + `ovs:"int"` + "`" + `
Protocol []AtomicTableProtocol ` + "`" + `ovs:"protocol"` + "`" + `
Str string ` + "`" + `ovs:"str"` + "`" + `
}
`,
},
Expand All @@ -70,17 +92,35 @@ type test struct {
package test
// test defines an object in test table
type test struct {
UUID string ` + "`" + `ovs:"_uuid"` + "`" + `
Float float64 ` + "`" + `ovs:"float"` + "`" + `
Int int ` + "`" + `ovs:"int"` + "`" + `
Str string ` + "`" + `ovs:"str"` + "`" + `
OtherUUID string
OtherFloat float64
OtherInt int
OtherStr string
type (
AtomicTableEventType string
AtomicTableProtocol string
)
const (
AtomicTableEventTypeEmptyLbBackends AtomicTableEventType = "empty_lb_backends"
AtomicTableProtocolTCP AtomicTableProtocol = "tcp"
AtomicTableProtocolUDP AtomicTableProtocol = "udp"
AtomicTableProtocolSCTP AtomicTableProtocol = "sctp"
)
// AtomicTable defines an object in AtomicTable table
type AtomicTable struct {
UUID string ` + "`" + `ovs:"_uuid"` + "`" + `
EventType AtomicTableEventType ` + "`" + `ovs:"event_type"` + "`" + `
Float float64 ` + "`" + `ovs:"float"` + "`" + `
Int int ` + "`" + `ovs:"int"` + "`" + `
Protocol []AtomicTableProtocol ` + "`" + `ovs:"protocol"` + "`" + `
Str string ` + "`" + `ovs:"str"` + "`" + `
OtherUUID string
OtherEventType AtomicTableEventType
OtherFloat float64
OtherInt int
OtherProtocol []AtomicTableProtocol
OtherStr string
}
`,
},
Expand All @@ -103,16 +143,32 @@ func {{ index . "TestName" }} () string {
package test
// test defines an object in test table
type test struct {
UUID string ` + "`" + `ovs:"_uuid"` + "`" + `
Float float64 ` + "`" + `ovs:"float"` + "`" + `
Int int ` + "`" + `ovs:"int"` + "`" + `
Str string ` + "`" + `ovs:"str"` + "`" + `
type (
AtomicTableEventType string
AtomicTableProtocol string
)
const (
AtomicTableEventTypeEmptyLbBackends AtomicTableEventType = "empty_lb_backends"
AtomicTableProtocolTCP AtomicTableProtocol = "tcp"
AtomicTableProtocolUDP AtomicTableProtocol = "udp"
AtomicTableProtocolSCTP AtomicTableProtocol = "sctp"
)
// AtomicTable defines an object in AtomicTable table
type AtomicTable struct {
UUID string ` + "`" + `ovs:"_uuid"` + "`" + `
EventType AtomicTableEventType ` + "`" + `ovs:"event_type"` + "`" + `
Float float64 ` + "`" + `ovs:"float"` + "`" + `
Int int ` + "`" + `ovs:"int"` + "`" + `
Protocol []AtomicTableProtocol ` + "`" + `ovs:"protocol"` + "`" + `
Str string ` + "`" + `ovs:"str"` + "`" + `
}
func TestFunc() string {
return "test"
return "AtomicTable"
}
`,
},
Expand Down Expand Up @@ -140,10 +196,11 @@ WRONG FORMAT

for _, tt := range test {
t.Run(fmt.Sprintf("Table Test: %s", tt.name), func(t *testing.T) {
table := schema.Tables["atomicTable"]
fakeTable := "AtomicTable"
table := schema.Tables[fakeTable]
templ, data := NewTableTemplate(
"test",
"test",
fakeTable,
&table,
)
if tt.err {
Expand Down

0 comments on commit 22eafef

Please sign in to comment.