Skip to content

Commit 89bb36e

Browse files
authored
MySQL support (#1)
* initial commit of sql schema validation * adds barebones support for most basic use-case * improves parsing and generation of params * adds decent tests for mysql * improves param implementation - adds tests - adds support for named params - adds support for Limit expressions * adds support for decimal types * resolves some testing issues * generalizes imports * adds null type tests * improves go struct generation * adds command line call to mysql generate * improves support for insert queries and adds tests * improves support for enum types * refactors config to function param * patchs pkg settings arguments * simplifies and improves param parsing * param implementation and test patches * patch placeholder default table * properly handles "select * " expressions * initial commit of sql schema validation * adds barebones support for most basic use-case * improves parsing and generation of params * adds decent tests for mysql * improves param implementation - adds tests - adds support for named params - adds support for Limit expressions * adds support for decimal types * resolves some testing issues * generalizes imports * adds null type tests * improves go struct generation * adds command line call to mysql generate * improves support for insert queries and adds tests * improves support for enum types * refactors config to function param * patchs pkg settings arguments * simplifies and improves param parsing * param implementation and test patches * patch placeholder default table * properly handles "select * " expressions
1 parent 6a4dcec commit 89bb36e

File tree

17 files changed

+1876
-123
lines changed

17 files changed

+1876
-123
lines changed

go.mod

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,10 @@ require (
88
github.com/jinzhu/inflection v1.0.0
99
github.com/lfittl/pg_query_go v1.0.0
1010
github.com/spf13/cobra v0.0.5
11+
github.com/spf13/pflag v1.0.5 // indirect
12+
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect
13+
golang.org/x/sys v0.0.0-20191220220014-0732a990476f // indirect
14+
google.golang.org/genproto v0.0.0-20191223191004-3caeed10a8bf // indirect
15+
google.golang.org/grpc v1.26.0 // indirect
16+
vitess.io/vitess v0.0.0-20191113025808-0629f0da20ab
1117
)

go.sum

Lines changed: 289 additions & 0 deletions
Large diffs are not rendered by default.

internal/cmd/cmd.go

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"path/filepath"
1212

1313
"github.com/kyleconroy/sqlc/internal/dinosql"
14+
"github.com/kyleconroy/sqlc/internal/mysql"
1415

1516
"github.com/davecgh/go-spew/spew"
1617
pg "github.com/lfittl/pg_query_go"
@@ -21,6 +22,7 @@ import (
2122
func Do(args []string, stdin io.Reader, stdout io.Writer, stderr io.Writer) int {
2223
rootCmd := &cobra.Command{Use: "sqlc", SilenceUsage: true}
2324
rootCmd.AddCommand(checkCmd)
25+
rootCmd.AddCommand(unstable__mysql)
2426
rootCmd.AddCommand(genCmd)
2527
rootCmd.AddCommand(initCmd)
2628
rootCmd.AddCommand(parseCmd)
@@ -108,7 +110,7 @@ var genCmd = &cobra.Command{
108110
os.Exit(1)
109111
}
110112

111-
settings, err := dinosql.ParseConfig(bytes.NewReader(blob))
113+
settings, err := dinosql.ParseConfigFile(bytes.NewReader(blob))
112114
if err != nil {
113115
switch err {
114116
case dinosql.ErrMissingVersion:
@@ -153,7 +155,7 @@ var genCmd = &cobra.Command{
153155
continue
154156
}
155157

156-
q, err := dinosql.ParseQueries(c, settings, pkg)
158+
q, err := dinosql.ParseQueries(c, pkg)
157159
if err != nil {
158160
fmt.Fprintf(os.Stderr, "# package %s\n", name)
159161
if parserErr, ok := err.(*dinosql.ParserErr); ok {
@@ -167,7 +169,7 @@ var genCmd = &cobra.Command{
167169
continue
168170
}
169171

170-
files, err := dinosql.Generate(q, settings, pkg)
172+
files, err := dinosql.Generate(q, settings)
171173
if err != nil {
172174
fmt.Fprintf(os.Stderr, "# package %s\n", name)
173175
fmt.Fprintf(os.Stderr, "error generating code: %s\n", err)
@@ -214,10 +216,41 @@ var checkCmd = &cobra.Command{
214216
if err != nil {
215217
return err
216218
}
217-
if _, err := dinosql.ParseQueries(c, settings, pkg); err != nil {
219+
if _, err := dinosql.ParseQueries(c, pkg); err != nil {
218220
return err
219221
}
220222
}
221223
return nil
222224
},
223225
}
226+
227+
var unstable__mysql = &cobra.Command{
228+
Use: "unstable__mysql generate",
229+
Short: "Generate MySQL Queries into typesafe Go code",
230+
RunE: func(cmd *cobra.Command, args []string) error {
231+
blob, err := ioutil.ReadFile("sqlc.json")
232+
if err != nil {
233+
return err
234+
}
235+
236+
var settings dinosql.GenerateSettings
237+
if err := json.Unmarshal(blob, &settings); err != nil {
238+
return err
239+
}
240+
241+
for _, pkg := range settings.Packages {
242+
res, err := mysql.GeneratePkg(pkg.Name, pkg.Queries, settings)
243+
if err != nil {
244+
return err
245+
}
246+
for filename, source := range res {
247+
os.MkdirAll(filepath.Dir(filename), 0755)
248+
if err := ioutil.WriteFile(filename, []byte(source), 0644); err != nil {
249+
fmt.Fprintf(os.Stderr, "%s: %s\n", filename, err)
250+
os.Exit(1)
251+
}
252+
}
253+
}
254+
return nil
255+
},
256+
}

internal/dinosql/checks_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
func TestFuncs(t *testing.T) {
1313
_, err := ParseQueries(
1414
pg.NewCatalog(),
15-
GenerateSettings{},
1615
PackageSettings{
1716
Queries: filepath.Join("testdata", "funcs"),
1817
},

internal/dinosql/config.go

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,78 @@
11
package dinosql
22

33
import (
4+
"bytes"
45
"encoding/json"
56
"errors"
67
"fmt"
78
"io"
9+
"io/ioutil"
10+
"os"
11+
"path/filepath"
812
"strings"
913

1014
"github.com/kyleconroy/sqlc/internal/pg"
1115
)
1216

17+
const errMessageNoVersion = `The configuration file must have a version number.
18+
Set the version to 1 at the top of sqlc.json:
19+
20+
{
21+
"version": "1"
22+
...
23+
}
24+
`
25+
26+
const errMessageUnknownVersion = `The configuration file has an invalid version number.
27+
The only supported version is "1".
28+
`
29+
30+
const errMessageNoPackages = `No packages are configured`
31+
32+
// InitConfig initializes the global config objcet
33+
func InitConfig() (*GenerateSettings, error) {
34+
fmt.Println("Config init func ran")
35+
blob, err := ioutil.ReadFile("sqlc.json")
36+
if err != nil {
37+
fmt.Fprintln(os.Stderr, "error parsing sqlc.json: file does not exist")
38+
os.Exit(1)
39+
}
40+
41+
settings, err := ParseConfigFile(bytes.NewReader(blob))
42+
if err != nil {
43+
switch err {
44+
case ErrMissingVersion:
45+
fmt.Fprintf(os.Stderr, errMessageNoVersion)
46+
case ErrUnknownVersion:
47+
fmt.Fprintf(os.Stderr, errMessageUnknownVersion)
48+
case ErrNoPackages:
49+
fmt.Fprintf(os.Stderr, errMessageNoPackages)
50+
}
51+
fmt.Fprintf(os.Stderr, "error parsing sqlc.json: %s\n", err)
52+
os.Exit(1)
53+
}
54+
55+
for i, pkg := range settings.Packages {
56+
name := pkg.Name
57+
58+
if pkg.Path == "" {
59+
fmt.Fprintf(os.Stderr, "package[%d]: path must be set\n", i)
60+
continue
61+
}
62+
63+
if name == "" {
64+
name = filepath.Base(pkg.Path)
65+
}
66+
}
67+
return &settings, nil
68+
}
69+
1370
type GenerateSettings struct {
14-
Version string `json:"version"`
15-
Packages []PackageSettings `json:"packages"`
16-
Overrides []Override `json:"overrides,omitempty"`
17-
Rename map[string]string `json:"rename,omitempty"`
71+
Version string `json:"version"`
72+
Packages []PackageSettings `json:"packages"`
73+
Overrides []Override `json:"overrides,omitempty"`
74+
Rename map[string]string `json:"rename,omitempty"`
75+
PackageMap map[string]PackageSettings
1876
}
1977

2078
type PackageSettings struct {
@@ -97,7 +155,7 @@ var ErrMissingVersion = errors.New("no version number")
97155
var ErrUnknownVersion = errors.New("invalid version number")
98156
var ErrNoPackages = errors.New("no packages")
99157

100-
func ParseConfig(rd io.Reader) (GenerateSettings, error) {
158+
func ParseConfigFile(rd io.Reader) (GenerateSettings, error) {
101159
dec := json.NewDecoder(rd)
102160
dec.DisallowUnknownFields()
103161
var config GenerateSettings
@@ -125,5 +183,21 @@ func ParseConfig(rd io.Reader) (GenerateSettings, error) {
125183
}
126184
}
127185
}
128-
return config, nil
186+
err := config.PopulatePkgMap()
187+
188+
return config, err
189+
}
190+
191+
func (s *GenerateSettings) PopulatePkgMap() error {
192+
packageMap := make(map[string]PackageSettings)
193+
194+
for _, c := range s.Packages {
195+
if c.Name == "" {
196+
return errors.New("Package name must be specified in sqlc.json")
197+
}
198+
packageMap[c.Name] = c
199+
}
200+
s.PackageMap = packageMap
201+
202+
return nil
129203
}

internal/dinosql/config_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ func TestBadConfigs(t *testing.T) {
5151
} {
5252
tt := test
5353
t.Run(tt.name, func(t *testing.T) {
54-
_, err := ParseConfig(strings.NewReader(tt.json))
54+
_, err := ParseConfigFile(strings.NewReader(tt.json))
5555
if err == nil {
5656
t.Fatalf("expected err; got nil")
5757
}

0 commit comments

Comments
 (0)