Generate models for all resources
Some refactoring of CUE files
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
package {{ .package }}
|
||||
|
||||
{{ template "gocode/header-gentext.tpl" }}
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/cortezaproject/corteza-server/pkg/dal"
|
||||
{{- range .imports }}
|
||||
{{ . }}
|
||||
{{- end }}
|
||||
)
|
||||
|
||||
type (
|
||||
modelReplacer interface {
|
||||
ReplaceModel(ctx context.Context, model *dal.Model) (err error)
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
{{ range .models }}
|
||||
{{ .var }} = &dal.Model{
|
||||
Ident: {{ printf "%q" .ident }},
|
||||
ResourceType: {{ .resType }},
|
||||
|
||||
Attributes: dal.AttributeSet{
|
||||
{{ range .attributes }}
|
||||
&dal.Attribute{
|
||||
Ident: {{ printf "%q" .expIdent }},
|
||||
|
||||
{{ if .primaryKey }}PrimaryKey: true, {{ end -}}
|
||||
{{ if .sortable }}Sortable: true, {{ end -}}
|
||||
{{ if .filterable }}Filterable: true, {{ end }}
|
||||
|
||||
Type: {{ .dal.fqType }}{
|
||||
{{ if .dal.nullable }}Nullable: true,{{ end -}}
|
||||
{{ if eq .dal.type "Ref" }}
|
||||
RefAttribute: {{ printf "%q" .dal.attribute }},
|
||||
RefModel: &dal.ModelRef{
|
||||
ResourceType: {{ printf "%q" .dal.refModelResType }},
|
||||
},
|
||||
{{ end }}
|
||||
},
|
||||
|
||||
{{ if .store }}
|
||||
Store: &dal.CodecAlias{Ident: {{ printf "%q" .storeIdent }}},
|
||||
{{ end }}
|
||||
},
|
||||
{{ end -}}
|
||||
},
|
||||
}
|
||||
{{ end }}
|
||||
)
|
||||
|
||||
func Register(ctx context.Context, mr modelReplacer) (err error) {
|
||||
{{- range .models }}
|
||||
if err = mr.ReplaceModel(ctx, {{ .var }}); err != nil {
|
||||
return
|
||||
}
|
||||
{{ end }}
|
||||
|
||||
return
|
||||
}
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
[key=_]: {"handle": key, "component": handle, "platform": platform} & #Resource
|
||||
}
|
||||
|
||||
fqrn: platform + "::" + handle
|
||||
fqrt: platform + "::" + handle
|
||||
|
||||
// All known RBAC operations for this component
|
||||
rbac: #rbacComponent & {
|
||||
|
||||
@@ -11,6 +11,18 @@ import (
|
||||
}
|
||||
}
|
||||
|
||||
#ModelAttributeDalType:
|
||||
"ID" | "Ref" |
|
||||
"Timestamp" | "Time" | "Date" |
|
||||
"Number" |
|
||||
"Text" |
|
||||
"Boolean" |
|
||||
"Enum" |
|
||||
"Geometry" |
|
||||
"JSON" |
|
||||
"Blob" |
|
||||
"UUID"
|
||||
|
||||
// logic in struct fields is a bit different
|
||||
#ModelAttribute: {
|
||||
name: #ident
|
||||
@@ -40,6 +52,55 @@ import (
|
||||
// currently disabled since not used by anything
|
||||
// it adds more than 4x overhead to the time it takes to generate the store code!
|
||||
// #ModelAttributeJsonTag
|
||||
|
||||
dal: {
|
||||
type: #ModelAttributeDalType | * "Text"
|
||||
|
||||
fqType: "dal.Type\(type)"
|
||||
|
||||
nullable: bool | *false
|
||||
|
||||
if type == "ID" {
|
||||
generatedByStore: bool | *false
|
||||
}
|
||||
|
||||
if type == "Ref" {
|
||||
refModelResType: #FQRT
|
||||
attribute: #handle | *"id"
|
||||
}
|
||||
|
||||
if type == "Timestamp" {
|
||||
timezone: bool | *false
|
||||
precision: number | *0
|
||||
}
|
||||
|
||||
if type == "Time" {
|
||||
timezone: bool | *false
|
||||
precision: number | *0
|
||||
}
|
||||
|
||||
if type == "Date" {}
|
||||
|
||||
if type == "Number" {
|
||||
precision: number | *0
|
||||
scale: number | *0
|
||||
}
|
||||
|
||||
if type == "Text" {
|
||||
length: number | *0
|
||||
}
|
||||
|
||||
if type == "Boolean" {}
|
||||
|
||||
if type == "Enum" {
|
||||
values: []
|
||||
}
|
||||
|
||||
if type == "Geometry" {}
|
||||
if type == "JSON" {}
|
||||
if type == "Blob" {}
|
||||
if type == "UUID" {}
|
||||
}
|
||||
}
|
||||
|
||||
IdField: {
|
||||
@@ -51,6 +112,7 @@ IdField: {
|
||||
|
||||
// @todo someday we'll replace this with the "ID" type
|
||||
goType: "uint64"
|
||||
dal: { type: "ID" }
|
||||
}
|
||||
|
||||
HandleField: {
|
||||
@@ -60,16 +122,24 @@ HandleField: {
|
||||
ignoreCase: true
|
||||
|
||||
goType: "string"
|
||||
dal: { type: "Text", length: 255 }
|
||||
}
|
||||
|
||||
AttributeUserRef: {
|
||||
goType: "uint64"
|
||||
dal: { type: "Ref", refModelResType: "corteza::system:user" }
|
||||
}
|
||||
|
||||
SortableTimestampField: {
|
||||
sortable: true
|
||||
goType: "time.Time"
|
||||
dal: { type: "Timestamp", precision: 0, timezone: true, nullable: false }
|
||||
}
|
||||
|
||||
SortableTimestampNilField: {
|
||||
sortable: true
|
||||
goType: "*time.Time"
|
||||
dal: { type: "Timestamp", precision: 0, timezone: true, nullable: true }
|
||||
}
|
||||
|
||||
#ModelAttributeJsonTag: {
|
||||
|
||||
@@ -4,9 +4,14 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// fully qualified resource type
|
||||
#FQRT: =~ "^corteza::(compose|system|federation|automation):[a-z][a-z0-9-]*$"
|
||||
|
||||
#Resource: {
|
||||
#_base
|
||||
|
||||
// type: #resourceType | *""
|
||||
|
||||
imports: [...{ import: string }]
|
||||
|
||||
// copy field values from #_base
|
||||
@@ -16,7 +21,7 @@ import (
|
||||
platform: #baseHandle | *"corteza"
|
||||
|
||||
// Fully qualified resource name
|
||||
fqrn: string | *(platform + "::" + component + ":" + handle)
|
||||
fqrt: #FQRT | *(platform + "::" + component + ":" + handle)
|
||||
|
||||
model: #Model & {
|
||||
// use resource handle (plural) as model ident as default
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
||||
// Identifier
|
||||
#ident: =~"^[a-z][a-zA-Z0-9_]*$"
|
||||
|
||||
@@ -19,7 +20,7 @@ import (
|
||||
#_base: {
|
||||
// lowercase dash-separated words
|
||||
// used to build ident and exported identifiers
|
||||
handle: #baseHandle | *"base"
|
||||
handle: #baseHandle
|
||||
_words: strings.Replace(strings.Replace(strings.Replace(handle, "-", " ", -1), "_", " ", -1), ".", " ", -1)
|
||||
|
||||
// lowercase (unexported, golang) identifier
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package codegen
|
||||
|
||||
import (
|
||||
"github.com/cortezaproject/corteza-server/app"
|
||||
"github.com/cortezaproject/corteza-server/codegen/schema"
|
||||
)
|
||||
|
||||
|
||||
[...schema.#codegen] &
|
||||
[
|
||||
for cmp in app.corteza.components {
|
||||
template: "gocode/dal/$component_model.go.tpl"
|
||||
output: "\(cmp.ident)/model/models.gen.go"
|
||||
payload: {
|
||||
package: "model"
|
||||
|
||||
imports: [
|
||||
"\"github.com/cortezaproject/corteza-server/\(cmp.ident)/types\"",
|
||||
]
|
||||
|
||||
cmpIdent: cmp.ident
|
||||
// Operation/resource validators, grouped by resource
|
||||
models: [
|
||||
for res in cmp.resources if res.model.attributes != _|_ {
|
||||
var: "\(res.expIdent)"
|
||||
resType: "types.\(res.expIdent)ResourceType"
|
||||
|
||||
ident: res.model.ident
|
||||
attributes: [
|
||||
for attr in res.model.attributes {
|
||||
attr
|
||||
}
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
||||
},
|
||||
]
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
types: [
|
||||
for res in cmp.resources if res.rbac != _|_ {
|
||||
const: "\(res.expIdent)ResourceType"
|
||||
type: res.fqrn
|
||||
type: res.fqrt
|
||||
resFunc: "\(res.expIdent)RbacResource"
|
||||
tplFunc: "\(res.expIdent)RbacResourceTpl"
|
||||
attFunc: "\(res.expIdent)RbacAttributes"
|
||||
@@ -28,7 +28,7 @@ import (
|
||||
},
|
||||
{
|
||||
const: "ComponentResourceType"
|
||||
type: cmp.fqrn
|
||||
type: cmp.fqrt
|
||||
resFunc: "ComponentRbacResource"
|
||||
tplFunc: "ComponentRbacResourceTpl"
|
||||
attFunc: "ComponentRbacAttributes"
|
||||
|
||||
@@ -18,11 +18,11 @@ import (
|
||||
types: [
|
||||
for res in cmp.resources {
|
||||
const: "\(res.expIdent)ResourceType"
|
||||
type: res.fqrn
|
||||
type: res.fqrt
|
||||
},
|
||||
{
|
||||
const: "ComponentResourceType"
|
||||
type: cmp.fqrn
|
||||
type: cmp.fqrt
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user