Skip to content
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
113 changes: 5 additions & 108 deletions internal/cmd/cmd.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cmd

import (
"bytes"
"encoding/json"
"fmt"
"io"
Expand All @@ -11,7 +10,6 @@ import (
"path/filepath"

"github.com/kyleconroy/sqlc/internal/dinosql"
"github.com/kyleconroy/sqlc/internal/mysql"

"github.com/davecgh/go-spew/spew"
pg "github.com/lfittl/pg_query_go"
Expand Down Expand Up @@ -84,127 +82,26 @@ var initCmd = &cobra.Command{
},
}

const errMessageNoVersion = `The configuration file must have a version number.
Set the version to 1 at the top of sqlc.json:

{
"version": "1"
...
}
`

const errMessageUnknownVersion = `The configuration file has an invalid version number.
The only supported version is "1".
`

const errMessageNoPackages = `No packages are configured`

var genCmd = &cobra.Command{
Use: "generate",
Short: "Generate Go code from SQL",
Run: func(cmd *cobra.Command, args []string) {
blob, err := ioutil.ReadFile("sqlc.json")
stderr := cmd.ErrOrStderr()
dir, err := os.Getwd()
if err != nil {
fmt.Fprintln(os.Stderr, "error parsing sqlc.json: file does not exist")
fmt.Fprintln(stderr, "error parsing sqlc.json: file does not exist")
os.Exit(1)
}

settings, err := dinosql.ParseConfig(bytes.NewReader(blob))
output, err := Generate(dir, stderr)
if err != nil {
switch err {
case dinosql.ErrMissingVersion:
fmt.Fprintf(os.Stderr, errMessageNoVersion)
case dinosql.ErrUnknownVersion:
fmt.Fprintf(os.Stderr, errMessageUnknownVersion)
case dinosql.ErrNoPackages:
fmt.Fprintf(os.Stderr, errMessageNoPackages)
}
fmt.Fprintf(os.Stderr, "error parsing sqlc.json: %s\n", err)
os.Exit(1)
}

var errored bool

output := map[string]string{}

for _, pkg := range settings.Packages {
name := pkg.Name
combo := dinosql.Combine(settings, pkg)
var result dinosql.Generateable

switch pkg.Engine {

case dinosql.EngineMySQL:
// Experimental MySQL support
q, err := mysql.GeneratePkg(name, pkg.Schema, pkg.Queries, combo)
if err != nil {
fmt.Fprintf(os.Stderr, "# package %s\n", name)
if parserErr, ok := err.(*dinosql.ParserErr); ok {
for _, fileErr := range parserErr.Errs {
fmt.Fprintf(os.Stderr, "%s:%d:%d: %s\n", fileErr.Filename, fileErr.Line, fileErr.Column, fileErr.Err)
}
} else {
fmt.Fprintf(os.Stderr, "error parsing schema: %s\n", err)
}
errored = true
continue
}
result = q

case dinosql.EnginePostgreSQL:
c, err := dinosql.ParseCatalog(pkg.Schema)
if err != nil {
fmt.Fprintf(os.Stderr, "# package %s\n", name)
if parserErr, ok := err.(*dinosql.ParserErr); ok {
for _, fileErr := range parserErr.Errs {
fmt.Fprintf(os.Stderr, "%s:%d:%d: %s\n", fileErr.Filename, fileErr.Line, fileErr.Column, fileErr.Err)
}
} else {
fmt.Fprintf(os.Stderr, "error parsing schema: %s\n", err)
}
errored = true
continue
}

q, err := dinosql.ParseQueries(c, pkg)
if err != nil {
fmt.Fprintf(os.Stderr, "# package %s\n", name)
if parserErr, ok := err.(*dinosql.ParserErr); ok {
for _, fileErr := range parserErr.Errs {
fmt.Fprintf(os.Stderr, "%s:%d:%d: %s\n", fileErr.Filename, fileErr.Line, fileErr.Column, fileErr.Err)
}
} else {
fmt.Fprintf(os.Stderr, "error parsing queries: %s\n", err)
}
errored = true
continue
}
result = q

}

files, err := dinosql.Generate(result, combo)
if err != nil {
fmt.Fprintf(os.Stderr, "# package %s\n", name)
fmt.Fprintf(os.Stderr, "error generating code: %s\n", err)
errored = true
continue
}

for n, source := range files {
filename := filepath.Join(pkg.Path, n)
output[filename] = source
}
}

if errored {
os.Exit(1)
}

for filename, source := range output {
os.MkdirAll(filepath.Dir(filename), 0755)
if err := ioutil.WriteFile(filename, []byte(source), 0644); err != nil {
fmt.Fprintf(os.Stderr, "%s: %s\n", filename, err)
fmt.Fprintf(stderr, "%s: %s\n", filename, err)
os.Exit(1)
}
}
Expand Down
131 changes: 131 additions & 0 deletions internal/cmd/generate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package cmd

import (
"bytes"
"fmt"
"io"
"io/ioutil"
"path/filepath"

"github.com/kyleconroy/sqlc/internal/dinosql"
"github.com/kyleconroy/sqlc/internal/mysql"
)

const errMessageNoVersion = `The configuration file must have a version number.
Set the version to 1 at the top of sqlc.json:

{
"version": "1"
...
}
`

const errMessageUnknownVersion = `The configuration file has an invalid version number.
The only supported version is "1".
`

const errMessageNoPackages = `No packages are configured`

func Generate(dir string, stderr io.Writer) (map[string]string, error) {
blob, err := ioutil.ReadFile(filepath.Join(dir, "sqlc.json"))
if err != nil {
fmt.Fprintln(stderr, "error parsing sqlc.json: file does not exist")
return nil, err
}

settings, err := dinosql.ParseConfig(bytes.NewReader(blob))
if err != nil {
switch err {
case dinosql.ErrMissingVersion:
fmt.Fprintf(stderr, errMessageNoVersion)
case dinosql.ErrUnknownVersion:
fmt.Fprintf(stderr, errMessageUnknownVersion)
case dinosql.ErrNoPackages:
fmt.Fprintf(stderr, errMessageNoPackages)
}
fmt.Fprintf(stderr, "error parsing sqlc.json: %s\n", err)
return nil, err
}

output := map[string]string{}
errored := false

for _, pkg := range settings.Packages {
name := pkg.Name
combo := dinosql.Combine(settings, pkg)
var result dinosql.Generateable

// TODO: This feels like a hack that will bite us later
pkg.Schema = filepath.Join(dir, pkg.Schema)
pkg.Queries = filepath.Join(dir, pkg.Queries)

switch pkg.Engine {

case dinosql.EngineMySQL:
// Experimental MySQL support
q, err := mysql.GeneratePkg(name, pkg.Schema, pkg.Queries, combo)
if err != nil {
fmt.Fprintf(stderr, "# package %s\n", name)
if parserErr, ok := err.(*dinosql.ParserErr); ok {
for _, fileErr := range parserErr.Errs {
fmt.Fprintf(stderr, "%s:%d:%d: %s\n", fileErr.Filename, fileErr.Line, fileErr.Column, fileErr.Err)
}
} else {
fmt.Fprintf(stderr, "error parsing schema: %s\n", err)
}
errored = true
continue
}
result = q

case dinosql.EnginePostgreSQL:
c, err := dinosql.ParseCatalog(pkg.Schema)
if err != nil {
fmt.Fprintf(stderr, "# package %s\n", name)
if parserErr, ok := err.(*dinosql.ParserErr); ok {
for _, fileErr := range parserErr.Errs {
fmt.Fprintf(stderr, "%s:%d:%d: %s\n", fileErr.Filename, fileErr.Line, fileErr.Column, fileErr.Err)
}
} else {
fmt.Fprintf(stderr, "error parsing schema: %s\n", err)
}
errored = true
continue
}

q, err := dinosql.ParseQueries(c, pkg)
if err != nil {
fmt.Fprintf(stderr, "# package %s\n", name)
if parserErr, ok := err.(*dinosql.ParserErr); ok {
for _, fileErr := range parserErr.Errs {
fmt.Fprintf(stderr, "%s:%d:%d: %s\n", fileErr.Filename, fileErr.Line, fileErr.Column, fileErr.Err)
}
} else {
fmt.Fprintf(stderr, "error parsing queries: %s\n", err)
}
errored = true
continue
}
result = q

}

files, err := dinosql.Generate(result, combo)
if err != nil {
fmt.Fprintf(stderr, "# package %s\n", name)
fmt.Fprintf(stderr, "error generating code: %s\n", err)
errored = true
continue
}

for n, source := range files {
filename := filepath.Join(dir, pkg.Path, n)
output[filename] = source
}
}

if errored {
return nil, fmt.Errorf("errored")
}
return output, nil
}
Loading