Add the ability to fully customize jet generated files.

This commit is contained in:
go-jet 2021-07-27 17:39:21 +02:00
parent caa81930dc
commit 8864667f47
40 changed files with 2274 additions and 882 deletions

View file

@ -4,15 +4,15 @@ import "fmt"
// Postgres test database connection parameters
const (
Host = "localhost"
Port = 5432
User = "jet"
Password = "jet"
DBName = "jetdb"
PgHost = "localhost"
PgPort = 5432
PgUser = "jet"
PgPassword = "jet"
PgDBName = "jetdb"
)
// PostgresConnectString is PostgreSQL test database connection string
var PostgresConnectString = fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", Host, Port, User, Password, DBName)
var PostgresConnectString = fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", PgHost, PgPort, PgUser, PgPassword, PgDBName)
// MySQL test database connection parameters
const (

View file

@ -6,7 +6,7 @@ import (
"fmt"
"github.com/go-jet/jet/v2/generator/mysql"
"github.com/go-jet/jet/v2/generator/postgres"
"github.com/go-jet/jet/v2/internal/utils"
"github.com/go-jet/jet/v2/internal/utils/throw"
"github.com/go-jet/jet/v2/tests/dbconfig"
_ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq"
@ -62,7 +62,7 @@ func initMySQLDB() {
cmd.Stdout = os.Stdout
err := cmd.Run()
utils.PanicOnError(err)
throw.OnError(err)
err = mysql.Generate("./.gentestdata/mysql", mysql.DBConnection{
Host: dbconfig.MySqLHost,
@ -72,7 +72,7 @@ func initMySQLDB() {
DBName: dbName,
})
utils.PanicOnError(err)
throw.OnError(err)
}
}
@ -99,24 +99,24 @@ func initPostgresDB() {
execFile(db, "./testdata/init/postgres/"+schemaName+".sql")
err = postgres.Generate("./.gentestdata", postgres.DBConnection{
Host: dbconfig.Host,
Host: dbconfig.PgHost,
Port: 5432,
User: dbconfig.User,
Password: dbconfig.Password,
DBName: dbconfig.DBName,
User: dbconfig.PgUser,
Password: dbconfig.PgPassword,
DBName: dbconfig.PgDBName,
SchemaName: schemaName,
SslMode: "disable",
})
utils.PanicOnError(err)
throw.OnError(err)
}
}
func execFile(db *sql.DB, sqlFilePath string) {
testSampleSql, err := ioutil.ReadFile(sqlFilePath)
utils.PanicOnError(err)
throw.OnError(err)
_, err = db.Exec(string(testSampleSql))
utils.PanicOnError(err)
throw.OnError(err)
}
func printOnError(err error) {

View file

@ -0,0 +1,25 @@
package file
import (
"github.com/stretchr/testify/require"
"io/ioutil"
"os"
"path"
"testing"
)
// Exists expects file to exist on path constructed from pathElems and returns content of the file
func Exists(t *testing.T, pathElems ...string) (fileContent string) {
modelFilePath := path.Join(pathElems...)
file, err := ioutil.ReadFile(modelFilePath)
require.Nil(t, err)
require.NotEmpty(t, file)
return string(file)
}
// NotExists expects file not to exist on path constructed from pathElems
func NotExists(t *testing.T, pathElems ...string) {
modelFilePath := path.Join(pathElems...)
_, err := ioutil.ReadFile(modelFilePath)
require.True(t, os.IsNotExist(err))
}

View file

@ -467,10 +467,10 @@ func TestStringOperators(t *testing.T) {
AllTypes.Text.NOT_LIKE(String("_b_")),
AllTypes.Text.REGEXP_LIKE(String("aba")),
AllTypes.Text.REGEXP_LIKE(String("aba"), false),
String("ABA").REGEXP_LIKE(String("aba"), true),
//String("ABA").REGEXP_LIKE(String("aba"), true),
AllTypes.Text.NOT_REGEXP_LIKE(String("aba")),
AllTypes.Text.NOT_REGEXP_LIKE(String("aba"), false),
String("ABA").NOT_REGEXP_LIKE(String("aba"), true),
//String("ABA").NOT_REGEXP_LIKE(String("aba"), true),
BIT_LENGTH(AllTypes.Text),
CHAR_LENGTH(AllTypes.Char),

View file

@ -0,0 +1,389 @@
package mysql
import (
"database/sql"
"fmt"
"github.com/go-jet/jet/v2/generator/metadata"
mysql2 "github.com/go-jet/jet/v2/generator/mysql"
"github.com/go-jet/jet/v2/generator/template"
"github.com/go-jet/jet/v2/internal/3rdparty/snaker"
"github.com/go-jet/jet/v2/internal/utils"
postgres2 "github.com/go-jet/jet/v2/postgres"
"github.com/go-jet/jet/v2/tests/dbconfig"
file2 "github.com/go-jet/jet/v2/tests/internal/utils/file"
"github.com/stretchr/testify/require"
"path"
"testing"
)
const tempTestDir = "./.tempTestDir"
var defaultModelPath = path.Join(tempTestDir, "dvds/model")
var defaultActorModelFilePath = path.Join(tempTestDir, "dvds/model", "actor.go")
var defaultTableSQLBuilderFilePath = path.Join(tempTestDir, "dvds/table")
var defaultViewSQLBuilderFilePath = path.Join(tempTestDir, "dvds/view")
var defaultEnumSQLBuilderFilePath = path.Join(tempTestDir, "dvds/enum")
var defaultActorSQLBuilderFilePath = path.Join(tempTestDir, "dvds/table", "actor.go")
var dbConnection = mysql2.DBConnection{
Host: dbconfig.MySqLHost,
Port: dbconfig.MySQLPort,
User: dbconfig.MySQLUser,
Password: dbconfig.MySQLPassword,
DBName: "dvds",
}
func TestGeneratorTemplate_Schema_ChangePath(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).UsePath("new/schema/path")
}),
)
require.Nil(t, err)
file2.Exists(t, tempTestDir, "new/schema/path/model/actor.go")
file2.Exists(t, tempTestDir, "new/schema/path/table/actor.go")
file2.Exists(t, tempTestDir, "new/schema/path/view/actor_info.go")
file2.Exists(t, tempTestDir, "new/schema/path/enum/film_rating.go")
}
func TestGeneratorTemplate_Model_SkipGeneration(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.Model{
Skip: true,
})
}),
)
require.Nil(t, err)
file2.NotExists(t, defaultActorModelFilePath)
file2.Exists(t, defaultTableSQLBuilderFilePath, "actor.go")
file2.Exists(t, defaultViewSQLBuilderFilePath, "actor_info.go")
file2.Exists(t, defaultEnumSQLBuilderFilePath, "film_rating.go")
}
func TestGeneratorTemplate_SQLBuilder_SkipGeneration(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.SQLBuilder{
Skip: true,
})
}),
)
require.Nil(t, err)
file2.Exists(t, defaultActorModelFilePath)
file2.NotExists(t, defaultTableSQLBuilderFilePath, "actor.go")
file2.NotExists(t, defaultViewSQLBuilderFilePath, "actor_info.go")
file2.NotExists(t, defaultEnumSQLBuilderFilePath, "film_rating.go")
}
func TestGeneratorTemplate_Model_ChangePath(t *testing.T) {
const newModelPath = "/new/model/path"
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().UsePath(newModelPath))
}),
)
require.Nil(t, err)
file2.Exists(t, tempTestDir, "dvds", newModelPath, "actor.go")
file2.NotExists(t, defaultActorModelFilePath)
}
func TestGeneratorTemplate_SQLBuilder_ChangePath(t *testing.T) {
const newModelPath = "/new/sql-builder/path"
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().UsePath(newModelPath))
}),
)
require.Nil(t, err)
file2.Exists(t, tempTestDir, "dvds", newModelPath, "table", "actor.go")
file2.Exists(t, tempTestDir, "dvds", newModelPath, "view", "actor_info.go")
file2.Exists(t, tempTestDir, "dvds", newModelPath, "enum", "film_rating.go")
file2.NotExists(t, defaultTableSQLBuilderFilePath, "actor.go")
file2.NotExists(t, defaultViewSQLBuilderFilePath, "actor_info.go")
file2.NotExists(t, defaultEnumSQLBuilderFilePath, "film_rating.go")
}
func TestGeneratorTemplate_Model_RenameFilesAndTypes(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().
UseTable(func(table metadata.Table) template.TableModel {
return template.DefaultTableModel(table).
UseFileName(schemaMetaData.Name + "_" + table.Name).
UseTypeName(utils.ToGoIdentifier(table.Name) + "Table")
}).
UseView(func(table metadata.Table) template.ViewModel {
return template.DefaultViewModel(table).
UseFileName(schemaMetaData.Name + "_" + table.Name + "_view").
UseTypeName(utils.ToGoIdentifier(table.Name) + "View")
}).
UseEnum(func(enumMetaData metadata.Enum) template.EnumModel {
return template.DefaultEnumModel(enumMetaData).
UseFileName(enumMetaData.Name + "_enum").
UseTypeName(utils.ToGoIdentifier(enumMetaData.Name) + "Enum")
}),
)
}),
)
require.Nil(t, err)
actor := file2.Exists(t, defaultModelPath, "dvds_actor.go")
require.Contains(t, actor, "type ActorTable struct {")
actorInfo := file2.Exists(t, defaultModelPath, "dvds_actor_info_view.go")
require.Contains(t, actorInfo, "type ActorInfoView struct {")
mpaaRating := file2.Exists(t, defaultModelPath, "film_rating_enum.go")
require.Contains(t, mpaaRating, "type FilmRatingEnum string")
}
func TestGeneratorTemplate_Model_SkipTableAndEnum(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().
UseTable(func(table metadata.Table) template.TableModel {
return template.TableModel{
Skip: true,
}
}).
UseEnum(func(enumMetaData metadata.Enum) template.EnumModel {
return template.EnumModel{
Skip: true,
}
}),
)
}),
)
require.Nil(t, err)
file2.NotExists(t, defaultModelPath, "actor.go")
file2.Exists(t, defaultModelPath, "actor_info.go")
file2.NotExists(t, defaultModelPath, "film_rating.go")
}
func TestGeneratorTemplate_SQLBuilder_SkipTableAndEnum(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().
UseTable(func(table metadata.Table) template.TableSQLBuilder {
return template.TableSQLBuilder{
Skip: true,
}
}).
UseView(func(table metadata.Table) template.TableSQLBuilder {
return template.TableSQLBuilder{
Skip: true,
}
}).
UseEnum(func(enumMetaData metadata.Enum) template.EnumSQLBuilder {
return template.EnumSQLBuilder{
Skip: true,
}
}),
)
}),
)
require.Nil(t, err)
file2.NotExists(t, defaultTableSQLBuilderFilePath, "actor.go")
file2.NotExists(t, defaultViewSQLBuilderFilePath, "actor_info.go")
file2.NotExists(t, defaultEnumSQLBuilderFilePath, "film_rating.go")
}
func TestGeneratorTemplate_SQLBuilder_ChangeTypeAndFileName(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().
UseTable(func(table metadata.Table) template.TableSQLBuilder {
return template.DefaultTableSQLBuilder(table).
UseFileName(schemaMetaData.Name + "_" + table.Name + "_table").
UseTypeName(utils.ToGoIdentifier(table.Name) + "TableSQLBuilder").
UseInstanceName("T_" + utils.ToGoIdentifier(table.Name))
}).
UseView(func(table metadata.Table) template.ViewSQLBuilder {
return template.DefaultViewSQLBuilder(table).
UseFileName(schemaMetaData.Name + "_" + table.Name + "_view").
UseTypeName(utils.ToGoIdentifier(table.Name) + "ViewSQLBuilder").
UseInstanceName("V_" + utils.ToGoIdentifier(table.Name))
}).
UseEnum(func(enum metadata.Enum) template.EnumSQLBuilder {
return template.DefaultEnumSQLBuilder(enum).
UseFileName(schemaMetaData.Name + "_" + enum.Name + "_enum").
UseInstanceName(utils.ToGoIdentifier(enum.Name) + "EnumSQLBuilder")
}),
)
}),
)
require.Nil(t, err)
actor := file2.Exists(t, defaultTableSQLBuilderFilePath, "dvds_actor_table.go")
require.Contains(t, actor, "type ActorTableSQLBuilder struct {")
require.Contains(t, actor, "var T_Actor = newActorTableSQLBuilder(\"dvds\", \"actor\", \"\")")
actorInfo := file2.Exists(t, defaultViewSQLBuilderFilePath, "dvds_actor_info_view.go")
require.Contains(t, actorInfo, "type ActorInfoViewSQLBuilder struct {")
require.Contains(t, actorInfo, "var V_ActorInfo = newActorInfoViewSQLBuilder(\"dvds\", \"actor_info\", \"\")")
mpaaRating := file2.Exists(t, defaultEnumSQLBuilderFilePath, "dvds_film_rating_enum.go")
require.Contains(t, mpaaRating, "var FilmRatingEnumSQLBuilder = &struct {")
}
func TestGeneratorTemplate_Model_AddTags(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().
UseTable(func(table metadata.Table) template.TableModel {
return template.DefaultTableModel(table).
UseField(func(columnMetaData metadata.Column) template.TableModelField {
defaultTableModelField := template.DefaultTableModelField(columnMetaData)
return defaultTableModelField.UseTags(
fmt.Sprintf(`json:"%s"`, snaker.SnakeToCamel(columnMetaData.Name, false)),
fmt.Sprintf(`xml:"%s"`, columnMetaData.Name),
)
})
}).
UseView(func(table metadata.Table) template.ViewModel {
return template.DefaultViewModel(table).
UseField(func(columnMetaData metadata.Column) template.TableModelField {
defaultTableModelField := template.DefaultTableModelField(columnMetaData)
if table.Name == "actor_info" && columnMetaData.Name == "actor_id" {
return defaultTableModelField.UseTags(`sql:"primary_key"`)
}
return defaultTableModelField
})
}),
)
}),
)
require.Nil(t, err)
actor := file2.Exists(t, defaultActorModelFilePath)
require.Contains(t, actor, "ActorID uint16 `sql:\"primary_key\" json:\"actorID\" xml:\"actor_id\"`")
require.Contains(t, actor, "FirstName string `json:\"firstName\" xml:\"first_name\"`")
actorInfo := file2.Exists(t, defaultModelPath, "actor_info.go")
require.Contains(t, actorInfo, "ActorID uint16 `sql:\"primary_key\"`")
}
func TestGeneratorTemplate_Model_ChangeFieldTypes(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().
UseTable(func(table metadata.Table) template.TableModel {
return template.DefaultTableModel(table).
UseField(func(columnMetaData metadata.Column) template.TableModelField {
defaultTableModelField := template.DefaultTableModelField(columnMetaData)
switch defaultTableModelField.Type.Name {
case "*string":
defaultTableModelField.Type = template.NewType(sql.NullString{})
case "*int32":
defaultTableModelField.Type = template.NewType(sql.NullInt32{})
case "*int64":
defaultTableModelField.Type = template.NewType(sql.NullInt64{})
case "*bool":
defaultTableModelField.Type = template.NewType(sql.NullBool{})
case "*float64":
defaultTableModelField.Type = template.NewType(sql.NullFloat64{})
case "*time.Time":
defaultTableModelField.Type = template.NewType(sql.NullTime{})
}
return defaultTableModelField
})
}),
)
}),
)
require.Nil(t, err)
data := file2.Exists(t, defaultModelPath, "film.go")
require.Contains(t, data, "\"database/sql\"")
require.Contains(t, data, "Description sql.NullString")
require.Contains(t, data, "ReleaseYear *int16")
require.Contains(t, data, "SpecialFeatures sql.NullString")
}
func TestGeneratorTemplate_SQLBuilder_ChangeColumnTypes(t *testing.T) {
err := mysql2.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().
UseTable(func(table metadata.Table) template.TableSQLBuilder {
return template.DefaultTableSQLBuilder(table).
UseColumn(func(column metadata.Column) template.TableSQLBuilderColumn {
defaultColumn := template.DefaultTableSQLBuilderColumn(column)
if defaultColumn.Name == "ActorID" {
defaultColumn.Type = "String"
}
return defaultColumn
})
}),
)
}),
)
require.Nil(t, err)
actor := file2.Exists(t, defaultActorSQLBuilderFilePath)
require.Contains(t, actor, "ActorID postgres.ColumnString")
}

View file

@ -66,9 +66,7 @@ func TestUpdateWithSubQueries(t *testing.T) {
expectedSQL := `
UPDATE test_sample.link
SET name = (
SELECT ?
),
SET name = ?,
url = (
SELECT link2.url AS "link2.url"
FROM test_sample.link2
@ -80,7 +78,7 @@ WHERE link.name = ?;
query := Link.
UPDATE(Link.Name, Link.URL).
SET(
SELECT(String("Bong")),
String("Bong"),
SELECT(Link2.URL).
FROM(Link2).
WHERE(Link2.Name.EQ(String("Youtube"))),
@ -96,7 +94,7 @@ WHERE link.name = ?;
query := Link.
UPDATE().
SET(
Link.Name.SET(StringExp(SELECT(String("Bong")))),
Link.Name.SET(String("Bong")),
Link.URL.SET(StringExp(
SELECT(Link2.URL).
FROM(Link2).

View file

@ -0,0 +1,387 @@
package postgres
import (
"database/sql"
"fmt"
"github.com/go-jet/jet/v2/generator/metadata"
"github.com/go-jet/jet/v2/generator/postgres"
"github.com/go-jet/jet/v2/generator/template"
"github.com/go-jet/jet/v2/internal/3rdparty/snaker"
"github.com/go-jet/jet/v2/internal/utils"
postgres2 "github.com/go-jet/jet/v2/postgres"
"github.com/go-jet/jet/v2/tests/dbconfig"
file2 "github.com/go-jet/jet/v2/tests/internal/utils/file"
"github.com/stretchr/testify/require"
"path"
"testing"
)
const tempTestDir = "./.tempTestDir"
var defaultModelPath = path.Join(tempTestDir, "jetdb/dvds/model")
var defaultActorModelFilePath = path.Join(tempTestDir, "jetdb/dvds/model", "actor.go")
var defaultTableSQLBuilderFilePath = path.Join(tempTestDir, "jetdb/dvds/table")
var defaultViewSQLBuilderFilePath = path.Join(tempTestDir, "jetdb/dvds/view")
var defaultEnumSQLBuilderFilePath = path.Join(tempTestDir, "jetdb/dvds/enum")
var defaultActorSQLBuilderFilePath = path.Join(tempTestDir, "jetdb/dvds/table", "actor.go")
var dbConnection = postgres.DBConnection{
Host: dbconfig.PgHost,
Port: 5432,
User: dbconfig.PgUser,
Password: dbconfig.PgPassword,
DBName: dbconfig.PgDBName,
SchemaName: "dvds",
SslMode: "disable",
}
func TestGeneratorTemplate_Schema_ChangePath(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).UsePath("new/schema/path")
}),
)
require.Nil(t, err)
file2.Exists(t, tempTestDir, "jetdb/new/schema/path/model/actor.go")
file2.Exists(t, tempTestDir, "jetdb/new/schema/path/table/actor.go")
file2.Exists(t, tempTestDir, "jetdb/new/schema/path/view/actor_info.go")
file2.Exists(t, tempTestDir, "jetdb/new/schema/path/enum/mpaa_rating.go")
}
func TestGeneratorTemplate_Model_SkipGeneration(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.Model{
Skip: true,
})
}),
)
require.Nil(t, err)
file2.NotExists(t, defaultActorModelFilePath)
}
func TestGeneratorTemplate_SQLBuilder_SkipGeneration(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.SQLBuilder{
Skip: true,
})
}),
)
require.Nil(t, err)
file2.NotExists(t, defaultTableSQLBuilderFilePath, "actor.go")
file2.NotExists(t, defaultViewSQLBuilderFilePath, "actor_info.go")
file2.NotExists(t, defaultEnumSQLBuilderFilePath, "mpaa_rating.go")
}
func TestGeneratorTemplate_Model_ChangePath(t *testing.T) {
const newModelPath = "/new/model/path"
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().UsePath(newModelPath))
}),
)
require.Nil(t, err)
file2.Exists(t, tempTestDir, "jetdb", "dvds", newModelPath, "actor.go")
file2.NotExists(t, defaultActorModelFilePath)
}
func TestGeneratorTemplate_SQLBuilder_ChangePath(t *testing.T) {
const newModelPath = "/new/sql-builder/path"
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().UsePath(newModelPath))
}),
)
require.Nil(t, err)
file2.Exists(t, tempTestDir, "jetdb", "dvds", newModelPath, "table", "actor.go")
file2.Exists(t, tempTestDir, "jetdb", "dvds", newModelPath, "view", "actor_info.go")
file2.Exists(t, tempTestDir, "jetdb", "dvds", newModelPath, "enum", "mpaa_rating.go")
file2.NotExists(t, defaultTableSQLBuilderFilePath, "actor.go")
file2.NotExists(t, defaultViewSQLBuilderFilePath, "actor_info.go")
file2.NotExists(t, defaultEnumSQLBuilderFilePath, "mpaa_rating.go")
}
func TestGeneratorTemplate_Model_RenameFilesAndTypes(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().
UseTable(func(table metadata.Table) template.TableModel {
return template.DefaultTableModel(table).
UseFileName(schemaMetaData.Name + "_" + table.Name).
UseTypeName(utils.ToGoIdentifier(table.Name) + "Table")
}).
UseView(func(table metadata.Table) template.ViewModel {
return template.DefaultViewModel(table).
UseFileName(schemaMetaData.Name + "_" + table.Name + "_view").
UseTypeName(utils.ToGoIdentifier(table.Name) + "View")
}).
UseEnum(func(enumMetaData metadata.Enum) template.EnumModel {
return template.DefaultEnumModel(enumMetaData).
UseFileName(enumMetaData.Name + "_enum").
UseTypeName(utils.ToGoIdentifier(enumMetaData.Name) + "Enum")
}),
)
}),
)
require.Nil(t, err)
actor := file2.Exists(t, defaultModelPath, "dvds_actor.go")
require.Contains(t, actor, "type ActorTable struct {")
actorInfo := file2.Exists(t, defaultModelPath, "dvds_actor_info_view.go")
require.Contains(t, actorInfo, "type ActorInfoView struct {")
mpaaRating := file2.Exists(t, defaultModelPath, "mpaa_rating_enum.go")
require.Contains(t, mpaaRating, "type MpaaRatingEnum string")
}
func TestGeneratorTemplate_Model_SkipTableAndEnum(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().
UseTable(func(table metadata.Table) template.TableModel {
return template.TableModel{
Skip: true,
}
}).
UseEnum(func(enumMetaData metadata.Enum) template.EnumModel {
return template.EnumModel{
Skip: true,
}
}),
)
}),
)
require.Nil(t, err)
file2.NotExists(t, defaultModelPath, "actor.go")
file2.Exists(t, defaultModelPath, "actor_info.go")
file2.NotExists(t, defaultModelPath, "mpaa_rating.go")
}
func TestGeneratorTemplate_SQLBuilder_SkipTableAndEnum(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().
UseTable(func(table metadata.Table) template.TableSQLBuilder {
return template.TableSQLBuilder{
Skip: true,
}
}).
UseView(func(table metadata.Table) template.TableSQLBuilder {
return template.TableSQLBuilder{
Skip: true,
}
}).
UseEnum(func(enumMetaData metadata.Enum) template.EnumSQLBuilder {
return template.EnumSQLBuilder{
Skip: true,
}
}),
)
}),
)
require.Nil(t, err)
file2.NotExists(t, defaultTableSQLBuilderFilePath, "actor.go")
file2.NotExists(t, defaultViewSQLBuilderFilePath, "actor_info.go")
file2.NotExists(t, defaultEnumSQLBuilderFilePath, "mpaa_rating.go")
}
func TestGeneratorTemplate_SQLBuilder_ChangeTypeAndFileName(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().
UseTable(func(table metadata.Table) template.TableSQLBuilder {
return template.DefaultTableSQLBuilder(table).
UseFileName(schemaMetaData.Name + "_" + table.Name + "_table").
UseTypeName(utils.ToGoIdentifier(table.Name) + "TableSQLBuilder").
UseInstanceName("T_" + utils.ToGoIdentifier(table.Name))
}).
UseView(func(table metadata.Table) template.ViewSQLBuilder {
return template.DefaultViewSQLBuilder(table).
UseFileName(schemaMetaData.Name + "_" + table.Name + "_view").
UseTypeName(utils.ToGoIdentifier(table.Name) + "ViewSQLBuilder").
UseInstanceName("V_" + utils.ToGoIdentifier(table.Name))
}).
UseEnum(func(enum metadata.Enum) template.EnumSQLBuilder {
return template.DefaultEnumSQLBuilder(enum).
UseFileName(schemaMetaData.Name + "_" + enum.Name + "_enum").
UseInstanceName(utils.ToGoIdentifier(enum.Name) + "EnumSQLBuilder")
}),
)
}),
)
require.Nil(t, err)
actor := file2.Exists(t, defaultTableSQLBuilderFilePath, "dvds_actor_table.go")
require.Contains(t, actor, "type ActorTableSQLBuilder struct {")
require.Contains(t, actor, "var T_Actor = newActorTableSQLBuilder(\"dvds\", \"actor\", \"\")")
actorInfo := file2.Exists(t, defaultViewSQLBuilderFilePath, "dvds_actor_info_view.go")
require.Contains(t, actorInfo, "type ActorInfoViewSQLBuilder struct {")
require.Contains(t, actorInfo, "var V_ActorInfo = newActorInfoViewSQLBuilder(\"dvds\", \"actor_info\", \"\")")
mpaaRating := file2.Exists(t, defaultEnumSQLBuilderFilePath, "dvds_mpaa_rating_enum.go")
require.Contains(t, mpaaRating, "var MpaaRatingEnumSQLBuilder = &struct {")
}
func TestGeneratorTemplate_Model_AddTags(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().
UseTable(func(table metadata.Table) template.TableModel {
return template.DefaultTableModel(table).
UseField(func(columnMetaData metadata.Column) template.TableModelField {
defaultTableModelField := template.DefaultTableModelField(columnMetaData)
return defaultTableModelField.UseTags(
fmt.Sprintf(`json:"%s"`, snaker.SnakeToCamel(columnMetaData.Name, false)),
fmt.Sprintf(`xml:"%s"`, columnMetaData.Name),
)
})
}).
UseView(func(table metadata.Table) template.ViewModel {
return template.DefaultViewModel(table).
UseField(func(columnMetaData metadata.Column) template.TableModelField {
defaultTableModelField := template.DefaultTableModelField(columnMetaData)
if table.Name == "actor_info" && columnMetaData.Name == "actor_id" {
return defaultTableModelField.UseTags(`sql:"primary_key"`)
}
return defaultTableModelField
})
}),
)
}),
)
require.Nil(t, err)
actor := file2.Exists(t, defaultActorModelFilePath)
require.Contains(t, actor, "ActorID int32 `sql:\"primary_key\" json:\"actorID\" xml:\"actor_id\"`")
require.Contains(t, actor, "FirstName string `json:\"firstName\" xml:\"first_name\"`")
actorInfo := file2.Exists(t, defaultModelPath, "actor_info.go")
require.Contains(t, actorInfo, "ActorID *int32 `sql:\"primary_key\"`")
}
func TestGeneratorTemplate_Model_ChangeFieldTypes(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseModel(template.DefaultModel().
UseTable(func(table metadata.Table) template.TableModel {
return template.DefaultTableModel(table).
UseField(func(columnMetaData metadata.Column) template.TableModelField {
defaultTableModelField := template.DefaultTableModelField(columnMetaData)
switch defaultTableModelField.Type.Name {
case "*string":
defaultTableModelField.Type = template.NewType(sql.NullString{})
case "*int32":
defaultTableModelField.Type = template.NewType(sql.NullInt32{})
case "*int64":
defaultTableModelField.Type = template.NewType(sql.NullInt64{})
case "*bool":
defaultTableModelField.Type = template.NewType(sql.NullBool{})
case "*float64":
defaultTableModelField.Type = template.NewType(sql.NullFloat64{})
case "*time.Time":
defaultTableModelField.Type = template.NewType(sql.NullTime{})
}
return defaultTableModelField
})
}),
)
}),
)
require.Nil(t, err)
data := file2.Exists(t, defaultModelPath, "film.go")
require.Contains(t, data, "\"database/sql\"")
require.Contains(t, data, "Description sql.NullString")
require.Contains(t, data, "ReleaseYear sql.NullInt32")
require.Contains(t, data, "SpecialFeatures sql.NullString")
}
func TestGeneratorTemplate_SQLBuilder_ChangeColumnTypes(t *testing.T) {
err := postgres.Generate(
tempTestDir,
dbConnection,
template.Default(postgres2.Dialect).
UseSchema(func(schemaMetaData metadata.Schema) template.Schema {
return template.DefaultSchema(schemaMetaData).
UseSQLBuilder(template.DefaultSQLBuilder().
UseTable(func(table metadata.Table) template.TableSQLBuilder {
return template.DefaultTableSQLBuilder(table).
UseColumn(func(column metadata.Column) template.TableSQLBuilderColumn {
defaultColumn := template.DefaultTableSQLBuilderColumn(column)
if defaultColumn.Name == "ActorID" {
defaultColumn.Type = "String"
}
return defaultColumn
})
}),
)
}),
)
require.Nil(t, err)
actor := file2.Exists(t, defaultActorSQLBuilderFilePath)
require.Contains(t, actor, "ActorID postgres.ColumnString")
}

View file

@ -67,14 +67,14 @@ func TestGenerator(t *testing.T) {
for i := 0; i < 3; i++ {
err := postgres.Generate(genTestDir2, postgres.DBConnection{
Host: dbconfig.Host,
Port: dbconfig.Port,
User: dbconfig.User,
Password: dbconfig.Password,
Host: dbconfig.PgHost,
Port: dbconfig.PgPort,
User: dbconfig.PgUser,
Password: dbconfig.PgPassword,
SslMode: "disable",
Params: "",
DBName: dbconfig.DBName,
DBName: dbconfig.PgDBName,
SchemaName: "dvds",
})

View file

@ -32,6 +32,8 @@ func TestMain(m *testing.M) {
setTestRoot()
for _, driverName := range []string{"postgres", "pgx"} {
fmt.Printf("\nRunning postgres tests for '%s' driver\n", driverName)
func() {
var err error
db, err = sql.Open(driverName, dbconfig.PostgresConnectString)