Skip to content

Commit

Permalink
new data layout, plus params in config (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
natefinch committed Sep 18, 2017
1 parent 72b134d commit c06a4fb
Show file tree
Hide file tree
Showing 28 changed files with 737 additions and 439 deletions.
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -7,6 +7,8 @@ Of course, contributions are more than welcome. Please read these guidelines for
Development discussion should take place on the #gnorm channel of [gopher
slack](https://gophers.slack.com/).

There is a separate #gnorm-dev channel that has the github app to post github activity to the channel, to make it easy to follow.

## Tasks

See the [Nearterm Todos](https://github.com/gnormal/gnorm/projects/1) github
Expand Down
6 changes: 6 additions & 0 deletions cli/config.go
Expand Up @@ -97,4 +97,10 @@ type Config struct {
// TypeMap and NullableTypeMap must be at the end of your configuration
// file.
NullableTypeMap map[string]string

// Params contains any data you may want to pass to your templates. This is
// a good way to make templates reusable with different configuration values
// for different situations. The values in this field will be available in
// the .Params value for all templates.
Params map[string]interface{}
}
19 changes: 19 additions & 0 deletions cli/config_test.go
@@ -0,0 +1,19 @@
package cli

import (
"testing"

"github.com/BurntSushi/toml"
)

func TestExampleToml(t *testing.T) {
c := Config{}
m, err := toml.DecodeFile("gnorm.toml", &c)
if err != nil {
t.Fatal("error parsing config file", err)
}
undec := m.Undecoded()
if len(undec) > 0 {
t.Fatal("Warning: unknown values present in config file:", undec)
}
}
21 changes: 14 additions & 7 deletions cli/gnorm.toml
@@ -1,23 +1,22 @@
# ConnStr is the connection string for the database.
# Postgres example:
# ConnStr = "dbname=mydb host=127.0.0.1 sslmode=disable user=admin"
# MySQL example:
# ConnStr = "root:admin@tcp/"
ConnStr = ""
# Postgres example:
ConnStr = "dbname=mydb host=127.0.0.1 sslmode=disable user=admin"

# DBType holds the type of db you're connecting to. Possible values are
# "postgres" or "mysql".
DBType = ""
DBType = "postgres"

# Schemas holds the names of schemas to generate code for.
Schemas = []
Schemas = ["public"]

# NameConversion defines how the DBName of tables, schemas, and enums are
# converted into their Name value. This is a template that may use all the
# regular functions. The "." value is the DB name of the item. Thus, to make an
# item's Name the same as its DBName, you'd use a template of "{{.}}". To make
# the Name the PascalCase version, you'd use "{{pascal .}}".
NameConversion = ""
NameConversion = "{{.}}"

# IncludeTables is a whitelist of tables to generate data for. Tables not
# in this list will not be included in data geenrated by gnorm. You cannot
Expand Down Expand Up @@ -118,4 +117,12 @@ PostRun = []
# "character varying" = "sql.NullString"
# "integer" = "sql.NullInt64"
# "numeric" = "sql.NullFloat64"
[NullableTypeMap]
[NullableTypeMap]


# Params contains any data you may want to pass to your templates. This is a
# good way to make templates reusable with different configuration values for
# different situations. The values in this field will be available in the
# .Params value for all templates.
[Params]
# mySpecalValue = "some value"
16 changes: 9 additions & 7 deletions cli/parse.go
Expand Up @@ -16,6 +16,7 @@ import (
"gnorm.org/gnorm/database/drivers/postgres"
"gnorm.org/gnorm/environ"
"gnorm.org/gnorm/run"
"gnorm.org/gnorm/run/data"
)

func parseFile(env environ.Values, file string) (*run.Config, error) {
Expand Down Expand Up @@ -61,13 +62,14 @@ func parse(env environ.Values, r io.Reader) (*run.Config, error) {
}

cfg := &run.Config{
ConnStr: c.ConnStr,
Schemas: c.Schemas,
NullableTypeMap: c.NullableTypeMap,
TypeMap: c.TypeMap,
PostRun: c.PostRun,
ExcludeTables: exclude,
IncludeTables: include,
ConfigData: data.ConfigData{
Schemas: c.Schemas,
NullableTypeMap: c.NullableTypeMap,
TypeMap: c.TypeMap,
PostRun: c.PostRun,
ExcludeTables: exclude,
IncludeTables: include,
},
}
d, err := getDriver(strings.ToLower(c.DBType))
if err != nil {
Expand Down
18 changes: 17 additions & 1 deletion cli/parse_test.go
@@ -1,6 +1,10 @@
package cli

import "testing"
import (
"testing"

"github.com/BurntSushi/toml"
)

func TestParseTables(t *testing.T) {
tables := []string{"table", "schema.table2"}
Expand Down Expand Up @@ -35,6 +39,18 @@ func TestParseTables(t *testing.T) {
}
}

func TestParseGnormTolm(t *testing.T) {
c := Config{}
m, err := toml.DecodeFile("gnorm.toml", &c)
if err != nil {
t.Fatal(err)
}
undec := m.Undecoded()
if len(undec) > 0 {
t.Fatalf("unknown values present in config file: %s", undec)
}
}

func contains(list []string, s string) bool {
for x := range list {
if list[x] == s {
Expand Down
21 changes: 14 additions & 7 deletions cli/sample.go
Expand Up @@ -25,25 +25,24 @@ package cli
// }
// gocog]]]
const sample = `# ConnStr is the connection string for the database.
# Postgres example:
# ConnStr = "dbname=mydb host=127.0.0.1 sslmode=disable user=admin"
# MySQL example:
# ConnStr = "root:admin@tcp/"
ConnStr = ""
# Postgres example:
ConnStr = "dbname=mydb host=127.0.0.1 sslmode=disable user=admin"
# DBType holds the type of db you're connecting to. Possible values are
# "postgres" or "mysql".
DBType = ""
DBType = "postgres"
# Schemas holds the names of schemas to generate code for.
Schemas = []
Schemas = ["public"]
# NameConversion defines how the DBName of tables, schemas, and enums are
# converted into their Name value. This is a template that may use all the
# regular functions. The "." value is the DB name of the item. Thus, to make an
# item's Name the same as its DBName, you'd use a template of "{{.}}". To make
# the Name the PascalCase version, you'd use "{{pascal .}}".
NameConversion = ""
NameConversion = "{{.}}"
# IncludeTables is a whitelist of tables to generate data for. Tables not
# in this list will not be included in data geenrated by gnorm. You cannot
Expand Down Expand Up @@ -144,5 +143,13 @@ PostRun = []
# "character varying" = "sql.NullString"
# "integer" = "sql.NullInt64"
# "numeric" = "sql.NullFloat64"
[NullableTypeMap]`
[NullableTypeMap]
# Params contains any data you may want to pass to your templates. This is a
# good way to make templates reusable with different configuration values for
# different situations. The values in this field will be available in the
# .Params value for all templates.
[Params]
# mySpecalValue = "some value"`
// [[[end]]]
23 changes: 11 additions & 12 deletions database/drivers/mysql/parse.go
Expand Up @@ -36,9 +36,9 @@ func parse(log *log.Logger, conn string, schemaNames []string, filterTables func
return nil, err
}

schemas := make(map[string]map[string]database.Columns, len(schemaNames))
schemas := make(map[string]map[string][]*database.Column, len(schemaNames))
for _, name := range schemaNames {
schemas[name] = map[string]database.Columns{}
schemas[name] = map[string][]*database.Column{}
}

for _, t := range tables {
Expand Down Expand Up @@ -80,21 +80,20 @@ func parse(log *log.Logger, conn string, schemaNames []string, filterTables func
}
schema[c.TableName] = append(schema[c.TableName], col)
if enum != nil {
enum.DBTable = c.TableName
enum.DBSchema = c.TableSchema
enums[enum.DBSchema] = append(enums[enum.DBSchema], enum)
enum.Table = c.TableName
enums[c.TableSchema] = append(enums[c.TableSchema], enum)
}
}

res := &database.Info{Schemas: make([]*database.Schema, 0, len(schemas))}
for _, schema := range schemaNames {
tables := schemas[schema]
s := &database.Schema{
DBName: schema,
Enums: enums[schema],
Name: schema,
Enums: enums[schema],
}
for tname, columns := range tables {
s.Tables = append(s.Tables, &database.Table{DBName: tname, DBSchema: schema, Columns: columns})
s.Tables = append(s.Tables, &database.Table{Name: tname, Columns: columns})
}
res.Schemas = append(res.Schemas, s)
}
Expand All @@ -104,10 +103,10 @@ func parse(log *log.Logger, conn string, schemaNames []string, filterTables func

func toDBColumn(c *columns.Row, log *log.Logger) (*database.Column, *database.Enum, error) {
col := &database.Column{
DBName: c.ColumnName,
Name: c.ColumnName,
Nullable: c.IsNullable == "YES",
HasDefault: c.ColumnDefault.String != "",
DBType: c.DataType,
Type: c.DataType,
Orig: *c,
}

Expand All @@ -132,7 +131,7 @@ func toDBColumn(c *columns.Row, log *log.Logger) (*database.Column, *database.En
// we'll call the enum the same as the column name.
// the function above will set the table name etc
enum := &database.Enum{
DBName: col.DBName,
Name: col.Name,
}
// strip off the enum and parens
s := c.ColumnType[5 : len(c.ColumnType)-1]
Expand All @@ -141,7 +140,7 @@ func toDBColumn(c *columns.Row, log *log.Logger) (*database.Column, *database.En
for x := range vals {
enum.Values[x] = &database.EnumValue{
// strip off the quotes
DBName: vals[x][1 : len(vals[x])-1],
Name: vals[x][1 : len(vals[x])-1],
// enum values start at 1 in mysql
Value: x + 1,
}
Expand Down
4 changes: 1 addition & 3 deletions database/drivers/mysql/templates/schema.gotmpl
Expand Up @@ -75,6 +75,4 @@ func (f {{$fieldName}}Field) In(vals []{{.}}) WhereClause {
}




{{end}}
{{end}}
3 changes: 2 additions & 1 deletion database/drivers/mysql/templates/table.gotmpl
@@ -1,5 +1,5 @@
// Code generated by gnorm, DO NOT EDIT!

{{with .Table}}
package {{toLower .Name}}

import "gnorm.org/gnorm/database/drivers/mysql/gnorm"
Expand Down Expand Up @@ -52,3 +52,4 @@ func Query(db gnorm.DB, where gnorm.WhereClause) ([]*Row, error) {
return vals, nil
}

{{end}}
12 changes: 6 additions & 6 deletions database/drivers/postgres/columns_test.go
Expand Up @@ -192,8 +192,8 @@ func TestUserDefined(t *testing.T) {
if !col.UserDefined {
t.Error("user defined enum not marked as UserDefined")
}
if col.DBType != BookTypeCol.UdtName.String {
t.Errorf("Expected column to have UdtName %q as DBType, but instead got %s", BookTypeCol.UdtName.String, col.DBType)
if col.Type != BookTypeCol.UdtName.String {
t.Errorf("Expected column to have UdtName %q as Type, but instead got %s", BookTypeCol.UdtName.String, col.Type)
}
}

Expand Down Expand Up @@ -248,14 +248,14 @@ func TestHasDefault(t *testing.T) {

func TestDBType(t *testing.T) {
col := toDBColumn(SummaryCol, tLog(t))
if col.DBType != SummaryCol.DataType.String {
t.Errorf("Column should have name %q but is %q.", SummaryCol.DataType.String, col.DBType)
if col.Type != SummaryCol.DataType.String {
t.Errorf("Column should have name %q but is %q.", SummaryCol.DataType.String, col.Type)
}

// User-defined columns are different, their data type is USER-DEFINED which
// is less than useful, so we copy the UdtName into the column Type.
col = toDBColumn(BookTypeCol, tLog(t))
if col.DBType != BookTypeCol.UdtName.String {
t.Errorf("Expected column to have UdtName %q as DBType, but instead got %s", BookTypeCol.UdtName.String, col.DBType)
if col.Type != BookTypeCol.UdtName.String {
t.Errorf("Expected column to have UdtName %q as Type, but instead got %s", BookTypeCol.UdtName.String, col.Type)
}
}
17 changes: 8 additions & 9 deletions database/drivers/postgres/parse.go
Expand Up @@ -97,11 +97,11 @@ func parse(log *log.Logger, conn string, schemaNames []string, filterTables func
for _, schema := range schemaNames {
tables := schemas[schema]
s := &database.Schema{
DBName: schema,
Enums: enums[schema],
Name: schema,
Enums: enums[schema],
}
for tname, columns := range tables {
s.Tables = append(s.Tables, &database.Table{DBName: tname, DBSchema: schema, Columns: columns})
s.Tables = append(s.Tables, &database.Table{Name: tname, Columns: columns})
}
res.Schemas = append(res.Schemas, s)
}
Expand All @@ -111,7 +111,7 @@ func parse(log *log.Logger, conn string, schemaNames []string, filterTables func

func toDBColumn(c *columns.Row, log *log.Logger) *database.Column {
col := &database.Column{
DBName: c.ColumnName.String,
Name: c.ColumnName.String,
Nullable: c.IsNullable.String == "YES",
HasDefault: c.ColumnDefault.String != "",
Length: int(c.CharacterMaximumLength.Int64),
Expand All @@ -131,7 +131,7 @@ func toDBColumn(c *columns.Row, log *log.Logger) *database.Column {
typ = c.UdtName.String
}

col.DBType = typ
col.Type = typ

return col
}
Expand Down Expand Up @@ -168,9 +168,8 @@ func queryEnums(log *log.Logger, db *sql.DB, schemas []string) (map[string][]*da
return nil, err
}
enum := &database.Enum{
DBName: name,
DBSchema: schema,
Values: vals,
Name: name,
Values: vals,
}
ret[schema] = append(ret[schema], enum)
}
Expand Down Expand Up @@ -201,7 +200,7 @@ func queryValues(log *log.Logger, db *sql.DB, schema, enum string) ([]*database.
if err := rows.Scan(&name, &val); err != nil {
return nil, errors.Wrapf(err, "failed reading enum values for %s.%s", schema, enum)
}
vals = append(vals, &database.EnumValue{DBName: name.String, Value: int(val.Int64)})
vals = append(vals, &database.EnumValue{Name: name.String, Value: int(val.Int64)})
}
log.Printf("found %d values for enum %v.%v", len(vals), schema, enum)
return vals, nil
Expand Down
3 changes: 2 additions & 1 deletion database/drivers/postgres/templates/table.gotmpl
@@ -1,5 +1,5 @@
// Code generated by gnorm, DO NOT EDIT!

{{with .Table}}
package {{toLower .Name}}

import "gnorm.org/gnorm/database/drivers/postgres/gnorm"
Expand Down Expand Up @@ -53,3 +53,4 @@ func Query(db gnorm.DB, where gnorm.WhereClause) ([]*Row, error) {
return vals, nil
}

{{end}}

0 comments on commit c06a4fb

Please sign in to comment.