diff --git a/internal/gen.go b/internal/gen.go index 8e69a1c..38e4ed1 100644 --- a/internal/gen.go +++ b/internal/gen.go @@ -5,6 +5,7 @@ import ( "bufio" "bytes" "context" + "sort" //"errors" //"fmt" @@ -21,11 +22,26 @@ import ( type tmplCtx struct { - Q string + Package string + Structs []Struct SqlcVersion string SourceName string } +type Struct struct { + Table *plugin.Identifier + Name string + Fields []Field + Comment string +} + +type Field struct { + Name string // TODO: CamelCase ? snaked-case? + DBName string // Name as used in the DB + Type string + Comment string +} + func Generate(ctx context.Context, req *plugin.GenerateRequest) (*plugin.GenerateResponse, error) { options, err := opts.Parse(req) if err != nil { @@ -36,15 +52,18 @@ func Generate(ctx context.Context, req *plugin.GenerateRequest) (*plugin.Generat return nil, err } - return generate(req, options) + structs := buildStructs(req, options) + + return generate(req, options, structs) } -func generate(req *plugin.GenerateRequest, options *opts.Options) (*plugin.GenerateResponse, error) { +func generate(req *plugin.GenerateRequest, options *opts.Options, structs []Struct) (*plugin.GenerateResponse, error) { tctx := tmplCtx{ - Q: "`", + Package: options.Package, SqlcVersion: req.SqlcVersion, + Structs: structs, } funcMap := template.FuncMap{ @@ -103,3 +122,50 @@ func generate(req *plugin.GenerateRequest, options *opts.Options) (*plugin.Gener return &resp, nil } +func buildStructs(req *plugin.GenerateRequest, options *opts.Options) []Struct { + var structs []Struct + for _, schema := range req.Catalog.Schemas { + if schema.Name == "pg_catalog" || schema.Name == "information_schema" { + continue + } + for _, table := range schema.Tables { + var tableName string + if schema.Name == req.Catalog.DefaultSchema { + tableName = table.Rel.Name + } else { + tableName = schema.Name + "_" + table.Rel.Name + } + + s := Struct{ + Table: &plugin.Identifier{Schema: schema.Name, Name: table.Rel.Name}, + Name: structName(tableName, options), + Comment: table.Comment, + } + for _, column := range table.Columns { + s.Fields = append(s.Fields, Field{ + Name: fieldName(column.Name, options), + Type: perlType(req, options, column), + Comment: column.Comment, + }) + } + structs = append(structs, s) + } + } + if len(structs) > 0 { + sort.Slice(structs, func(i, j int) bool { return structs[i].Name < structs[j].Name }) + } + return structs +} + +func structName(name string, options *opts.Options) string { + return sdk.LowerTitle(name) +} + +func fieldName(name string, options *opts.Options) string { + return sdk.LowerTitle(name) +} + +func perlType(req *plugin.GenerateRequest, options *opts.Options, column *plugin.Column) string { + // TODO: implement + return "Str" +} diff --git a/internal/opts/options.go b/internal/opts/options.go index 8d79ec6..69dbe03 100644 --- a/internal/opts/options.go +++ b/internal/opts/options.go @@ -10,6 +10,7 @@ import ( ) type Options struct { + Package string `json:"package" yaml:"package"` OutputModelsFileName string `json:"output_models_file_name,omitempty" yaml:"output_models_file_name"` } diff --git a/internal/templates/template.tmpl b/internal/templates/template.tmpl index ba16836..e7fa055 100644 --- a/internal/templates/template.tmpl +++ b/internal/templates/template.tmpl @@ -2,16 +2,28 @@ # Code generated by sqlc. DO NOT EDIT. # versions: # sqlc: {{.SqlcVersion}} +# source: {{.SourceName}} -package Models; +package {{.Package}}; use strict; use warnings; +use Types::Standard -types; + {{template "modelsCode" .}} 1; {{end}} {{define "modelsCode"}} -Hello + +{{range .Structs}} +{{if .Comment}}{comment .Comment}{{end}} +use kote {{.Name}} => Dict[ {{- range .Fields}} + {{- if .Comment}}{{comment .Comment}}{{end}} + {{.Name}} => {{.Type}}, + {{- end}} +]; +{{end}} + {{end}}