252 lines
6.8 KiB
CUE
252 lines
6.8 KiB
CUE
package codegen
|
|
|
|
import (
|
|
"strings"
|
|
"list"
|
|
"github.com/cortezaproject/corteza/server/app"
|
|
"github.com/cortezaproject/corteza/server/codegen/schema"
|
|
)
|
|
|
|
|
|
_StoreResource: {
|
|
res = "res": schema.#Resource
|
|
typePkg = "typePkg": string
|
|
|
|
|
|
pkAttrNames: [string, ...]
|
|
hasPrimaryKey: res.model.indexes.primary != _|_
|
|
|
|
if hasPrimaryKey {
|
|
// primary key flag is no longer explicitly set on
|
|
// the attribute but via model.indexes.primary
|
|
pkAttrNames: [
|
|
for f in res.model.indexes.primary.fields { f.attribute }
|
|
]
|
|
}
|
|
|
|
result: {
|
|
ident: res.store.ident
|
|
identPlural: res.store.identPlural
|
|
expIdent: res.store.expIdent
|
|
expIdentPlural: res.store.expIdentPlural
|
|
modelIdent: res.model.ident
|
|
goType: "\(typePkg).\(res.expIdent)"
|
|
goSetType: "\(typePkg).\(res.expIdent)Set"
|
|
goFilterType: "\(typePkg).\(res.filter.expIdent)"
|
|
|
|
|
|
struct: [ for attr in res.model.attributes if attr.store {
|
|
"ident": attr.ident
|
|
"expIdent": attr.expIdent
|
|
"storeIdent": attr.storeIdent
|
|
"name": attr.name
|
|
"primaryKey": list.Contains(pkAttrNames, attr.name)
|
|
"ignoreCase": attr.ignoreCase
|
|
"goType": strings.Replace(attr.goType, "types.", "\(typePkg).", 1)
|
|
}]
|
|
|
|
filter: {
|
|
// query fields as defined in struct
|
|
"query": [ for name in res.filter.query {res.model.attributes[name]}],
|
|
|
|
// filter by nil state as defined in filter
|
|
"byNilState": [ for name in res.filter.byNilState {res.filter.struct[name]}]
|
|
|
|
// filter by false as defined in filter
|
|
"byFalseState": [ for name in res.filter.byFalseState {res.filter.struct[name]}]
|
|
|
|
// filter by value as defined in filter
|
|
// @todo this should be pulled from the struct
|
|
"byValue": [ for name in res.filter.byValue {res.filter.struct[name]}]
|
|
"byLabel": res.features.labels
|
|
"byFlag": res.features.flags
|
|
}
|
|
|
|
auxIdent: "aux\(expIdent)"
|
|
auxStruct: struct
|
|
|
|
features: {
|
|
paging: res.features.paging
|
|
sorting: res.features.sorting
|
|
checkFn: res.features.checkFn
|
|
}
|
|
|
|
api: {
|
|
if res.store.api != _|_ {
|
|
_base: {
|
|
"ident": res.store.ident
|
|
"expStoreIdent": res.store.expIdentPlural
|
|
"goType": goType
|
|
"goFilterType": goFilterType
|
|
"auxIdent": auxIdent
|
|
}
|
|
|
|
if hasPrimaryKey {
|
|
deleteByPK: {
|
|
"pkAttrNames": pkAttrNames,
|
|
attributes: [ for attr in pkAttrNames { res.model.attributes[attr] } ]
|
|
_expIdents: strings.Join([ for attr in pkAttrNames { res.model.attributes[attr].expIdent } ], "")
|
|
"expFnIdent": "Delete\(res.store.expIdent)By\(_expIdents)"
|
|
}
|
|
}
|
|
|
|
lookups: [
|
|
for l in res.store.api.lookups {
|
|
_base
|
|
|
|
"expFnIdent": l.expIdent
|
|
|
|
if (l.description != _|_) {
|
|
description: "// \(l.expIdent) " + strings.Join(strings.Split(l.description, "\n"), "\n// ")
|
|
}
|
|
|
|
// Copy all relevant fields from the struct
|
|
"args": [
|
|
for name in l.fields {
|
|
let attr = res.model.attributes[name]
|
|
|
|
"ident": attr.ident
|
|
"storeIdent": attr.storeIdent
|
|
"goType": attr.goType
|
|
"ignoreCase": attr.ignoreCase
|
|
},
|
|
]
|
|
|
|
"nullConstraint": l.nullConstraint
|
|
"returnType": "\(goType)"
|
|
"collectionFnIdent": "\(res.store.ident)Collection"
|
|
},
|
|
]
|
|
|
|
// all additional store functions we need for this resource
|
|
functions: [
|
|
for f in res.store.api.functions {
|
|
_base
|
|
|
|
"expFnIdent": f.expIdent
|
|
|
|
if (f.description != _|_) {
|
|
description: "// \(f.expIdent) " + strings.Join(strings.Split(f.description, "\n"), "\n// ")
|
|
}
|
|
|
|
"args": [ for a in f.args {
|
|
"ident": a.ident
|
|
"goType": strings.Replace(a.goType, "types.", "\(typePkg).", 1)
|
|
"spread": a.spread
|
|
}]
|
|
"return": [ for r in f.return {strings.Replace(r, "types.", "\(typePkg).", 1)}]
|
|
},
|
|
]
|
|
|
|
sortableFields: {
|
|
_base
|
|
|
|
"fnIdent": "sortable\(expIdent)Fields"
|
|
|
|
fields: {
|
|
for attr in res.model.attributes if attr.sortable || attr.unique || list.Contains(pkAttrNames, attr.name) {
|
|
{
|
|
"\(strings.ToLower(attr.name))": attr.name
|
|
"\(strings.ToLower(attr.ident))": attr.name
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
collectCursorValues: {
|
|
_base
|
|
|
|
"fnIdent": "collect\(expIdent)CursorValues"
|
|
|
|
fields: [ for attr in res.model.attributes if attr.sortable || attr.unique || list.Contains(pkAttrNames, attr.name) {
|
|
attr
|
|
"primaryKey": list.Contains(pkAttrNames, attr.name)
|
|
} ]
|
|
|
|
primaryKeys: [ for attr in res.model.attributes if list.Contains(pkAttrNames, attr.name) {attr} ]
|
|
}
|
|
|
|
checkConstraints: {
|
|
_base
|
|
|
|
"fnIdent": "check\(expIdent)Constraints"
|
|
|
|
checks: [
|
|
for lookup in res.store.api.lookups if lookup.constraintCheck {
|
|
lookupFnIdent: lookup.expIdent
|
|
fields: [ for name in lookup.fields {res.model.attributes[name]}]
|
|
nullConstraint: [
|
|
for f in res.model.attributes if list.Contains(lookup.nullConstraint, f.name) {
|
|
"expIdent": f.expIdent
|
|
},
|
|
]
|
|
},
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Codegen template payload, reused for multiple outputs
|
|
_payload: {
|
|
package: string | *"store"
|
|
|
|
imports: {
|
|
// per-component type imports
|
|
for cmp in app.corteza.components for res in cmp.resources if res.store != _|_ {
|
|
"github.com/cortezaproject/corteza/server/\(cmp.ident)/types": "\(cmp.ident)Type"
|
|
}
|
|
|
|
for res in app.corteza.resources if res.store != _|_ {
|
|
"\(res.package.import)": "\(res.package.ident)Type"
|
|
}
|
|
|
|
for cmp in app.corteza.components for res in cmp.resources for i in res.imports {
|
|
"\(i.import)": ""
|
|
}
|
|
}
|
|
|
|
types: {
|
|
// for each resource in every store with store and actions defined
|
|
for cmp in app.corteza.components for res in cmp.resources if res.store != _|_ {
|
|
// use _Store resource as a function (https://cuetorials.com/patterns/functions/)
|
|
// and pass res(ource) and type-package string in as "arguments"
|
|
"\(res.store.ident)": { _StoreResource & { "res": res, "typePkg": "\(cmp.ident)Type" } }.result
|
|
},
|
|
|
|
for res in app.corteza.resources if res.store != _|_ {
|
|
"\(res.store.ident)": { _StoreResource & { "res": res, "typePkg": "\(res.package.ident)Type" } }.result
|
|
}
|
|
}
|
|
}
|
|
|
|
[...schema.#codegen] &
|
|
[
|
|
{
|
|
"bulk": [
|
|
{
|
|
"template": "gocode/store/interfaces.go.tpl"
|
|
"output": "store/interfaces.gen.go"
|
|
}, {
|
|
"template": "gocode/store/rdbms/rdbms.go.tpl"
|
|
"output": "store/adapters/rdbms/rdbms.gen.go"
|
|
}, {
|
|
"template": "gocode/store/rdbms/aux_types.go.tpl"
|
|
"output": "store/adapters/rdbms/aux_types.gen.go"
|
|
}, {
|
|
"template": "gocode/store/rdbms/queries.go.tpl"
|
|
"output": "store/adapters/rdbms/queries.gen.go"
|
|
}, {
|
|
"template": "gocode/store/rdbms/filters.go.tpl"
|
|
"output": "store/adapters/rdbms/filters.gen.go"
|
|
}, {
|
|
"template": "gocode/store/tests/all.go.tpl"
|
|
"output": "store/tests/all_test.go"
|
|
},
|
|
]
|
|
|
|
"payload": { _payload }
|
|
},
|
|
]
|