cosmos-sdk/orm/internal/codegen/index.go

140 lines
3.7 KiB
Go

package codegen
import (
"fmt"
"strings"
"github.com/iancoleman/strcase"
"google.golang.org/protobuf/reflect/protoreflect"
)
func (t tableGen) genIndexKeys() {
// interface that all keys must adhere to
t.P("type ", t.indexKeyInterfaceName(), " interface {")
t.P("id() uint32")
t.P("values() []interface{}")
t.P(t.param(t.indexKeyInterfaceName()), "()")
t.P("}")
t.P()
// start with primary key..
t.P("// primary key starting index..")
t.genIndex(t.table.PrimaryKey.Fields, 0, true)
for _, idx := range t.table.Index {
t.genIndex(idx.Fields, idx.Id, false)
}
}
func (t tableGen) genIterator() {
t.P("type ", t.iteratorName(), " struct {")
t.P(ormTablePkg.Ident("Iterator"))
t.P("}")
t.P()
t.genValueFunc()
t.P()
}
func (t tableGen) genValueFunc() {
varName := t.param(t.msg.GoIdent.GoName)
t.P("func (i ", t.iteratorName(), ") Value() (*", t.QualifiedGoIdent(t.msg.GoIdent), ", error) {")
t.P("var ", varName, " ", t.QualifiedGoIdent(t.msg.GoIdent))
t.P("err := i.UnmarshalMessage(&", varName, ")")
t.P("return &", varName, ", err")
t.P("}")
}
func (t tableGen) genIndexMethods(idxKeyName string) {
receiverFunc := fmt.Sprintf("func (x %s) ", idxKeyName)
t.P(receiverFunc, "id() uint32 { return ", t.table.Id, " /* primary key */ }")
t.P(receiverFunc, "values() []interface{} { return x.vs }")
t.P(receiverFunc, t.param(t.indexKeyInterfaceName()), "() {}")
t.P()
}
func (t tableGen) genIndexInterfaceGuard(idxKeyName string) {
t.P("var _ ", t.indexKeyInterfaceName(), " = ", idxKeyName, "{}")
t.P()
}
func (t tableGen) indexKeyInterfaceName() string {
return t.msg.GoIdent.GoName + "IndexKey"
}
func (t tableGen) genIndexKey(idxKeyName string) {
t.P("type ", idxKeyName, " struct {")
t.P("vs []interface{}")
t.P("}")
t.P()
}
func (t tableGen) indexKeyParts(names []protoreflect.Name) string {
cnames := make([]string, len(names))
for i, name := range names {
cnames[i] = strcase.ToCamel(string(name))
}
return strings.Join(cnames, "")
}
func (t tableGen) indexKeyName(names []protoreflect.Name) string {
cnames := make([]string, len(names))
for i, name := range names {
cnames[i] = strcase.ToCamel(string(name))
}
joinedNames := strings.Join(cnames, "")
return t.msg.GoIdent.GoName + joinedNames + "IndexKey"
}
func (t tableGen) indexStructName(fields []string) string {
names := make([]string, len(fields))
for i, field := range fields {
names[i] = strcase.ToCamel(field)
}
joinedNames := strings.Join(names, "")
return t.msg.GoIdent.GoName + joinedNames + "IndexKey"
}
func (t tableGen) genIndex(fields string, id uint32, isPrimaryKey bool) {
fieldsSlc := strings.Split(fields, ",")
idxKeyName := t.indexStructName(fieldsSlc)
if isPrimaryKey {
t.P("type ", t.msg.GoIdent.GoName, "PrimaryKey = ", idxKeyName)
t.P()
}
t.P("type ", idxKeyName, " struct {")
t.P("vs []interface{}")
t.P("}")
t.genIndexInterfaceMethods(id, idxKeyName)
for i := 1; i < len(fieldsSlc)+1; i++ {
t.genWithMethods(idxKeyName, fieldsSlc[:i])
}
}
func (t tableGen) genIndexInterfaceMethods(id uint32, indexStructName string) {
funPrefix := fmt.Sprintf("func (x %s) ", indexStructName)
t.P(funPrefix, "id() uint32 {return ", id, "}")
t.P(funPrefix, "values() []interface{} {return x.vs}")
t.P(funPrefix, t.param(t.indexKeyInterfaceName()), "() {}")
t.P()
}
func (t tableGen) genWithMethods(indexStructName string, parts []string) {
funcPrefix := fmt.Sprintf("func (this %s) ", indexStructName)
camelParts := make([]string, len(parts))
for i, part := range parts {
camelParts[i] = strcase.ToCamel(part)
}
funcName := "With" + strings.Join(camelParts, "")
t.P(funcPrefix, funcName, "(", t.fieldArgsFromStringSlice(parts), ") ", indexStructName, "{")
t.P("this.vs = []interface{}{", strings.Join(parts, ","), "}")
t.P("return this")
t.P("}")
t.P()
}