pull/2/head
Brad Rydzewski 7 years ago
parent d0e92aab08
commit ad6a7de082

@ -1,22 +0,0 @@
package main
import (
"fmt"
"os"
"github.com/urfave/cli"
)
func main() {
app := cli.NewApp()
app.Name = "sqlbin"
app.Usage = "sqlbin provides command line tools for generating embedded sql opterations"
app.Commands = []cli.Command{
ddlCommand,
sqlCommand,
}
if err := app.Run(os.Args); err != nil {
fmt.Println(err)
os.Exit(1)
}
}

@ -6,13 +6,13 @@ import (
"github.com/urfave/cli"
"github.com/bradrydzewski/sqlbin/parse"
"github.com/bradrydzewski/sqlbin/parser"
"github.com/bradrydzewski/sqlbin/template"
)
type migration struct {
Name string
Statements []*parse.Statement
Statements []*parser.Statement
}
type logger struct {
@ -78,9 +78,9 @@ func ddlAction(c *cli.Context) error {
},
}
parser := parse.New()
parse := parser.New()
for _, match := range matches {
statements, perr := parser.ParseFile(match)
statements, perr := parse.ParseFile(match)
if perr != nil {
return perr
}

@ -6,14 +6,14 @@ import (
"github.com/urfave/cli"
"github.com/bradrydzewski/sqlbin/parse"
"github.com/bradrydzewski/sqlbin/parser"
"github.com/bradrydzewski/sqlbin/template"
)
type sqlParams struct {
Package string
Dialect string
Statements []*parse.Statement
Statements []*parser.Statement
}
var sqlCommand = cli.Command{
@ -56,9 +56,9 @@ func sqlAction(c *cli.Context) error {
Dialect: c.String("dialect"),
}
parser := parse.New()
parse := parser.New()
for _, match := range matches {
statements, perr := parser.ParseFile(match)
statements, perr := parse.ParseFile(match)
if perr != nil {
return perr
}

@ -1,20 +0,0 @@
package main
import (
"bytes"
"io"
"os"
"os/exec"
)
// format formats a template using gofmt.
func format(in io.Reader) (io.Reader, error) {
var out bytes.Buffer
gofmt := exec.Command("gofmt", "-s")
gofmt.Stdin = in
gofmt.Stdout = &out
gofmt.Stderr = os.Stderr
err := gofmt.Run()
return &out, err
}

@ -1,72 +1,23 @@
package main
import (
"bytes"
"flag"
"fmt"
"io"
"io/ioutil"
"os"
"path/filepath"
)
var (
input = flag.String("input", "", "input file name; required")
output = flag.String("o", "", "output file name; required")
pkgname = flag.String("pkg", "main", "output package name; required")
"github.com/urfave/cli"
)
func main() {
flag.Parse()
files, err := filepath.Glob(*input)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
var buf bytes.Buffer
for _, file := range files {
out, ferr := ioutil.ReadFile(file)
if ferr != nil {
fmt.Println(ferr)
os.Exit(1)
}
buf.Write(out)
}
// parses the sql statements from the file.
stmts, err := parse(&buf)
if err != nil {
fmt.Println(err)
os.Exit(1)
app := cli.NewApp()
app.Name = "sqlbin"
app.Usage = "sqlbin provides command line tools for generating embedded sql opterations"
app.Version = "1.0.0-alpha"
app.Commands = []cli.Command{
ddlCommand,
sqlCommand,
}
buf.Reset()
err = generate(&buf, *pkgname, stmts)
if err != nil {
if err := app.Run(os.Args); err != nil {
fmt.Println(err)
os.Exit(1)
}
// formats the generated file using gofmt
pretty, err := format(&buf)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return
}
// create output source for file. defaults to
// stdout but may be file.
var out = os.Stdout
if *output != "" {
out, err = os.Create(*output)
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
return
}
defer out.Close()
}
io.Copy(out, pretty)
}

@ -1,54 +0,0 @@
package main
import (
"bufio"
"fmt"
"io"
"strings"
)
const (
prefix = "-- +statement "
comment = "--"
newline = "\n"
)
type statement struct {
Name string
Value string
Driver string
}
func parse(r io.Reader) ([]*statement, error) {
var (
stmts []*statement
stmt *statement
)
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := scanner.Text()
if strings.HasPrefix(line, prefix) {
stmt = new(statement)
stmt.Name, stmt.Driver = parsePrefix(line)
stmts = append(stmts, stmt)
}
if strings.HasPrefix(line, comment) {
continue
}
if stmt != nil {
stmt.Value += line + newline
}
}
for _, stmt := range stmts {
stmt.Value = strings.TrimSpace(stmt.Value)
}
return stmts, nil
}
func parsePrefix(line string) (name string, driver string) {
line = strings.TrimPrefix(line, prefix)
line = strings.TrimSpace(line)
fmt.Sscanln(line, &name, &driver)
return
}

@ -1 +0,0 @@
package parse

@ -1,48 +0,0 @@
package main
import (
"encoding/json"
"os"
"strings"
"testing"
)
func TestParse(t *testing.T) {
stmts, err := parse(strings.NewReader(example))
if err != nil {
t.Error(err)
}
enc := json.NewEncoder(os.Stderr)
enc.SetIndent("", " ")
enc.SetEscapeHTML(false)
enc.Encode(stmts)
}
var example = `
--
-- +statement select-pets
--
select *
from pets
{{ if .Type }}
WHERE type = ?
{{ else if .MaxPrice }}
WHERE price <= ?
{{ end }}
-- +statement select-pets-by-id
select *
from pets
where id = ?
-- +statement select-pets-by-type postgres
select *
from pets
where type = $1
`

@ -1,4 +1,4 @@
package parse
package parser
import (
"bufio"

@ -0,0 +1 @@
package parser

@ -5,7 +5,8 @@ func Lookup(name string) string {
return index[name]
}
var index = map[string]string{"user-select-all": userSelectAll,
var index = map[string]string{
"user-select-all": userSelectAll,
"user-select-username": userSelectUsername,
}

@ -6,7 +6,7 @@ func Lookup(name string) string {
}
var index = map[string]string{
{{- range .Statements -}}
{{ range .Statements -}}
{{ printf "%q" .Name }}: {{ camelize .Name }},
{{ end -}}
}

@ -89,7 +89,7 @@ func filesDdlTmpl() (*asset, error) {
return a, nil
}
var _filesSqlTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x50\xcd\x4a\x03\x31\x10\x3e\x9b\xa7\xf8\x28\x08\x0a\x36\xbd\x0b\xbe\x81\x88\x20\x78\x29\x05\x87\xdd\x69\x5d\xba\x3b\x1b\xb3\x89\x88\x21\xef\xee\x24\x59\xbd\xd8\xd3\xfc\x7c\x3f\xf3\x25\x8e\xba\x33\x9d\x18\x29\xc1\x3e\xaf\x7d\xce\xc6\xec\x76\x78\x9c\xe7\x73\x74\xf0\x1c\xa2\x97\x05\xe1\x9d\x21\x34\x71\x8f\x25\x50\xe0\x89\x25\x58\x73\x8c\xd2\xad\xc4\x9b\x02\x2a\xe6\x07\x39\xdd\xae\x15\xc9\x5c\x35\x3d\x06\xe9\xf9\x6b\x5f\x38\x07\xa3\xfe\x9f\xe4\xdb\x0a\x0f\x98\xc8\xed\x1b\xff\xd0\x8a\xaa\x52\xda\xc2\x93\x68\x1a\xfb\xf2\x7b\x6e\xc1\x56\xa3\x29\x04\xa7\xac\x70\xc4\xe6\xfa\x63\x03\xfb\x54\xee\xe6\x7c\x5f\xde\xd0\x69\x3f\x0e\xdf\xfc\xb7\xbd\xab\x7c\x96\xbe\x6a\xf5\xb0\x4e\xff\x7d\x15\x2a\x81\x2e\x19\x68\xbe\xb7\x22\xb2\xaf\x34\xc6\xfa\x37\x75\x2c\x8e\xda\xff\x04\x00\x00\xff\xff\x92\xf4\x54\xbf\x3f\x01\x00\x00")
var _filesSqlTmpl = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\x6c\x50\xcd\x4a\xc7\x30\x0c\x3f\xdb\xa7\x08\x7f\x10\x14\xb4\xbb\x0b\xbe\x81\x88\x20\x78\x19\x03\xc3\x96\xcd\xb1\x2d\xab\x5d\x2b\xe2\xe8\xbb\x9b\xb4\xd3\xd3\x4e\xc9\xf2\xfb\x5c\x1d\xb6\x13\x0e\x04\xfb\x0e\xf6\xe5\xd8\x53\x32\xa6\xaa\xe0\x69\x5d\xa7\xe8\xc0\x53\x88\x9e\x37\x08\x1f\x04\x8c\x0b\x75\xb0\x05\x0c\xb4\x10\x07\x6b\xfa\xc8\xed\x41\xbc\x51\x50\x30\x3f\xf2\x70\x7b\x4c\xd8\xcd\x55\xd1\xc3\xc8\x1d\x7d\xd7\xca\x69\x8c\xf8\x7f\xa1\x2f\x27\x78\x84\x05\x5d\x5d\xf8\x4d\x19\xa2\x92\x3e\x1e\x59\xca\xd8\xd7\xbf\xb4\x0d\xee\xa5\x99\x22\x4e\x48\xa1\x87\xcb\xf5\xe7\x05\xec\xb3\xc6\xa6\xf4\xa0\xbf\xd0\xca\x3e\x8f\x3f\xf4\x7f\xbd\xcb\x7c\xe2\x2e\x6b\x25\xf7\xd4\x57\x20\xed\x73\x66\x20\xf5\xde\x55\x64\xdf\x70\x8e\xf9\x69\xf2\xa7\x3a\xca\xfe\x1b\x00\x00\xff\xff\xa2\x6f\x57\x8d\x3e\x01\x00\x00")
func filesSqlTmplBytes() ([]byte, error) {
return bindataRead(
@ -104,7 +104,7 @@ func filesSqlTmpl() (*asset, error) {
return nil, err
}
info := bindataFileInfo{name: "files/sql.tmpl", size: 319, mode: os.FileMode(420), modTime: time.Unix(1490514861, 0)}
info := bindataFileInfo{name: "files/sql.tmpl", size: 318, mode: os.FileMode(420), modTime: time.Unix(1490544026, 0)}
a := &asset{bytes: bytes, info: info}
return a, nil
}

@ -1,197 +0,0 @@
package main
import (
"io"
"strings"
"text/template"
)
var funcs = map[string]interface{}{
"join": func(a, b string) string {
if b == "" {
return a
}
return strings.Join([]string{a, b}, "-")
},
"camelize": camelize,
}
type data struct {
Package string
Labels []string
Statements []*statement
}
func generate(w io.Writer, pkg string, stmts []*statement) error {
t, err := template.New("_").Funcs(funcs).Parse(text)
if err != nil {
panic(err)
}
set := map[string]string{}
for _, stmt := range stmts {
if stmt.Driver != "" {
set[stmt.Driver] = stmt.Driver
}
}
var labels []string
for k := range set {
labels = append(labels, k)
}
return t.Execute(w, data{
Package: pkg,
Labels: labels,
Statements: stmts,
})
}
var text = `
package {{ .Package }}
// THIS FILE WAS AUTO-GENERATED. DO NOT MODIFY.
// Lookup returns the named statement.
func Lookup(name string) (string) {
return index[name]
}
{{ if .Labels }}
// LookupTag returns the named statement by tag.
func LookupTag(name, tag string) (string) {
switch tag {
{{- range .Labels }}
case {{ printf "%q" . }}:
return {{ . }}Index[name]
{{- end }}
default:
return index[name]
}
}
{{ end }}
var index = map[string]string{
{{- range $i, $stmt := .Statements -}}
{{- if not .Driver }}
{{- $name := join .Name .Driver }}
{{ printf "%q" $stmt.Name }}: {{ camelize $name }},
{{- end -}}
{{ end }}
}
{{ $statements := .Statements }}
{{ range $ii, $label := .Labels }}
var {{ $label }}Index = map[string]string{
{{- range $i, $stmt := $statements -}}
{{- if eq $label $stmt.Driver }}
{{- $name := join .Name .Driver }}
{{ printf "%q" $stmt.Name }}: {{ camelize $name }},
{{ end -}}
{{- end -}}
}
{{ end }}
{{ range .Statements -}}
{{ $name := join .Name .Driver }}
var {{ camelize $name }} = ` + "`" + "\n{{.Value }}\n" + "`" + `
{{ end }}
`
func camelize(kebab string) (camelCase string) {
isToUpper := false
for _, runeValue := range kebab {
if isToUpper {
camelCase += strings.ToUpper(string(runeValue))
isToUpper = false
} else {
if runeValue == '-' {
isToUpper = true
} else {
camelCase += string(runeValue)
}
}
}
return
}
// old version of template
var textBackup = `
package {{ .Package }}
import "text/template"
type statement struct {
name string
value string
templ *template.Template
}
func init() {
for _, s := range statements {
s.templ = template.Must(
template.New(s.name).Parse(s.value),
)
}
}
// Lookup returns the named statement.
func Lookup(name string) (s string) {
stmt, ok := index[name]
if ok {
return stmt.value
}
return
}
// LookupTag returns the named statement by tag.
func LookupTag(name, tag string) (s string) {
switch tag {
{{- range .Labels }}
case {{ printf "%q" . }}:
stmt, ok := {{ . }}Index[name]
if ok {
return stmt.value
}
{{- end }}
default:
// no-op
}
// fallback to default statement
return Lookup(name)
}
var statements = []*statement{
{{ range .Statements -}}
{{ $name := join .Name .Driver -}}
{
name: {{ printf "%q" .Name }},
value: {{ camelize $name }},
},
{{ end }}
}
var index = map[string]*statement{
{{- range $i, $stmt := .Statements -}}
{{- if not .Driver }}
{{ printf "%q" $stmt.Name }}: statements[{{$i}}],
{{- end -}}
{{ end }}
}
{{ $statements := .Statements }}
{{ range $ii, $label := .Labels }}
var {{ $label }}Index = map[string]*statement{
{{- range $i, $stmt := $statements -}}
{{- if eq $label $stmt.Driver }}
{{ printf "%q" $stmt.Name }}: statements[{{$i}}],
{{ end -}}
{{- end -}}
}
{{ end }}
{{ range .Statements -}}
{{ $name := join .Name .Driver }}
var {{ camelize $name }} = ` + "`" + "\n{{.Value }}\n" + "`" + `
{{ end }}
`
Loading…
Cancel
Save