Skip to content

Define code generation interface via Protocol Buffers #1406

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ sqlc-pg-gen:
start:
docker-compose up -d

fmt:
go fmt ./...

psql:
PGPASSWORD=mysecretpassword psql --host=127.0.0.1 --port=5432 --username=postgres dinotest

Expand Down
1 change: 1 addition & 0 deletions examples/authors/mysql/db_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build examples
// +build examples

package authors
Expand Down
1 change: 1 addition & 0 deletions examples/authors/postgresql/db_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build examples
// +build examples

package authors
Expand Down
1 change: 1 addition & 0 deletions examples/booktest/postgresql/db_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build examples
// +build examples

package booktest
Expand Down
1 change: 1 addition & 0 deletions examples/ondeck/mysql/db_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build examples
// +build examples

package ondeck
Expand Down
1 change: 1 addition & 0 deletions examples/ondeck/postgresql/db_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build examples
// +build examples

package ondeck
Expand Down
11 changes: 10 additions & 1 deletion internal/cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/kyleconroy/sqlc/internal/debug"
"github.com/kyleconroy/sqlc/internal/multierr"
"github.com/kyleconroy/sqlc/internal/opts"
"github.com/kyleconroy/sqlc/internal/plugin"
)

const errMessageNoVersion = `The configuration file must have a version number.
Expand Down Expand Up @@ -187,6 +188,7 @@ func Generate(ctx context.Context, e Env, dir, filename string, stderr io.Writer
region = trace.StartRegion(ctx, "codegen")
}
var files map[string]string
var resp *plugin.CodeGenResponse
var out string
switch {
case sql.Gen.Go != nil:
Expand All @@ -197,14 +199,21 @@ func Generate(ctx context.Context, e Env, dir, filename string, stderr io.Writer
files, err = kotlin.Generate(result, combo)
case sql.Gen.Python != nil:
out = combo.Python.Out
files, err = python.Generate(result, combo)
resp, err = python.Generate(codeGenRequest(result, combo))
default:
panic("missing language backend")
}
if region != nil {
region.End()
}

if resp != nil {
files = map[string]string{}
for _, file := range resp.Files {
files[file.Name] = string(file.Contents)
}
}

if err != nil {
fmt.Fprintf(stderr, "# package %s\n", name)
fmt.Fprintf(stderr, "error generating code: %s\n", err)
Expand Down
217 changes: 217 additions & 0 deletions internal/cmd/shim.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
package cmd

import (
"strings"

"github.com/kyleconroy/sqlc/internal/compiler"
"github.com/kyleconroy/sqlc/internal/config"
"github.com/kyleconroy/sqlc/internal/plugin"
"github.com/kyleconroy/sqlc/internal/sql/catalog"
)

func pluginOverride(o config.Override) *plugin.Override {
var column string
var table plugin.Identifier

if o.Column != "" {
colParts := strings.Split(o.Column, ".")
switch len(colParts) {
case 2:
table.Schema = "public"
table.Name = colParts[0]
column = colParts[1]
case 3:
table.Schema = colParts[0]
table.Name = colParts[1]
column = colParts[2]
case 4:
table.Catalog = colParts[0]
table.Schema = colParts[1]
table.Name = colParts[2]
column = colParts[3]
}
}
return &plugin.Override{
CodeType: "", // FIXME
DbType: o.DBType,
Nullable: o.Nullable,
Column: o.Column,
ColumnName: column,
Table: &table,
PythonType: pluginPythonType(o.PythonType),
}
}

func pluginSettings(cs config.CombinedSettings) *plugin.Settings {
var over []*plugin.Override
for _, o := range cs.Overrides {
over = append(over, pluginOverride(o))
}
return &plugin.Settings{
Version: cs.Global.Version,
Engine: string(cs.Package.Engine),
Schema: []string(cs.Package.Schema),
Queries: []string(cs.Package.Queries),
Overrides: over,
Rename: cs.Rename,
Python: pluginPythonCode(cs.Python),
}
}

func pluginPythonCode(s config.SQLPython) *plugin.PythonCode {
return &plugin.PythonCode{
Out: s.Out,
Package: s.Package,
EmitExactTableNames: s.EmitExactTableNames,
EmitSyncQuerier: s.EmitSyncQuerier,
EmitAsyncQuerier: s.EmitAsyncQuerier,
}
}

func pluginPythonType(pt config.PythonType) *plugin.PythonType {
return &plugin.PythonType{
Module: pt.Module,
Name: pt.Name,
}
}

func pluginCatalog(c *catalog.Catalog) *plugin.Catalog {
var schemas []*plugin.Schema
for _, s := range c.Schemas {
var enums []*plugin.Enum
for _, typ := range s.Types {
enum, ok := typ.(*catalog.Enum)
if !ok {
continue
}
enums = append(enums, &plugin.Enum{
Name: enum.Name,
Comment: enum.Comment,
Vals: enum.Vals,
})
}
var tables []*plugin.Table
for _, t := range s.Tables {
var columns []*plugin.Column
for _, c := range t.Columns {
l := -1
if c.Length != nil {
l = *c.Length
}
columns = append(columns, &plugin.Column{
Name: c.Name,
Type: &plugin.Identifier{
Catalog: c.Type.Catalog,
Schema: c.Type.Schema,
Name: c.Type.Name,
},
Comment: c.Comment,
NotNull: c.IsNotNull,
IsArray: c.IsArray,
Length: int32(l),
Table: &plugin.Identifier{
Catalog: t.Rel.Catalog,
Schema: t.Rel.Schema,
Name: t.Rel.Name,
},
})
}
tables = append(tables, &plugin.Table{
Rel: &plugin.Identifier{
Catalog: t.Rel.Catalog,
Schema: t.Rel.Schema,
Name: t.Rel.Name,
},
Columns: columns,
Comment: t.Comment,
})
}
schemas = append(schemas, &plugin.Schema{
Comment: s.Comment,
Name: s.Name,
Tables: tables,
Enums: enums,
})
}
return &plugin.Catalog{
Name: c.Name,
DefaultSchema: c.DefaultSchema,
Comment: c.Comment,
Schemas: schemas,
}
}

func pluginQueries(r *compiler.Result) []*plugin.Query {
var out []*plugin.Query
for _, q := range r.Queries {
var params []*plugin.Parameter
var columns []*plugin.Column
for _, c := range q.Columns {
columns = append(columns, pluginQueryColumn(c))
}
for _, p := range q.Params {
params = append(params, pluginQueryParam(p))
}
out = append(out, &plugin.Query{
Name: q.Name,
Cmd: q.Cmd,
Text: q.SQL,
Comments: q.Comments,
Columns: columns,
Params: params,
Filename: q.Filename,
})
}
return out
}

func pluginQueryColumn(c *compiler.Column) *plugin.Column {
l := -1
if c.Length != nil {
l = *c.Length
}
out := &plugin.Column{
Name: c.Name,
Comment: c.Comment,
NotNull: c.NotNull,
IsArray: c.IsArray,
Length: int32(l),
}

if c.Type != nil {
out.Type = &plugin.Identifier{
Catalog: c.Type.Catalog,
Schema: c.Type.Schema,
Name: c.Type.Name,
}
} else {
out.Type = &plugin.Identifier{
Name: c.DataType,
}
}

if c.Table != nil {
out.Table = &plugin.Identifier{
Catalog: c.Table.Catalog,
Schema: c.Table.Schema,
Name: c.Table.Name,
}
}

return out
}

func pluginQueryParam(p compiler.Parameter) *plugin.Parameter {
return &plugin.Parameter{
Number: int32(p.Number),
Column: pluginQueryColumn(p.Column),
}
}

func codeGenRequest(r *compiler.Result, settings config.CombinedSettings) *plugin.CodeGenRequest {
return &plugin.CodeGenRequest{
Settings: pluginSettings(settings),
Catalog: pluginCatalog(r.Catalog),
Queries: pluginQueries(r),
}
}
Loading