Package structure refactor.

This commit is contained in:
go-jet 2019-08-03 14:10:47 +02:00
parent 3d8e872336
commit 23fd973699
125 changed files with 2401 additions and 1818 deletions

View file

@ -1,136 +0,0 @@
package jet
import (
"testing"
)
func TestBoolExpressionEQ(t *testing.T) {
assertClauseSerializeErr(t, table1ColBool.EQ(nil), "jet: nil rhs")
AssertPostgreClauseSerialize(t, table1ColBool.EQ(table2ColBool), "(table1.col_bool = table2.col_bool)")
AssertPostgreClauseSerialize(t, table1ColBool.EQ(Bool(true)), "(table1.col_bool = $1)", true)
AssertMySQLClauseSerialize(t, table1ColBool.EQ(table2ColBool), "(table1.col_bool = table2.col_bool)")
AssertMySQLClauseSerialize(t, table1ColBool.EQ(Bool(true)), "(table1.col_bool = ?)", true)
}
func TestBoolExpressionNOT_EQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.NOT_EQ(table2ColBool), "(table1.col_bool != table2.col_bool)")
AssertPostgreClauseSerialize(t, table1ColBool.NOT_EQ(Bool(true)), "(table1.col_bool != $1)", true)
AssertMySQLClauseSerialize(t, table1ColBool.NOT_EQ(table2ColBool), "(table1.col_bool != table2.col_bool)")
AssertMySQLClauseSerialize(t, table1ColBool.NOT_EQ(Bool(true)), "(table1.col_bool != ?)", true)
}
func TestBoolExpressionIS_DISTINCT_FROM(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(table2ColBool), "(table1.col_bool IS DISTINCT FROM table2.col_bool)")
AssertPostgreClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(Bool(false)), "(table1.col_bool IS DISTINCT FROM $1)", false)
AssertMySQLClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(table2ColBool), "(NOT table1.col_bool <=> table2.col_bool)")
AssertMySQLClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(Bool(false)), "(NOT table1.col_bool <=> ?)", false)
}
func TestBoolExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(table2ColBool), "(table1.col_bool IS NOT DISTINCT FROM table2.col_bool)")
AssertPostgreClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(Bool(false)), "(table1.col_bool IS NOT DISTINCT FROM $1)", false)
AssertMySQLClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(table2ColBool), "(table1.col_bool <=> table2.col_bool)")
AssertMySQLClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(Bool(false)), "(table1.col_bool <=> ?)", false)
}
func TestBoolExpressionIS_TRUE(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.IS_TRUE(), "table1.col_bool IS TRUE")
AssertPostgreClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE(),
`($1 = table1.col_int) IS TRUE`, int64(2))
AssertPostgreClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE().AND(Int(4).EQ(table2ColInt)),
`(($1 = table1.col_int) IS TRUE AND ($2 = table2.col_int))`, int64(2), int64(4))
AssertMySQLClauseSerialize(t, table1ColBool.IS_TRUE(), "table1.col_bool IS TRUE")
AssertMySQLClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE(),
`(? = table1.col_int) IS TRUE`, int64(2))
AssertMySQLClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE().AND(Int(4).EQ(table2ColInt)),
`((? = table1.col_int) IS TRUE AND (? = table2.col_int))`, int64(2), int64(4))
}
func TestBoolExpressionIS_NOT_TRUE(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.IS_NOT_TRUE(), "table1.col_bool IS NOT TRUE")
AssertMySQLClauseSerialize(t, table1ColBool.IS_NOT_TRUE(), "table1.col_bool IS NOT TRUE")
}
func TestBoolExpressionIS_FALSE(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.IS_FALSE(), "table1.col_bool IS FALSE")
AssertMySQLClauseSerialize(t, table1ColBool.IS_FALSE(), "table1.col_bool IS FALSE")
}
func TestBoolExpressionIS_NOT_FALSE(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.IS_NOT_FALSE(), "table1.col_bool IS NOT FALSE")
}
func TestBoolExpressionIS_UNKNOWN(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.IS_UNKNOWN(), "table1.col_bool IS UNKNOWN")
AssertMySQLClauseSerialize(t, table1ColBool.IS_UNKNOWN(), "table1.col_bool IS UNKNOWN")
}
func TestBoolExpressionIS_NOT_UNKNOWN(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColBool.IS_NOT_UNKNOWN(), "table1.col_bool IS NOT UNKNOWN")
AssertMySQLClauseSerialize(t, table1ColBool.IS_NOT_UNKNOWN(), "table1.col_bool IS NOT UNKNOWN")
}
func TestBinaryBoolExpression(t *testing.T) {
boolExpression := Int(2).EQ(Int(3))
AssertPostgreClauseSerialize(t, boolExpression, "($1 = $2)", int64(2), int64(3))
assertProjectionSerialize(t, boolExpression, "$1 = $2", int64(2), int64(3))
assertProjectionSerialize(t, boolExpression.AS("alias_eq_expression"),
`($1 = $2) AS "alias_eq_expression"`, int64(2), int64(3))
AssertPostgreClauseSerialize(t, boolExpression.AND(Int(4).EQ(Int(5))),
"(($1 = $2) AND ($3 = $4))", int64(2), int64(3), int64(4), int64(5))
AssertPostgreClauseSerialize(t, boolExpression.OR(Int(4).EQ(Int(5))),
"(($1 = $2) OR ($3 = $4))", int64(2), int64(3), int64(4), int64(5))
}
func TestBoolLiteral(t *testing.T) {
AssertPostgreClauseSerialize(t, Bool(true), "$1", true)
AssertPostgreClauseSerialize(t, Bool(false), "$1", false)
AssertMySQLClauseSerialize(t, Bool(true), "?", true)
AssertMySQLClauseSerialize(t, Bool(false), "?", false)
}
func TestExists(t *testing.T) {
AssertPostgreClauseSerialize(t, EXISTS(
table2.
SELECT(Int(1)).
WHERE(table1Col1.EQ(table2Col3)),
),
`(EXISTS (
SELECT $1
FROM db.table2
WHERE table1.col1 = table2.col3
))`, int64(1))
AssertMySQLClauseSerialize(t, EXISTS(
table2.
SELECT(Int(1)).
WHERE(table1Col1.EQ(table2Col3)),
),
`(EXISTS (
SELECT ?
FROM db.table2
WHERE table1.col1 = table2.col3
))`, int64(1))
}
func TestBoolExp(t *testing.T) {
AssertPostgreClauseSerialize(t, BoolExp(String("true")), "$1", "true")
AssertPostgreClauseSerialize(t, BoolExp(String("true")).IS_TRUE(), "$1 IS TRUE", "true")
AssertMySQLClauseSerialize(t, BoolExp(String("true")), "?", "true")
AssertMySQLClauseSerialize(t, BoolExp(String("true")).IS_TRUE(), "? IS TRUE", "true")
}

View file

@ -3,9 +3,10 @@ package main
import ( import (
"flag" "flag"
"fmt" "fmt"
"github.com/go-jet/jet" mysqlgen "github.com/go-jet/jet/generator/mysql"
"github.com/go-jet/jet/generator/mysql" postgresgen "github.com/go-jet/jet/generator/postgres"
"github.com/go-jet/jet/generator/postgres" "github.com/go-jet/jet/mysql"
"github.com/go-jet/jet/postgres"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
_ "github.com/lib/pq" _ "github.com/lib/pq"
"os" "os"
@ -27,7 +28,7 @@ var (
) )
func init() { func init() {
flag.StringVar(&source, "source", string(jet.PostgreSQL.Name), "Database name") flag.StringVar(&source, "source", postgres.Dialect.Name(), "Database name")
flag.StringVar(&host, "host", "", "Database host path (Example: localhost)") flag.StringVar(&host, "host", "", "Database host path (Example: localhost)")
flag.IntVar(&port, "port", 0, "Database port") flag.IntVar(&port, "port", 0, "Database port")
@ -72,14 +73,14 @@ Usage of jet:
var err error var err error
switch source { switch source {
case jet.PostgreSQL.Name: case postgres.Dialect.Name():
if host == "" || port == 0 || user == "" || dbName == "" || schemaName == "" { if host == "" || port == 0 || user == "" || dbName == "" || schemaName == "" {
fmt.Println("\njet: required flag missing") fmt.Println("\njet: required flag missing")
flag.Usage() flag.Usage()
os.Exit(-2) os.Exit(-2)
} }
genData := postgres.DBConnection{ genData := postgresgen.DBConnection{
Host: host, Host: host,
Port: port, Port: port,
User: user, User: user,
@ -91,16 +92,16 @@ Usage of jet:
SchemaName: schemaName, SchemaName: schemaName,
} }
err = postgres.Generate(destDir, genData) err = postgresgen.Generate(destDir, genData)
case jet.MySQL.Name: case mysql.Dialect.Name():
if host == "" || port == 0 || user == "" || dbName == "" { if host == "" || port == 0 || user == "" || dbName == "" {
fmt.Println("\njet: required flag missing") fmt.Println("\njet: required flag missing")
flag.Usage() flag.Usage()
os.Exit(-2) os.Exit(-2)
} }
dbConn := mysql.DBConnection{ dbConn := mysqlgen.DBConnection{
Host: host, Host: host,
Port: port, Port: port,
User: user, User: user,
@ -110,7 +111,7 @@ Usage of jet:
DBName: dbName, DBName: dbName,
} }
err = mysql.Generate(destDir, dbConn) err = mysqlgen.Generate(destDir, dbConn)
} }
if err != nil { if err != nil {

View file

@ -1,232 +0,0 @@
package jet
import (
"github.com/pkg/errors"
"strconv"
)
var (
Default = MySQL
PostgreSQL = newPostgresDialect()
MySQL = newMySQLDialect()
)
func newPostgresDialect() Dialect {
postgresDialect := newDialect("PostgreSQL", "postgres")
postgresDialect.CastOverride = postgresCAST
postgresDialect.AliasQuoteChar = '"'
postgresDialect.IdentifierQuoteChar = '"'
postgresDialect.ArgumentPlaceholder = func(ord int) string {
return "$" + strconv.Itoa(ord)
}
postgresDialect.SupportsReturning = true
postgresDialect.UpdateAssigment = postgresUpdateAssigment
return postgresDialect
}
func newMySQLDialect() Dialect {
mySQLDialect := newDialect("MySQL", "mysql")
mySQLDialect.SerializeOverrides["IS DISTINCT FROM"] = mysql_IS_DISTINCT_FROM
mySQLDialect.SerializeOverrides["IS NOT DISTINCT FROM"] = mysql_IS_NOT_DISTINCT_FROM
mySQLDialect.SerializeOverrides["/"] = mysql_DIVISION
mySQLDialect.SerializeOverrides["#"] = mysql_BIT_XOR
mySQLDialect.AliasQuoteChar = '"'
mySQLDialect.IdentifierQuoteChar = '`'
mySQLDialect.ArgumentPlaceholder = func(int) string {
return "?"
}
mySQLDialect.SupportsReturning = false
mySQLDialect.UpdateAssigment = mysqlUpdateAssigment
return mySQLDialect
}
type Dialect struct {
Name string
PackageName string
SerializeOverrides map[string]serializeOverride
CastOverride castOverride
AliasQuoteChar byte
IdentifierQuoteChar byte
ArgumentPlaceholder queryPlaceholderFunc
UpdateAssigment func(columns []column, values []clause, out *sqlBuilder) (err error)
SupportsReturning bool
}
func (d *Dialect) serializeOverride(operator string) serializeOverride {
return d.SerializeOverrides[operator]
}
func mysqlUpdateAssigment(columns []column, values []clause, out *sqlBuilder) (err error) {
if len(columns) != len(values) {
return errors.New("jet: mismatch in numers of columns and values")
}
for i, column := range columns {
if i > 0 {
out.writeString(", ")
}
out.writeString(column.Name())
out.writeString(" = ")
if err = values[i].serialize(updateStatement, out); err != nil {
return err
}
}
return nil
}
func postgresUpdateAssigment(columns []column, values []clause, out *sqlBuilder) (err error) {
if len(columns) > 1 {
out.writeString("(")
}
err = serializeColumnNames(columns, out)
if err != nil {
return
}
if len(columns) > 1 {
out.writeString(")")
}
out.writeString("=")
if len(values) > 1 {
out.writeString("(")
}
err = serializeClauseList(updateStatement, values, out)
if err != nil {
return
}
if len(values) > 1 {
out.writeString(")")
}
return
}
type queryPlaceholderFunc func(ord int) string
func newDialect(name, packageName string) Dialect {
newDialect := Dialect{
Name: name,
PackageName: packageName,
}
newDialect.SerializeOverrides = make(map[string]serializeOverride)
return newDialect
}
func mysql_BIT_XOR(expressions ...Expression) serializeFunc {
return func(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if len(expressions) != 2 {
return errors.New("Invalid number of expressions for operator")
}
lhs := expressions[0]
rhs := expressions[1]
if err := lhs.serialize(statement, out, options...); err != nil {
return err
}
out.writeString("^")
if err := rhs.serialize(statement, out, options...); err != nil {
return err
}
return nil
}
}
func mysql_DIVISION(expressions ...Expression) serializeFunc {
return func(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if len(expressions) != 2 {
return errors.New("Invalid number of expressions for operator")
}
lhs := expressions[0]
rhs := expressions[1]
if err := lhs.serialize(statement, out, options...); err != nil {
return err
}
_, isLhsInt := lhs.(IntegerExpression)
_, isRhsInt := rhs.(IntegerExpression)
if isLhsInt && isRhsInt {
out.writeString("DIV")
} else {
out.writeString("/")
}
if err := rhs.serialize(statement, out, options...); err != nil {
return err
}
return nil
}
}
func mysql_IS_NOT_DISTINCT_FROM(expressions ...Expression) serializeFunc {
return func(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if len(expressions) != 2 {
return errors.New("Invalid number of expressions for operator")
}
if err := expressions[0].serialize(statement, out); err != nil {
return err
}
out.writeString("<=>")
if err := expressions[1].serialize(statement, out); err != nil {
return err
}
return nil
}
}
func mysql_IS_DISTINCT_FROM(expressions ...Expression) serializeFunc {
return func(statement statementType, out *sqlBuilder, options ...serializeOption) error {
out.writeString("NOT")
err := mysql_IS_NOT_DISTINCT_FROM(expressions...)(statement, out, options...)
if err != nil {
return err
}
return nil
}
}
func postgresCAST(expression Expression, castType string) serializeFunc {
return func(statement statementType, out *sqlBuilder, options ...serializeOption) error {
if err := expression.serialize(statement, out, options...); err != nil {
return err
}
out.writeString("::" + castType)
return nil
}
}
type serializeFunc func(statement statementType, out *sqlBuilder, options ...serializeOption) error
type serializeOverride func(expressions ...Expression) serializeFunc
type castOverride func(expression Expression, castType string) serializeFunc

View file

@ -9,8 +9,8 @@ import (
// dot import so go code would resemble as much as native SQL // dot import so go code would resemble as much as native SQL
// dot import is not mandatory // dot import is not mandatory
. "github.com/go-jet/jet"
. "github.com/go-jet/jet/examples/quick-start/.gen/jetdb/dvds/table" . "github.com/go-jet/jet/examples/quick-start/.gen/jetdb/dvds/table"
. "github.com/go-jet/jet/postgres"
"github.com/go-jet/jet/examples/quick-start/.gen/jetdb/dvds/model" "github.com/go-jet/jet/examples/quick-start/.gen/jetdb/dvds/model"
) )

View file

@ -1,58 +0,0 @@
package jet
import (
"testing"
)
func TestExpressionIS_NULL(t *testing.T) {
AssertPostgreClauseSerialize(t, table2Col3.IS_NULL(), "table2.col3 IS NULL")
AssertPostgreClauseSerialize(t, table2Col3.ADD(table2Col3).IS_NULL(), "(table2.col3 + table2.col3) IS NULL")
assertClauseSerializeErr(t, table2Col3.ADD(nil), "jet: nil rhs")
}
func TestExpressionIS_NOT_NULL(t *testing.T) {
AssertPostgreClauseSerialize(t, table2Col3.IS_NOT_NULL(), "table2.col3 IS NOT NULL")
AssertPostgreClauseSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_NULL(), "(table2.col3 + table2.col3) IS NOT NULL")
}
func TestExpressionIS_DISTINCT_FROM(t *testing.T) {
AssertPostgreClauseSerialize(t, table2Col3.IS_DISTINCT_FROM(table2Col4), "(table2.col3 IS DISTINCT FROM table2.col4)")
AssertPostgreClauseSerialize(t, table2Col3.ADD(table2Col3).IS_DISTINCT_FROM(Int(23)), "((table2.col3 + table2.col3) IS DISTINCT FROM $1)", int64(23))
}
func TestExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
AssertPostgreClauseSerialize(t, table2Col3.IS_NOT_DISTINCT_FROM(table2Col4), "(table2.col3 IS NOT DISTINCT FROM table2.col4)")
AssertPostgreClauseSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_DISTINCT_FROM(Int(23)), "((table2.col3 + table2.col3) IS NOT DISTINCT FROM $1)", int64(23))
}
func TestIN(t *testing.T) {
AssertPostgreClauseSerialize(t, Float(1.11).IN(table1.SELECT(table1Col1)),
`($1 IN ((
SELECT table1.col1 AS "table1.col1"
FROM db.table1
)))`, float64(1.11))
AssertPostgreClauseSerialize(t, ROW(Int(12), table1Col1).IN(table2.SELECT(table2Col3, table3Col1)),
`(ROW($1, table1.col1) IN ((
SELECT table2.col3 AS "table2.col3",
table3.col1 AS "table3.col1"
FROM db.table2
)))`, int64(12))
}
func TestNOT_IN(t *testing.T) {
AssertPostgreClauseSerialize(t, Float(1.11).NOT_IN(table1.SELECT(table1Col1)),
`($1 NOT IN ((
SELECT table1.col1 AS "table1.col1"
FROM db.table1
)))`, float64(1.11))
AssertPostgreClauseSerialize(t, ROW(Int(12), table1Col1).NOT_IN(table2.SELECT(table2Col3, table3Col1)),
`(ROW($1, table1.col1) NOT IN ((
SELECT table2.col3 AS "table2.col3",
table3.col1 AS "table3.col1"
FROM db.table2
)))`, int64(12))
}

View file

@ -1,85 +0,0 @@
package jet
import (
"testing"
)
func TestFloatExpressionEQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.EQ(table2ColFloat), "(table1.col_float = table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.EQ(Float(2.11)), "(table1.col_float = $1)", float64(2.11))
}
func TestFloatExpressionNOT_EQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.NOT_EQ(table2ColFloat), "(table1.col_float != table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.NOT_EQ(Float(2.11)), "(table1.col_float != $1)", float64(2.11))
}
func TestFloatExpressionIS_DISTINCT_FROM(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.IS_DISTINCT_FROM(table2ColFloat), "(table1.col_float IS DISTINCT FROM table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.IS_DISTINCT_FROM(Float(2.11)), "(table1.col_float IS DISTINCT FROM $1)", float64(2.11))
}
func TestFloatExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.IS_NOT_DISTINCT_FROM(table2ColFloat), "(table1.col_float IS NOT DISTINCT FROM table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.IS_NOT_DISTINCT_FROM(Float(2.11)), "(table1.col_float IS NOT DISTINCT FROM $1)", float64(2.11))
}
func TestFloatExpressionGT(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.GT(table2ColFloat), "(table1.col_float > table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.GT(Float(2.11)), "(table1.col_float > $1)", float64(2.11))
}
func TestFloatExpressionGT_EQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.GT_EQ(table2ColFloat), "(table1.col_float >= table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.GT_EQ(Float(2.11)), "(table1.col_float >= $1)", float64(2.11))
}
func TestFloatExpressionLT(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.LT(table2ColFloat), "(table1.col_float < table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.LT(Float(2.11)), "(table1.col_float < $1)", float64(2.11))
}
func TestFloatExpressionLT_EQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.LT_EQ(table2ColFloat), "(table1.col_float <= table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.LT_EQ(Float(2.11)), "(table1.col_float <= $1)", float64(2.11))
}
func TestFloatExpressionADD(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.ADD(table2ColFloat), "(table1.col_float + table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.ADD(Float(2.11)), "(table1.col_float + $1)", float64(2.11))
}
func TestFloatExpressionSUB(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.SUB(table2ColFloat), "(table1.col_float - table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.SUB(Float(2.11)), "(table1.col_float - $1)", float64(2.11))
}
func TestFloatExpressionMUL(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.MUL(table2ColFloat), "(table1.col_float * table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.MUL(Float(2.11)), "(table1.col_float * $1)", float64(2.11))
}
func TestFloatExpressionDIV(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.DIV(table2ColFloat), "(table1.col_float / table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.DIV(Float(2.11)), "(table1.col_float / $1)", float64(2.11))
AssertMySQLClauseSerialize(t, table1ColFloat.DIV(table2ColFloat), "(table1.col_float / table2.col_float)")
AssertMySQLClauseSerialize(t, table1ColFloat.DIV(Float(2.11)), "(table1.col_float / ?)", float64(2.11))
}
func TestFloatExpressionMOD(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.MOD(table2ColFloat), "(table1.col_float % table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.MOD(Float(2.11)), "(table1.col_float % $1)", float64(2.11))
}
func TestFloatExpressionPOW(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColFloat.POW(table2ColFloat), "POW(table1.col_float, table2.col_float)")
AssertPostgreClauseSerialize(t, table1ColFloat.POW(Float(2.11)), "POW(table1.col_float, $1)", float64(2.11))
}
func TestFloatExp(t *testing.T) {
AssertPostgreClauseSerialize(t, FloatExp(table1ColInt), "table1.col_int")
AssertPostgreClauseSerialize(t, FloatExp(table1ColInt.ADD(table3ColInt)), "(table1.col_int + table3.col_int)")
AssertPostgreClauseSerialize(t, FloatExp(table1ColInt.ADD(table3ColInt)).ADD(Float(11.11)),
"((table1.col_int + table3.col_int) + $1)", float64(11.11))
}

View file

@ -1,162 +0,0 @@
package jet
import (
"testing"
)
func TestFuncAVG(t *testing.T) {
AssertPostgreClauseSerialize(t, AVG(table1ColFloat), "AVG(table1.col_float)")
AssertPostgreClauseSerialize(t, AVG(table1ColInt), "AVG(table1.col_int)")
}
func TestFuncBIT_AND(t *testing.T) {
AssertPostgreClauseSerialize(t, BIT_AND(table1ColInt), "BIT_AND(table1.col_int)")
}
func TestFuncBIT_OR(t *testing.T) {
AssertPostgreClauseSerialize(t, BIT_OR(table1ColInt), "BIT_OR(table1.col_int)")
}
func TestFuncBOOL_AND(t *testing.T) {
AssertPostgreClauseSerialize(t, BOOL_AND(table1ColBool), "BOOL_AND(table1.col_bool)")
}
func TestFuncBOOL_OR(t *testing.T) {
AssertPostgreClauseSerialize(t, BOOL_OR(table1ColBool), "BOOL_OR(table1.col_bool)")
}
func TestFuncEVERY(t *testing.T) {
AssertPostgreClauseSerialize(t, EVERY(table1ColBool), "EVERY(table1.col_bool)")
}
func TestFuncMIN(t *testing.T) {
t.Run("float", func(t *testing.T) {
AssertPostgreClauseSerialize(t, MINf(table1ColFloat), "MIN(table1.col_float)")
})
t.Run("integer", func(t *testing.T) {
AssertPostgreClauseSerialize(t, MINi(table1ColInt), "MIN(table1.col_int)")
})
}
func TestFuncMAX(t *testing.T) {
t.Run("float", func(t *testing.T) {
AssertPostgreClauseSerialize(t, MAXf(table1ColFloat), "MAX(table1.col_float)")
AssertPostgreClauseSerialize(t, MAXf(Float(11.2222)), "MAX($1)", float64(11.2222))
})
t.Run("integer", func(t *testing.T) {
AssertPostgreClauseSerialize(t, MAXi(table1ColInt), "MAX(table1.col_int)")
AssertPostgreClauseSerialize(t, MAXi(Int(11)), "MAX($1)", int64(11))
})
}
func TestFuncSUM(t *testing.T) {
t.Run("float", func(t *testing.T) {
AssertPostgreClauseSerialize(t, SUMf(table1ColFloat), "SUM(table1.col_float)")
AssertPostgreClauseSerialize(t, SUMf(Float(11.2222)), "SUM($1)", float64(11.2222))
})
t.Run("integer", func(t *testing.T) {
AssertPostgreClauseSerialize(t, SUMi(table1ColInt), "SUM(table1.col_int)")
AssertPostgreClauseSerialize(t, SUMi(Int(11)), "SUM($1)", int64(11))
})
}
func TestFuncCOUNT(t *testing.T) {
AssertPostgreClauseSerialize(t, COUNT(STAR), "COUNT(*)")
AssertPostgreClauseSerialize(t, COUNT(table1ColFloat), "COUNT(table1.col_float)")
AssertPostgreClauseSerialize(t, COUNT(Float(11.2222)), "COUNT($1)", float64(11.2222))
}
func TestFuncABS(t *testing.T) {
t.Run("float", func(t *testing.T) {
AssertPostgreClauseSerialize(t, ABSf(table1ColFloat), "ABS(table1.col_float)")
AssertPostgreClauseSerialize(t, ABSf(Float(11.2222)), "ABS($1)", float64(11.2222))
})
t.Run("integer", func(t *testing.T) {
AssertPostgreClauseSerialize(t, ABSi(table1ColInt), "ABS(table1.col_int)")
AssertPostgreClauseSerialize(t, ABSi(Int(11)), "ABS($1)", int64(11))
})
}
func TestFuncSQRT(t *testing.T) {
AssertPostgreClauseSerialize(t, SQRT(table1ColFloat), "SQRT(table1.col_float)")
AssertPostgreClauseSerialize(t, SQRT(Float(11.2222)), "SQRT($1)", float64(11.2222))
AssertPostgreClauseSerialize(t, SQRT(table1ColInt), "SQRT(table1.col_int)")
AssertPostgreClauseSerialize(t, SQRT(Int(11)), "SQRT($1)", int64(11))
}
func TestFuncCBRT(t *testing.T) {
AssertPostgreClauseSerialize(t, CBRT(table1ColFloat), "CBRT(table1.col_float)")
AssertPostgreClauseSerialize(t, CBRT(Float(11.2222)), "CBRT($1)", float64(11.2222))
AssertPostgreClauseSerialize(t, CBRT(table1ColInt), "CBRT(table1.col_int)")
AssertPostgreClauseSerialize(t, CBRT(Int(11)), "CBRT($1)", int64(11))
}
func TestFuncCEIL(t *testing.T) {
AssertPostgreClauseSerialize(t, CEIL(table1ColFloat), "CEIL(table1.col_float)")
AssertPostgreClauseSerialize(t, CEIL(Float(11.2222)), "CEIL($1)", float64(11.2222))
}
func TestFuncFLOOR(t *testing.T) {
AssertPostgreClauseSerialize(t, FLOOR(table1ColFloat), "FLOOR(table1.col_float)")
AssertPostgreClauseSerialize(t, FLOOR(Float(11.2222)), "FLOOR($1)", float64(11.2222))
}
func TestFuncROUND(t *testing.T) {
AssertPostgreClauseSerialize(t, ROUND(table1ColFloat), "ROUND(table1.col_float)")
AssertPostgreClauseSerialize(t, ROUND(Float(11.2222)), "ROUND($1)", float64(11.2222))
AssertPostgreClauseSerialize(t, ROUND(table1ColFloat, Int(2)), "ROUND(table1.col_float, $1)", int64(2))
AssertPostgreClauseSerialize(t, ROUND(Float(11.2222), Int(1)), "ROUND($1, $2)", float64(11.2222), int64(1))
}
func TestFuncSIGN(t *testing.T) {
AssertPostgreClauseSerialize(t, SIGN(table1ColFloat), "SIGN(table1.col_float)")
AssertPostgreClauseSerialize(t, SIGN(Float(11.2222)), "SIGN($1)", float64(11.2222))
}
func TestFuncTRUNC(t *testing.T) {
AssertPostgreClauseSerialize(t, TRUNC(table1ColFloat), "TRUNC(table1.col_float)")
AssertPostgreClauseSerialize(t, TRUNC(Float(11.2222)), "TRUNC($1)", float64(11.2222))
AssertPostgreClauseSerialize(t, TRUNC(table1ColFloat, Int(2)), "TRUNC(table1.col_float, $1)", int64(2))
AssertPostgreClauseSerialize(t, TRUNC(Float(11.2222), Int(1)), "TRUNC($1, $2)", float64(11.2222), int64(1))
}
func TestFuncLN(t *testing.T) {
AssertPostgreClauseSerialize(t, LN(table1ColFloat), "LN(table1.col_float)")
AssertPostgreClauseSerialize(t, LN(Float(11.2222)), "LN($1)", float64(11.2222))
}
func TestFuncLOG(t *testing.T) {
AssertPostgreClauseSerialize(t, LOG(table1ColFloat), "LOG(table1.col_float)")
AssertPostgreClauseSerialize(t, LOG(Float(11.2222)), "LOG($1)", float64(11.2222))
}
func TestFuncCOALESCE(t *testing.T) {
AssertPostgreClauseSerialize(t, COALESCE(table1ColFloat), "COALESCE(table1.col_float)")
AssertPostgreClauseSerialize(t, COALESCE(Float(11.2222), NULL, String("str")), "COALESCE($1, NULL, $2)", float64(11.2222), "str")
}
func TestFuncNULLIF(t *testing.T) {
AssertPostgreClauseSerialize(t, NULLIF(table1ColFloat, table2ColInt), "NULLIF(table1.col_float, table2.col_int)")
AssertPostgreClauseSerialize(t, NULLIF(Float(11.2222), NULL), "NULLIF($1, NULL)", float64(11.2222))
}
func TestFuncGREATEST(t *testing.T) {
AssertPostgreClauseSerialize(t, GREATEST(table1ColFloat), "GREATEST(table1.col_float)")
AssertPostgreClauseSerialize(t, GREATEST(Float(11.2222), NULL, String("str")), "GREATEST($1, NULL, $2)", float64(11.2222), "str")
}
func TestFuncLEAST(t *testing.T) {
AssertPostgreClauseSerialize(t, LEAST(table1ColFloat), "LEAST(table1.col_float)")
AssertPostgreClauseSerialize(t, LEAST(Float(11.2222), NULL, String("str")), "LEAST($1, NULL, $2)", float64(11.2222), "str")
}
func TestTO_ASCII(t *testing.T) {
AssertPostgreClauseSerialize(t, TO_ASCII(String("Karel")), `TO_ASCII($1)`, "Karel")
AssertPostgreClauseSerialize(t, TO_ASCII(String("Karel")), `TO_ASCII($1)`, "Karel")
}

View file

@ -3,8 +3,8 @@ package template
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"github.com/go-jet/jet"
"github.com/go-jet/jet/generator/internal/metadata" "github.com/go-jet/jet/generator/internal/metadata"
"github.com/go-jet/jet/internal/jet"
"github.com/go-jet/jet/internal/utils" "github.com/go-jet/jet/internal/utils"
"path/filepath" "path/filepath"
"text/template" "text/template"
@ -93,7 +93,7 @@ func generate(dirPath, packageName string, template string, metaDataList []metad
} }
// GenerateTemplate generates template with template text and template data. // GenerateTemplate generates template with template text and template data.
func GenerateTemplate(templateText string, templateData interface{}, dialect jet.Dialect) ([]byte, error) { func GenerateTemplate(templateText string, templateData interface{}, dialect1 jet.Dialect) ([]byte, error) {
t, err := template.New("sqlBuilderTableTemplate").Funcs(template.FuncMap{ t, err := template.New("sqlBuilderTableTemplate").Funcs(template.FuncMap{
"ToGoIdentifier": utils.ToGoIdentifier, "ToGoIdentifier": utils.ToGoIdentifier,
@ -101,7 +101,7 @@ func GenerateTemplate(templateText string, templateData interface{}, dialect jet
return time.Now().Format(time.RFC850) return time.Now().Format(time.RFC850)
}, },
"dialect": func() jet.Dialect { "dialect": func() jet.Dialect {
return dialect return dialect1
}, },
}).Parse(templateText) }).Parse(templateText)

View file

@ -21,22 +21,21 @@ var tableSQLBuilderTemplate = `
package table package table
import ( import (
"github.com/go-jet/jet"
"github.com/go-jet/jet/{{dialect.PackageName}}" "github.com/go-jet/jet/{{dialect.PackageName}}"
) )
var {{ToGoIdentifier .Name}} = new{{.GoStructName}}() var {{ToGoIdentifier .Name}} = new{{.GoStructName}}()
type {{.GoStructName}} struct { type {{.GoStructName}} struct {
jet.Table {{dialect.PackageName}}.Table
//Columns //Columns
{{- range .Columns}} {{- range .Columns}}
{{ToGoIdentifier .Name}} {{dialect.PackageName}}.Column{{.SqlBuilderColumnType}} {{ToGoIdentifier .Name}} {{dialect.PackageName}}.Column{{.SqlBuilderColumnType}}
{{- end}} {{- end}}
AllColumns jet.ColumnList AllColumns {{dialect.PackageName}}.IColumnList
MutableColumns jet.ColumnList MutableColumns {{dialect.PackageName}}.IColumnList
} }
// creates new {{.GoStructName}} with assigned alias // creates new {{.GoStructName}} with assigned alias
@ -56,15 +55,15 @@ func new{{.GoStructName}}() *{{.GoStructName}} {
) )
return &{{.GoStructName}}{ return &{{.GoStructName}}{
Table: jet.NewTable(jet.{{dialect.Name}}, "{{.SchemaName}}", "{{.Name}}", {{template "column-list" .Columns}}), Table: {{dialect.PackageName}}.NewTable("{{.SchemaName}}", "{{.Name}}", {{template "column-list" .Columns}}),
//Columns //Columns
{{- range .Columns}} {{- range .Columns}}
{{ToGoIdentifier .Name}}: {{ToGoIdentifier .Name}}Column, {{ToGoIdentifier .Name}}: {{ToGoIdentifier .Name}}Column,
{{- end}} {{- end}}
AllColumns: jet.ColumnList{ {{template "column-list" .Columns}} }, AllColumns: {{dialect.PackageName}}.ColumnList( {{template "column-list" .Columns}} ),
MutableColumns: jet.ColumnList{ {{template "column-list" .MutableColumns}} }, MutableColumns: {{dialect.PackageName}}.ColumnList( {{template "column-list" .MutableColumns}} ),
} }
} }
@ -91,15 +90,15 @@ type {{ToGoIdentifier .Name}} struct {
` `
var enumSQLBuilderTemplate = `package enum var enumSQLBuilderTemplate = `package enum
import "github.com/go-jet/jet" import "github.com/go-jet/jet/postgres"
var {{ToGoIdentifier $.Name}} = &struct { var {{ToGoIdentifier $.Name}} = &struct {
{{- range $index, $element := .Values}} {{- range $index, $element := .Values}}
{{ToGoIdentifier $element}} jet.StringExpression {{ToGoIdentifier $element}} postgres.StringExpression
{{- end}} {{- end}}
} { } {
{{- range $index, $element := .Values}} {{- range $index, $element := .Values}}
{{ToGoIdentifier $element}}: jet.NewEnumValue("{{$element}}"), {{ToGoIdentifier $element}}: postgres.NewEnumValue("{{$element}}"),
{{- end}} {{- end}}
} }
` `

View file

@ -3,9 +3,9 @@ package mysql
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/go-jet/jet"
"github.com/go-jet/jet/generator/internal/metadata" "github.com/go-jet/jet/generator/internal/metadata"
"github.com/go-jet/jet/generator/internal/template" "github.com/go-jet/jet/generator/internal/template"
"github.com/go-jet/jet/mysql"
"path" "path"
) )
@ -38,7 +38,7 @@ func Generate(destDir string, dbConn DBConnection) error {
genPath := path.Join(destDir, dbConn.DBName) genPath := path.Join(destDir, dbConn.DBName)
err = template.GenerateFiles(genPath, dbInfo.TableInfos, dbInfo.EnumInfos, jet.MySQL) err = template.GenerateFiles(genPath, dbInfo.TableInfos, dbInfo.EnumInfos, mysql.Dialect)
if err != nil { if err != nil {
return err return err

View file

@ -3,9 +3,9 @@ package postgres
import ( import (
"database/sql" "database/sql"
"fmt" "fmt"
"github.com/go-jet/jet"
"github.com/go-jet/jet/generator/internal/metadata" "github.com/go-jet/jet/generator/internal/metadata"
"github.com/go-jet/jet/generator/internal/template" "github.com/go-jet/jet/generator/internal/template"
"github.com/go-jet/jet/postgres"
"path" "path"
"strconv" "strconv"
) )
@ -42,7 +42,7 @@ func Generate(destDir string, dbConn DBConnection) error {
genPath := path.Join(destDir, dbConn.DBName, dbConn.SchemaName) genPath := path.Join(destDir, dbConn.DBName, dbConn.SchemaName)
err = template.GenerateFiles(genPath, schemaInfo.TableInfos, schemaInfo.EnumInfos, jet.PostgreSQL) err = template.GenerateFiles(genPath, schemaInfo.TableInfos, schemaInfo.EnumInfos, postgres.Dialect)
if err != nil { if err != nil {
return err return err

View file

@ -1,5 +0,0 @@
package jet
type groupByClause interface {
serializeForGroupBy(statement statementType, out *sqlBuilder) error
}

View file

@ -1,118 +0,0 @@
package jet
import (
"testing"
)
func TestIntegerExpressionEQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.EQ(table2ColInt), "(table1.col_int = table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.EQ(Int(11)), "(table1.col_int = $1)", int64(11))
}
func TestIntegerExpressionNOT_EQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.NOT_EQ(table2ColInt), "(table1.col_int != table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.NOT_EQ(Int(11)), "(table1.col_int != $1)", int64(11))
}
func TestIntegerExpressionGT(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.GT(table2ColInt), "(table1.col_int > table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.GT(Int(11)), "(table1.col_int > $1)", int64(11))
}
func TestIntegerExpressionGT_EQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.GT_EQ(table2ColInt), "(table1.col_int >= table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.GT_EQ(Int(11)), "(table1.col_int >= $1)", int64(11))
}
func TestIntegerExpressionLT(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.LT(table2ColInt), "(table1.col_int < table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.LT(Int(11)), "(table1.col_int < $1)", int64(11))
}
func TestIntegerExpressionLT_EQ(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.LT_EQ(table2ColInt), "(table1.col_int <= table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.LT_EQ(Int(11)), "(table1.col_int <= $1)", int64(11))
}
func TestIntegerExpressionADD(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.ADD(table2ColInt), "(table1.col_int + table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.ADD(Int(11)), "(table1.col_int + $1)", int64(11))
}
func TestIntegerExpressionSUB(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.SUB(table2ColInt), "(table1.col_int - table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.SUB(Int(11)), "(table1.col_int - $1)", int64(11))
}
func TestIntegerExpressionMUL(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.MUL(table2ColInt), "(table1.col_int * table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.MUL(Int(11)), "(table1.col_int * $1)", int64(11))
}
func TestIntegerExpressionDIV(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.DIV(table2ColInt), "(table1.col_int / table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.DIV(Int(11)), "(table1.col_int / $1)", int64(11))
AssertMySQLClauseSerialize(t, table1ColInt.DIV(table2ColInt), "(table1.col_int DIV table2.col_int)")
AssertMySQLClauseSerialize(t, table1ColInt.DIV(Int(11)), "(table1.col_int DIV ?)", int64(11))
}
func TestIntExpressionMOD(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.MOD(table2ColInt), "(table1.col_int % table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.MOD(Int(11)), "(table1.col_int % $1)", int64(11))
}
func TestIntExpressionPOW(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.POW(table2ColInt), "POW(table1.col_int, table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.POW(Int(11)), "POW(table1.col_int, $1)", int64(11))
}
func TestIntExpressionBIT_NOT(t *testing.T) {
AssertPostgreClauseSerialize(t, BIT_NOT(table2ColInt), "(~ table2.col_int)")
AssertPostgreClauseSerialize(t, BIT_NOT(Int(11)), "(~ $1)", int64(11))
}
func TestIntExpressionBIT_AND(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.BIT_AND(table2ColInt), "(table1.col_int & table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.BIT_AND(Int(11)), "(table1.col_int & $1)", int64(11))
AssertMySQLClauseSerialize(t, table1ColInt.BIT_AND(table2ColInt), "(table1.col_int & table2.col_int)")
AssertMySQLClauseSerialize(t, table1ColInt.BIT_AND(Int(11)), "(table1.col_int & ?)", int64(11))
}
func TestIntExpressionBIT_OR(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.BIT_OR(table2ColInt), "(table1.col_int | table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.BIT_OR(Int(11)), "(table1.col_int | $1)", int64(11))
AssertMySQLClauseSerialize(t, table1ColInt.BIT_OR(table2ColInt), "(table1.col_int | table2.col_int)")
AssertMySQLClauseSerialize(t, table1ColInt.BIT_OR(Int(11)), "(table1.col_int | ?)", int64(11))
}
func TestIntExpressionBIT_XOR(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.BIT_XOR(table2ColInt), "(table1.col_int # table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.BIT_XOR(Int(11)), "(table1.col_int # $1)", int64(11))
AssertMySQLClauseSerialize(t, table1ColInt.BIT_XOR(table2ColInt), "(table1.col_int ^ table2.col_int)")
AssertMySQLClauseSerialize(t, table1ColInt.BIT_XOR(Int(11)), "(table1.col_int ^ ?)", int64(11))
}
func TestIntExpressionBIT_SHIFT_LEFT(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.BIT_SHIFT_LEFT(table2ColInt), "(table1.col_int << table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.BIT_SHIFT_LEFT(Int(11)), "(table1.col_int << $1)", int64(11))
}
func TestIntExpressionBIT_SHIFT_RIGHT(t *testing.T) {
AssertPostgreClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(table2ColInt), "(table1.col_int >> table2.col_int)")
AssertPostgreClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(Int(11)), "(table1.col_int >> $1)", int64(11))
}
func TestIntExpressionIntExp(t *testing.T) {
AssertPostgreClauseSerialize(t, IntExp(table1ColFloat), "table1.col_float")
AssertPostgreClauseSerialize(t, IntExp(table1ColFloat.ADD(table2ColFloat)).ADD(Int(11)),
"((table1.col_float + table2.col_float) + $1)", int64(11))
}
func TestIntExpression_MINUSi(t *testing.T) {
AssertPostgreClauseSerialize(t, MINUSi(table2ColInt), "(- table2.col_int)")
AssertPostgreClauseSerialize(t, MINUSi(Int(3)), "(- $1)", int64(3))
}

View file

@ -5,14 +5,14 @@ type alias struct {
alias string alias string
} }
func newAlias(expression Expression, aliasName string) projection { func newAlias(expression Expression, aliasName string) Projection {
return &alias{ return &alias{
expression: expression, expression: expression,
alias: aliasName, alias: aliasName,
} }
} }
func (a *alias) from(subQuery SelectTable) projection { func (a *alias) fromImpl(subQuery SelectTable) Projection {
column := newColumn(a.alias, "", nil) column := newColumn(a.alias, "", nil)
column.parent = &column column.parent = &column
column.subQuery = subQuery column.subQuery = subQuery
@ -20,14 +20,14 @@ func (a *alias) from(subQuery SelectTable) projection {
return &column return &column
} }
func (a *alias) serializeForProjection(statement statementType, out *sqlBuilder) error { func (a *alias) serializeForProjection(statement StatementType, out *SqlBuilder) error {
err := a.expression.serialize(statement, out) err := a.expression.serialize(statement, out)
if err != nil { if err != nil {
return err return err
} }
out.writeString("AS") out.WriteString("AS")
out.writeAlias(a.alias) out.writeAlias(a.alias)
return nil return nil

View file

@ -0,0 +1,90 @@
package jet
import (
"testing"
)
func TestBoolExpressionEQ(t *testing.T) {
assertClauseSerializeErr(t, table1ColBool.EQ(nil), "jet: nil rhs")
assertClauseSerialize(t, table1ColBool.EQ(table2ColBool), "(table1.col_bool = table2.col_bool)")
}
func TestBoolExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColBool.NOT_EQ(table2ColBool), "(table1.col_bool != table2.col_bool)")
assertClauseSerialize(t, table1ColBool.NOT_EQ(Bool(true)), "(table1.col_bool != TRUE)")
}
func TestBoolExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(table2ColBool), "(table1.col_bool IS DISTINCT FROM table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(Bool(false)), "(table1.col_bool IS DISTINCT FROM FALSE)")
}
func TestBoolExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(table2ColBool), "(table1.col_bool IS NOT DISTINCT FROM table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(Bool(false)), "(table1.col_bool IS NOT DISTINCT FROM FALSE)")
}
func TestBoolExpressionIS_TRUE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_TRUE(), "table1.col_bool IS TRUE")
assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE(),
`(2 = table1.col_int) IS TRUE`)
assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE().AND(Int(4).EQ(table2ColInt)),
`((2 = table1.col_int) IS TRUE AND (4 = table2.col_int))`)
}
func TestBoolExpressionIS_NOT_TRUE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_TRUE(), "table1.col_bool IS NOT TRUE")
}
func TestBoolExpressionIS_FALSE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_FALSE(), "table1.col_bool IS FALSE")
}
func TestBoolExpressionIS_NOT_FALSE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_FALSE(), "table1.col_bool IS NOT FALSE")
}
func TestBoolExpressionIS_UNKNOWN(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_UNKNOWN(), "table1.col_bool IS UNKNOWN")
}
func TestBoolExpressionIS_NOT_UNKNOWN(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_UNKNOWN(), "table1.col_bool IS NOT UNKNOWN")
}
func TestBinaryBoolExpression(t *testing.T) {
boolExpression := Int(2).EQ(Int(3))
assertClauseSerialize(t, boolExpression, "(2 = 3)")
assertProjectionSerialize(t, boolExpression, "2 = 3")
assertProjectionSerialize(t, boolExpression.AS("alias_eq_expression"),
`(2 = 3) AS "alias_eq_expression"`)
assertClauseSerialize(t, boolExpression.AND(Int(4).EQ(Int(5))),
"((2 = 3) AND (4 = 5))")
assertClauseSerialize(t, boolExpression.OR(Int(4).EQ(Int(5))),
"((2 = 3) OR (4 = 5))")
}
func TestBoolLiteral(t *testing.T) {
assertClauseSerialize(t, Bool(true), "TRUE", true)
assertClauseSerialize(t, Bool(false), "FALSE", false)
}
func TestExists(t *testing.T) {
assertClauseSerialize(t, EXISTS(
table2.
SELECT(Int(1)).
WHERE(table1Col1.EQ(table2Col3)),
),
`(EXISTS (
SELECT 1
FROM db.table2
WHERE table1.col1 = table2.col3
))`)
}
func TestBoolExp(t *testing.T) {
assertClauseSerialize(t, BoolExp(String("true")), "'true'")
assertClauseSerialize(t, BoolExp(String("true")).IS_TRUE(), "'true' IS TRUE")
}

View file

@ -71,23 +71,23 @@ func (b *castExpression) accept(visitor visitor) {
b.expression.accept(visitor) b.expression.accept(visitor)
} }
func (b *castExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (b *castExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
expression := b.expression expression := b.expression
castType := b.cast castType := b.cast
if castOverride := out.dialect.CastOverride; castOverride != nil { if castOverride := out.Dialect.CastOverride(); castOverride != nil {
return castOverride(expression, castType)(statement, out, options...) return castOverride(expression, castType)(statement, out, options...)
} }
out.writeString("CAST(") out.WriteString("CAST(")
err := expression.serialize(statement, out, options...) err := expression.serialize(statement, out, options...)
if err != nil { if err != nil {
return err return err
} }
out.writeString("AS") out.WriteString("AS")
out.writeString(castType + ")") out.WriteString(castType + ")")
return err return err
} }

View file

@ -9,17 +9,21 @@ import (
"time" "time"
) )
type serializeOption int type SerializeOption int
const ( const (
noWrap serializeOption = iota noWrap SerializeOption = iota
) )
type clause interface { type Clause interface {
serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error
} }
func contains(options []serializeOption, option serializeOption) bool { func Serialize(exp Clause, statementType StatementType, out *SqlBuilder, options ...SerializeOption) error {
return exp.serialize(statementType, out, options...)
}
func contains(options []SerializeOption, option SerializeOption) bool {
for _, opt := range options { for _, opt := range options {
if opt == option { if opt == option {
return true return true
@ -29,33 +33,37 @@ func contains(options []serializeOption, option serializeOption) bool {
return false return false
} }
type sqlBuilder struct { type SqlBuilder struct {
dialect Dialect Dialect Dialect
buff bytes.Buffer Buff bytes.Buffer
args []interface{} Args []interface{}
lastChar byte lastChar byte
ident int ident int
} }
type statementType string func (s *SqlBuilder) DebugSQL() string {
return queryStringToDebugString(s.Buff.String(), s.Args, s.Dialect)
}
type StatementType string
const ( const (
selectStatement statementType = "SELECT" SelectStatementType StatementType = "SELECT"
insertStatement statementType = "INSERT" InsertStatementType StatementType = "INSERT"
updateStatement statementType = "UPDATE" UpdateStatementType StatementType = "UPDATE"
deleteStatement statementType = "DELETE" DeleteStatementType StatementType = "DELETE"
setStatement statementType = "SET" SetStatementType StatementType = "SET"
lockStatement statementType = "LOCK" LockStatementType StatementType = "LOCK"
) )
const defaultIdent = 5 const defaultIdent = 5
func (q *sqlBuilder) increaseIdent() { func (q *SqlBuilder) increaseIdent() {
q.ident += defaultIdent q.ident += defaultIdent
} }
func (q *sqlBuilder) decreaseIdent() { func (q *SqlBuilder) decreaseIdent() {
if q.ident < defaultIdent { if q.ident < defaultIdent {
q.ident = 0 q.ident = 0
} }
@ -63,16 +71,16 @@ func (q *sqlBuilder) decreaseIdent() {
q.ident -= defaultIdent q.ident -= defaultIdent
} }
func (q *sqlBuilder) writeProjections(statement statementType, projections []projection) error { func (q *SqlBuilder) writeProjections(statement StatementType, projections []Projection) error {
q.increaseIdent() q.increaseIdent()
err := serializeProjectionList(statement, projections, q) err := SerializeProjectionList(statement, projections, q)
q.decreaseIdent() q.decreaseIdent()
return err return err
} }
func (q *sqlBuilder) writeFrom(statement statementType, table ReadableTable) error { func (q *SqlBuilder) writeFrom(statement StatementType, table ReadableTable) error {
q.newLine() q.newLine()
q.writeString("FROM") q.WriteString("FROM")
q.increaseIdent() q.increaseIdent()
err := table.serialize(statement, q) err := table.serialize(statement, q)
@ -81,9 +89,9 @@ func (q *sqlBuilder) writeFrom(statement statementType, table ReadableTable) err
return err return err
} }
func (q *sqlBuilder) writeWhere(statement statementType, where Expression) error { func (q *SqlBuilder) writeWhere(statement StatementType, where Expression) error {
q.newLine() q.newLine()
q.writeString("WHERE") q.WriteString("WHERE")
q.increaseIdent() q.increaseIdent()
err := where.serialize(statement, q, noWrap) err := where.serialize(statement, q, noWrap)
@ -92,9 +100,9 @@ func (q *sqlBuilder) writeWhere(statement statementType, where Expression) error
return err return err
} }
func (q *sqlBuilder) writeGroupBy(statement statementType, groupBy []groupByClause) error { func (q *SqlBuilder) writeGroupBy(statement StatementType, groupBy []groupByClause) error {
q.newLine() q.newLine()
q.writeString("GROUP BY") q.WriteString("GROUP BY")
q.increaseIdent() q.increaseIdent()
err := serializeGroupByClauseList(statement, groupBy, q) err := serializeGroupByClauseList(statement, groupBy, q)
@ -103,9 +111,9 @@ func (q *sqlBuilder) writeGroupBy(statement statementType, groupBy []groupByClau
return err return err
} }
func (q *sqlBuilder) writeOrderBy(statement statementType, orderBy []orderByClause) error { func (q *SqlBuilder) writeOrderBy(statement StatementType, orderBy []orderByClause) error {
q.newLine() q.newLine()
q.writeString("ORDER BY") q.WriteString("ORDER BY")
q.increaseIdent() q.increaseIdent()
err := serializeOrderByClauseList(statement, orderBy, q) err := serializeOrderByClauseList(statement, orderBy, q)
@ -114,9 +122,9 @@ func (q *sqlBuilder) writeOrderBy(statement statementType, orderBy []orderByClau
return err return err
} }
func (q *sqlBuilder) writeHaving(statement statementType, having Expression) error { func (q *SqlBuilder) writeHaving(statement StatementType, having Expression) error {
q.newLine() q.newLine()
q.writeString("HAVING") q.WriteString("HAVING")
q.increaseIdent() q.increaseIdent()
err := having.serialize(statement, q, noWrap) err := having.serialize(statement, q, noWrap)
@ -125,37 +133,37 @@ func (q *sqlBuilder) writeHaving(statement statementType, having Expression) err
return err return err
} }
func (q *sqlBuilder) writeReturning(statement statementType, returning []projection) error { func (q *SqlBuilder) writeReturning(statement StatementType, returning []Projection) error {
if len(returning) == 0 { if len(returning) == 0 {
return nil return nil
} }
if !q.dialect.SupportsReturning { if !q.Dialect.SupportsReturning() {
panic("jet: " + q.dialect.Name + " dialect does not support RETURNING.") panic("jet: " + q.Dialect.Name() + " dialect does not support RETURNING.")
} }
q.newLine() q.newLine()
q.writeString("RETURNING") q.WriteString("RETURNING")
q.increaseIdent() q.increaseIdent()
return q.writeProjections(statement, returning) return q.writeProjections(statement, returning)
} }
func (q *sqlBuilder) newLine() { func (q *SqlBuilder) newLine() {
q.write([]byte{'\n'}) q.write([]byte{'\n'})
q.write(bytes.Repeat([]byte{' '}, q.ident)) q.write(bytes.Repeat([]byte{' '}, q.ident))
} }
func (q *sqlBuilder) write(data []byte) { func (q *SqlBuilder) write(data []byte) {
if len(data) == 0 { if len(data) == 0 {
return return
} }
if !isPreSeparator(q.lastChar) && !isPostSeparator(data[0]) && q.buff.Len() > 0 { if !isPreSeparator(q.lastChar) && !isPostSeparator(data[0]) && q.Buff.Len() > 0 {
q.buff.WriteByte(' ') q.Buff.WriteByte(' ')
} }
q.buff.Write(data) q.Buff.Write(data)
q.lastChar = data[len(data)-1] q.lastChar = data[len(data)-1]
} }
@ -167,43 +175,43 @@ func isPostSeparator(b byte) bool {
return b == ' ' || b == '.' || b == ',' || b == ')' || b == '\n' || b == ':' return b == ' ' || b == '.' || b == ',' || b == ')' || b == '\n' || b == ':'
} }
func (q *sqlBuilder) writeAlias(str string) { func (q *SqlBuilder) writeAlias(str string) {
aliasQuoteChar := string(q.dialect.AliasQuoteChar) aliasQuoteChar := string(q.Dialect.AliasQuoteChar())
q.writeString(aliasQuoteChar + str + aliasQuoteChar) q.WriteString(aliasQuoteChar + str + aliasQuoteChar)
} }
func (q *sqlBuilder) writeString(str string) { func (q *SqlBuilder) WriteString(str string) {
q.write([]byte(str)) q.write([]byte(str))
} }
func (q *sqlBuilder) writeIdentifier(name string, alwaysQuote ...bool) { func (q *SqlBuilder) writeIdentifier(name string, alwaysQuote ...bool) {
quoteWrap := name != strings.ToLower(name) || strings.ContainsAny(name, ". -") quoteWrap := name != strings.ToLower(name) || strings.ContainsAny(name, ". -")
if quoteWrap || len(alwaysQuote) > 0 { if quoteWrap || len(alwaysQuote) > 0 {
identQuoteChar := string(q.dialect.IdentifierQuoteChar) identQuoteChar := string(q.Dialect.IdentifierQuoteChar())
q.writeString(identQuoteChar + name + identQuoteChar) q.WriteString(identQuoteChar + name + identQuoteChar)
} else { } else {
q.writeString(name) q.WriteString(name)
} }
} }
func (q *sqlBuilder) writeByte(b byte) { func (q *SqlBuilder) writeByte(b byte) {
q.write([]byte{b}) q.write([]byte{b})
} }
func (q *sqlBuilder) finalize() (string, []interface{}) { func (q *SqlBuilder) finalize() (string, []interface{}) {
return q.buff.String() + ";\n", q.args return q.Buff.String() + ";\n", q.Args
} }
func (q *sqlBuilder) insertConstantArgument(arg interface{}) { func (q *SqlBuilder) insertConstantArgument(arg interface{}) {
q.writeString(argToString(arg)) q.WriteString(argToString(arg))
} }
func (q *sqlBuilder) insertParametrizedArgument(arg interface{}) { func (q *SqlBuilder) insertParametrizedArgument(arg interface{}) {
q.args = append(q.args, arg) q.Args = append(q.Args, arg)
argPlaceholder := q.dialect.ArgumentPlaceholder(len(q.args)) argPlaceholder := q.Dialect.ArgumentPlaceholder()(len(q.Args))
q.writeString(argPlaceholder) q.WriteString(argPlaceholder)
} }
func argToString(value interface{}) string { func argToString(value interface{}) string {

View file

@ -2,19 +2,19 @@
package jet package jet
type column interface { type IColumn interface {
Name() string Name() string
TableName() string TableName() string
setTableName(table string) SetTableName(table string)
setSubQuery(subQuery SelectTable) SetSubQuery(subQuery SelectTable)
defaultAlias() string DefaultAlias() string
} }
// Column is common column interface for all types of columns. // Column is common column interface for all types of columns.
type Column interface { type Column interface {
Expression Expression
column IColumn
} }
// The base type for real materialized columns. // The base type for real materialized columns.
@ -47,15 +47,15 @@ func (c *columnImpl) TableName() string {
return c.tableName return c.tableName
} }
func (c *columnImpl) setTableName(table string) { func (c *columnImpl) SetTableName(table string) {
c.tableName = table c.tableName = table
} }
func (c *columnImpl) setSubQuery(subQuery SelectTable) { func (c *columnImpl) SetSubQuery(subQuery SelectTable) {
c.subQuery = subQuery c.subQuery = subQuery
} }
func (c *columnImpl) defaultAlias() string { func (c *columnImpl) DefaultAlias() string {
if c.tableName != "" { if c.tableName != "" {
return c.tableName + "." + c.name return c.tableName + "." + c.name
} }
@ -63,10 +63,10 @@ func (c *columnImpl) defaultAlias() string {
return c.name return c.name
} }
func (c *columnImpl) serializeForOrderBy(statement statementType, out *sqlBuilder) error { func (c *columnImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) error {
if statement == setStatement { if statement == SetStatementType {
// set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause // set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause
out.writeAlias(c.defaultAlias()) //always quote out.writeAlias(c.DefaultAlias()) //always quote
return nil return nil
} }
@ -74,25 +74,25 @@ func (c *columnImpl) serializeForOrderBy(statement statementType, out *sqlBuilde
return c.serialize(statement, out) return c.serialize(statement, out)
} }
func (c columnImpl) serializeForProjection(statement statementType, out *sqlBuilder) error { func (c columnImpl) serializeForProjection(statement StatementType, out *SqlBuilder) error {
err := c.serialize(statement, out) err := c.serialize(statement, out)
if err != nil { if err != nil {
return err return err
} }
out.writeString("AS") out.WriteString("AS")
out.writeAlias(c.defaultAlias()) out.writeAlias(c.DefaultAlias())
return nil return nil
} }
func (c columnImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (c columnImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if c.subQuery != nil { if c.subQuery != nil {
out.writeIdentifier(c.subQuery.Alias()) out.writeIdentifier(c.subQuery.Alias())
out.writeByte('.') out.writeByte('.')
out.writeIdentifier(c.defaultAlias(), true) out.writeIdentifier(c.DefaultAlias(), true)
} else { } else {
if c.tableName != "" { if c.tableName != "" {
out.writeIdentifier(c.tableName) out.writeIdentifier(c.tableName)
@ -107,26 +107,38 @@ func (c columnImpl) serialize(statement statementType, out *sqlBuilder, options
//------------------------------------------------------// //------------------------------------------------------//
// ColumnList is redefined type to support list of columns as single projection type IColumnList interface {
type ColumnList []Column Projection
IColumn
// projection interface implementation Columns() []Column
func (cl ColumnList) isProjectionType() {} }
func (cl ColumnList) from(subQuery SelectTable) projection { func ColumnList(columns ...Column) IColumnList {
return columnListImpl(columns)
}
// ColumnList is redefined type to support list of columns as single Projection
type columnListImpl []Column
func (cl columnListImpl) Columns() []Column {
return cl
}
func (cl columnListImpl) fromImpl(subQuery SelectTable) Projection {
newProjectionList := ProjectionList{} newProjectionList := ProjectionList{}
for _, column := range cl { for _, column := range cl {
newProjectionList = append(newProjectionList, column.from(subQuery)) newProjectionList = append(newProjectionList, column.fromImpl(subQuery))
} }
return newProjectionList return newProjectionList
} }
func (cl ColumnList) serializeForProjection(statement statementType, out *sqlBuilder) error { func (cl columnListImpl) serializeForProjection(statement StatementType, out *SqlBuilder) error {
projections := columnListToProjectionList(cl) projections := ColumnListToProjectionList(cl)
err := serializeProjectionList(statement, projections, out) err := SerializeProjectionList(statement, projections, out)
if err != nil { if err != nil {
return err return err
@ -138,10 +150,10 @@ func (cl ColumnList) serializeForProjection(statement statementType, out *sqlBui
// dummy column interface implementation // dummy column interface implementation
// Name is placeholder for ColumnList to implement Column interface // Name is placeholder for ColumnList to implement Column interface
func (cl ColumnList) Name() string { return "" } func (cl columnListImpl) Name() string { return "" }
// TableName is placeholder for ColumnList to implement Column interface // TableName is placeholder for ColumnList to implement Column interface
func (cl ColumnList) TableName() string { return "" } func (cl columnListImpl) TableName() string { return "" }
func (cl ColumnList) setTableName(name string) {} func (cl columnListImpl) SetTableName(name string) {}
func (cl ColumnList) setSubQuery(subQuery SelectTable) {} func (cl columnListImpl) SetSubQuery(subQuery SelectTable) {}
func (cl ColumnList) defaultAlias() string { return "" } func (cl columnListImpl) DefaultAlias() string { return "" }

View file

@ -6,9 +6,9 @@ func TestColumn(t *testing.T) {
column := newColumn("col", "", nil) column := newColumn("col", "", nil)
column.expressionInterfaceImpl.parent = &column column.expressionInterfaceImpl.parent = &column
AssertPostgreClauseSerialize(t, column, "col") assertClauseSerialize(t, column, "col")
column.setTableName("table1") column.SetTableName("table1")
AssertPostgreClauseSerialize(t, column, "table1.col") assertClauseSerialize(t, column, "table1.col")
assertProjectionSerialize(t, &column, `table1.col AS "table1.col"`) assertProjectionSerialize(t, &column, `table1.col AS "table1.col"`)
assertProjectionSerialize(t, column.AS("alias1"), `table1.col AS "alias1"`) assertProjectionSerialize(t, column.AS("alias1"), `table1.col AS "alias1"`)
} }

View file

@ -3,7 +3,7 @@ package jet
// ColumnBool is interface for SQL boolean columns. // ColumnBool is interface for SQL boolean columns.
type ColumnBool interface { type ColumnBool interface {
BoolExpression BoolExpression
column IColumn
From(subQuery SelectTable) ColumnBool From(subQuery SelectTable) ColumnBool
} }
@ -14,16 +14,16 @@ type boolColumnImpl struct {
columnImpl columnImpl
} }
func (i *boolColumnImpl) from(subQuery SelectTable) projection { func (i *boolColumnImpl) fromImpl(subQuery SelectTable) Projection {
newBoolColumn := BoolColumn(i.name) newBoolColumn := BoolColumn(i.name)
newBoolColumn.setTableName(i.tableName) newBoolColumn.SetTableName(i.tableName)
newBoolColumn.setSubQuery(subQuery) newBoolColumn.SetSubQuery(subQuery)
return newBoolColumn return newBoolColumn
} }
func (i *boolColumnImpl) From(subQuery SelectTable) ColumnBool { func (i *boolColumnImpl) From(subQuery SelectTable) ColumnBool {
newBoolColumn := i.from(subQuery).(ColumnBool) newBoolColumn := i.fromImpl(subQuery).(ColumnBool)
return newBoolColumn return newBoolColumn
} }
@ -42,7 +42,7 @@ func BoolColumn(name string) ColumnBool {
// ColumnFloat is interface for SQL real, numeric, decimal or double precision column. // ColumnFloat is interface for SQL real, numeric, decimal or double precision column.
type ColumnFloat interface { type ColumnFloat interface {
FloatExpression FloatExpression
column IColumn
From(subQuery SelectTable) ColumnFloat From(subQuery SelectTable) ColumnFloat
} }
@ -52,16 +52,16 @@ type floatColumnImpl struct {
columnImpl columnImpl
} }
func (i *floatColumnImpl) from(subQuery SelectTable) projection { func (i *floatColumnImpl) fromImpl(subQuery SelectTable) Projection {
newFloatColumn := FloatColumn(i.name) newFloatColumn := FloatColumn(i.name)
newFloatColumn.setTableName(i.tableName) newFloatColumn.SetTableName(i.tableName)
newFloatColumn.setSubQuery(subQuery) newFloatColumn.SetSubQuery(subQuery)
return newFloatColumn return newFloatColumn
} }
func (i *floatColumnImpl) From(subQuery SelectTable) ColumnFloat { func (i *floatColumnImpl) From(subQuery SelectTable) ColumnFloat {
newFloatColumn := i.from(subQuery).(ColumnFloat) newFloatColumn := i.fromImpl(subQuery).(ColumnFloat)
return newFloatColumn return newFloatColumn
} }
@ -80,7 +80,7 @@ func FloatColumn(name string) ColumnFloat {
// ColumnInteger is interface for SQL smallint, integer, bigint columns. // ColumnInteger is interface for SQL smallint, integer, bigint columns.
type ColumnInteger interface { type ColumnInteger interface {
IntegerExpression IntegerExpression
column IColumn
From(subQuery SelectTable) ColumnInteger From(subQuery SelectTable) ColumnInteger
} }
@ -91,16 +91,16 @@ type integerColumnImpl struct {
columnImpl columnImpl
} }
func (i *integerColumnImpl) from(subQuery SelectTable) projection { func (i *integerColumnImpl) fromImpl(subQuery SelectTable) Projection {
newIntColumn := IntegerColumn(i.name) newIntColumn := IntegerColumn(i.name)
newIntColumn.setTableName(i.tableName) newIntColumn.SetTableName(i.tableName)
newIntColumn.setSubQuery(subQuery) newIntColumn.SetSubQuery(subQuery)
return newIntColumn return newIntColumn
} }
func (i *integerColumnImpl) From(subQuery SelectTable) ColumnInteger { func (i *integerColumnImpl) From(subQuery SelectTable) ColumnInteger {
return i.from(subQuery).(ColumnInteger) return i.fromImpl(subQuery).(ColumnInteger)
} }
// IntegerColumn creates named integer column. // IntegerColumn creates named integer column.
@ -118,7 +118,7 @@ func IntegerColumn(name string) ColumnInteger {
// bytea, uuid columns and enums types. // bytea, uuid columns and enums types.
type ColumnString interface { type ColumnString interface {
StringExpression StringExpression
column IColumn
From(subQuery SelectTable) ColumnString From(subQuery SelectTable) ColumnString
} }
@ -129,16 +129,16 @@ type stringColumnImpl struct {
columnImpl columnImpl
} }
func (i *stringColumnImpl) from(subQuery SelectTable) projection { func (i *stringColumnImpl) fromImpl(subQuery SelectTable) Projection {
newStrColumn := StringColumn(i.name) newStrColumn := StringColumn(i.name)
newStrColumn.setTableName(i.tableName) newStrColumn.SetTableName(i.tableName)
newStrColumn.setSubQuery(subQuery) newStrColumn.SetSubQuery(subQuery)
return newStrColumn return newStrColumn
} }
func (i *stringColumnImpl) From(subQuery SelectTable) ColumnString { func (i *stringColumnImpl) From(subQuery SelectTable) ColumnString {
return i.from(subQuery).(ColumnString) return i.fromImpl(subQuery).(ColumnString)
} }
// StringColumn creates named string column. // StringColumn creates named string column.
@ -155,7 +155,7 @@ func StringColumn(name string) ColumnString {
// ColumnTime is interface for SQL time column. // ColumnTime is interface for SQL time column.
type ColumnTime interface { type ColumnTime interface {
TimeExpression TimeExpression
column IColumn
From(subQuery SelectTable) ColumnTime From(subQuery SelectTable) ColumnTime
} }
@ -165,16 +165,16 @@ type timeColumnImpl struct {
columnImpl columnImpl
} }
func (i *timeColumnImpl) from(subQuery SelectTable) projection { func (i *timeColumnImpl) fromImpl(subQuery SelectTable) Projection {
newTimeColumn := TimeColumn(i.name) newTimeColumn := TimeColumn(i.name)
newTimeColumn.setTableName(i.tableName) newTimeColumn.SetTableName(i.tableName)
newTimeColumn.setSubQuery(subQuery) newTimeColumn.SetSubQuery(subQuery)
return newTimeColumn return newTimeColumn
} }
func (i *timeColumnImpl) From(subQuery SelectTable) ColumnTime { func (i *timeColumnImpl) From(subQuery SelectTable) ColumnTime {
return i.from(subQuery).(ColumnTime) return i.fromImpl(subQuery).(ColumnTime)
} }
// TimeColumn creates named time column // TimeColumn creates named time column
@ -190,7 +190,7 @@ func TimeColumn(name string) ColumnTime {
// ColumnTimez is interface of SQL time with time zone columns. // ColumnTimez is interface of SQL time with time zone columns.
type ColumnTimez interface { type ColumnTimez interface {
TimezExpression TimezExpression
column IColumn
From(subQuery SelectTable) ColumnTimez From(subQuery SelectTable) ColumnTimez
} }
@ -201,16 +201,16 @@ type timezColumnImpl struct {
columnImpl columnImpl
} }
func (i *timezColumnImpl) from(subQuery SelectTable) projection { func (i *timezColumnImpl) fromImpl(subQuery SelectTable) Projection {
newTimezColumn := TimezColumn(i.name) newTimezColumn := TimezColumn(i.name)
newTimezColumn.setTableName(i.tableName) newTimezColumn.SetTableName(i.tableName)
newTimezColumn.setSubQuery(subQuery) newTimezColumn.SetSubQuery(subQuery)
return newTimezColumn return newTimezColumn
} }
func (i *timezColumnImpl) From(subQuery SelectTable) ColumnTimez { func (i *timezColumnImpl) From(subQuery SelectTable) ColumnTimez {
return i.from(subQuery).(ColumnTimez) return i.fromImpl(subQuery).(ColumnTimez)
} }
// TimezColumn creates named time with time zone column. // TimezColumn creates named time with time zone column.
@ -227,7 +227,7 @@ func TimezColumn(name string) ColumnTimez {
// ColumnTimestamp is interface of SQL timestamp columns. // ColumnTimestamp is interface of SQL timestamp columns.
type ColumnTimestamp interface { type ColumnTimestamp interface {
TimestampExpression TimestampExpression
column IColumn
From(subQuery SelectTable) ColumnTimestamp From(subQuery SelectTable) ColumnTimestamp
} }
@ -238,16 +238,16 @@ type timestampColumnImpl struct {
columnImpl columnImpl
} }
func (i *timestampColumnImpl) from(subQuery SelectTable) projection { func (i *timestampColumnImpl) fromImpl(subQuery SelectTable) Projection {
newTimestampColumn := TimestampColumn(i.name) newTimestampColumn := TimestampColumn(i.name)
newTimestampColumn.setTableName(i.tableName) newTimestampColumn.SetTableName(i.tableName)
newTimestampColumn.setSubQuery(subQuery) newTimestampColumn.SetSubQuery(subQuery)
return newTimestampColumn return newTimestampColumn
} }
func (i *timestampColumnImpl) From(subQuery SelectTable) ColumnTimestamp { func (i *timestampColumnImpl) From(subQuery SelectTable) ColumnTimestamp {
return i.from(subQuery).(ColumnTimestamp) return i.fromImpl(subQuery).(ColumnTimestamp)
} }
// TimestampColumn creates named timestamp column // TimestampColumn creates named timestamp column
@ -264,7 +264,7 @@ func TimestampColumn(name string) ColumnTimestamp {
// ColumnTimestampz is interface of SQL timestamp with timezone columns. // ColumnTimestampz is interface of SQL timestamp with timezone columns.
type ColumnTimestampz interface { type ColumnTimestampz interface {
TimestampzExpression TimestampzExpression
column IColumn
From(subQuery SelectTable) ColumnTimestampz From(subQuery SelectTable) ColumnTimestampz
} }
@ -275,16 +275,16 @@ type timestampzColumnImpl struct {
columnImpl columnImpl
} }
func (i *timestampzColumnImpl) from(subQuery SelectTable) projection { func (i *timestampzColumnImpl) fromImpl(subQuery SelectTable) Projection {
newTimestampzColumn := TimestampzColumn(i.name) newTimestampzColumn := TimestampzColumn(i.name)
newTimestampzColumn.setTableName(i.tableName) newTimestampzColumn.SetTableName(i.tableName)
newTimestampzColumn.setSubQuery(subQuery) newTimestampzColumn.SetSubQuery(subQuery)
return newTimestampzColumn return newTimestampzColumn
} }
func (i *timestampzColumnImpl) From(subQuery SelectTable) ColumnTimestampz { func (i *timestampzColumnImpl) From(subQuery SelectTable) ColumnTimestampz {
return i.from(subQuery).(ColumnTimestampz) return i.fromImpl(subQuery).(ColumnTimestampz)
} }
// TimestampzColumn creates named timestamp with time zone column. // TimestampzColumn creates named timestamp with time zone column.
@ -301,7 +301,7 @@ func TimestampzColumn(name string) ColumnTimestampz {
// ColumnDate is interface of SQL date columns. // ColumnDate is interface of SQL date columns.
type ColumnDate interface { type ColumnDate interface {
DateExpression DateExpression
column IColumn
From(subQuery SelectTable) ColumnDate From(subQuery SelectTable) ColumnDate
} }
@ -312,16 +312,16 @@ type dateColumnImpl struct {
columnImpl columnImpl
} }
func (i *dateColumnImpl) from(subQuery SelectTable) projection { func (i *dateColumnImpl) fromImpl(subQuery SelectTable) Projection {
newDateColumn := DateColumn(i.name) newDateColumn := DateColumn(i.name)
newDateColumn.setTableName(i.tableName) newDateColumn.SetTableName(i.tableName)
newDateColumn.setSubQuery(subQuery) newDateColumn.SetSubQuery(subQuery)
return newDateColumn return newDateColumn
} }
func (i *dateColumnImpl) From(subQuery SelectTable) ColumnDate { func (i *dateColumnImpl) From(subQuery SelectTable) ColumnDate {
return i.from(subQuery).(ColumnDate) return i.fromImpl(subQuery).(ColumnDate)
} }
// DateColumn creates named date column. // DateColumn creates named date column.

View file

@ -8,38 +8,38 @@ var subQuery = table1.SELECT(table1ColFloat, table1ColInt).AsTable("sub_query")
func TestNewBoolColumn(t *testing.T) { func TestNewBoolColumn(t *testing.T) {
boolColumn := BoolColumn("colBool").From(subQuery) boolColumn := BoolColumn("colBool").From(subQuery)
AssertPostgreClauseSerialize(t, boolColumn, `sub_query."colBool"`) assertClauseSerialize(t, boolColumn, `sub_query."colBool"`)
AssertPostgreClauseSerialize(t, boolColumn.EQ(Bool(true)), `(sub_query."colBool" = $1)`, true) assertClauseSerialize(t, boolColumn.EQ(Bool(true)), `(sub_query."colBool" = $1)`, true)
assertProjectionSerialize(t, boolColumn, `sub_query."colBool" AS "colBool"`) assertProjectionSerialize(t, boolColumn, `sub_query."colBool" AS "colBool"`)
boolColumn2 := table1ColBool.From(subQuery) boolColumn2 := table1ColBool.From(subQuery)
AssertPostgreClauseSerialize(t, boolColumn2, `sub_query."table1.col_bool"`) assertClauseSerialize(t, boolColumn2, `sub_query."table1.col_bool"`)
AssertPostgreClauseSerialize(t, boolColumn2.EQ(Bool(true)), `(sub_query."table1.col_bool" = $1)`, true) assertClauseSerialize(t, boolColumn2.EQ(Bool(true)), `(sub_query."table1.col_bool" = $1)`, true)
assertProjectionSerialize(t, boolColumn2, `sub_query."table1.col_bool" AS "table1.col_bool"`) assertProjectionSerialize(t, boolColumn2, `sub_query."table1.col_bool" AS "table1.col_bool"`)
} }
func TestNewIntColumn(t *testing.T) { func TestNewIntColumn(t *testing.T) {
intColumn := IntegerColumn("col_int").From(subQuery) intColumn := IntegerColumn("col_int").From(subQuery)
AssertPostgreClauseSerialize(t, intColumn, `sub_query."col_int"`) assertClauseSerialize(t, intColumn, `sub_query."col_int"`)
AssertPostgreClauseSerialize(t, intColumn.EQ(Int(12)), `(sub_query."col_int" = $1)`, int64(12)) assertClauseSerialize(t, intColumn.EQ(Int(12)), `(sub_query."col_int" = $1)`, int64(12))
assertProjectionSerialize(t, intColumn, `sub_query."col_int" AS "col_int"`) assertProjectionSerialize(t, intColumn, `sub_query."col_int" AS "col_int"`)
intColumn2 := table1ColInt.From(subQuery) intColumn2 := table1ColInt.From(subQuery)
AssertPostgreClauseSerialize(t, intColumn2, `sub_query."table1.col_int"`) assertClauseSerialize(t, intColumn2, `sub_query."table1.col_int"`)
AssertPostgreClauseSerialize(t, intColumn2.EQ(Int(14)), `(sub_query."table1.col_int" = $1)`, int64(14)) assertClauseSerialize(t, intColumn2.EQ(Int(14)), `(sub_query."table1.col_int" = $1)`, int64(14))
assertProjectionSerialize(t, intColumn2, `sub_query."table1.col_int" AS "table1.col_int"`) assertProjectionSerialize(t, intColumn2, `sub_query."table1.col_int" AS "table1.col_int"`)
} }
func TestNewFloatColumnColumn(t *testing.T) { func TestNewFloatColumnColumn(t *testing.T) {
floatColumn := FloatColumn("col_float").From(subQuery) floatColumn := FloatColumn("col_float").From(subQuery)
AssertPostgreClauseSerialize(t, floatColumn, `sub_query."col_float"`) assertClauseSerialize(t, floatColumn, `sub_query."col_float"`)
AssertPostgreClauseSerialize(t, floatColumn.EQ(Float(1.11)), `(sub_query."col_float" = $1)`, float64(1.11)) assertClauseSerialize(t, floatColumn.EQ(Float(1.11)), `(sub_query."col_float" = $1)`, float64(1.11))
assertProjectionSerialize(t, floatColumn, `sub_query."col_float" AS "col_float"`) assertProjectionSerialize(t, floatColumn, `sub_query."col_float" AS "col_float"`)
floatColumn2 := table1ColFloat.From(subQuery) floatColumn2 := table1ColFloat.From(subQuery)
AssertPostgreClauseSerialize(t, floatColumn2, `sub_query."table1.col_float"`) assertClauseSerialize(t, floatColumn2, `sub_query."table1.col_float"`)
AssertPostgreClauseSerialize(t, floatColumn2.EQ(Float(2.22)), `(sub_query."table1.col_float" = $1)`, float64(2.22)) assertClauseSerialize(t, floatColumn2.EQ(Float(2.22)), `(sub_query."table1.col_float" = $1)`, float64(2.22))
assertProjectionSerialize(t, floatColumn2, `sub_query."table1.col_float" AS "table1.col_float"`) assertProjectionSerialize(t, floatColumn2, `sub_query."table1.col_float" AS "table1.col_float"`)
} }

View file

@ -13,7 +13,7 @@ type DeleteStatement interface {
WHERE(expression BoolExpression) DeleteStatement WHERE(expression BoolExpression) DeleteStatement
RETURNING(projections ...projection) DeleteStatement RETURNING(projections ...Projection) DeleteStatement
} }
func newDeleteStatement(table WritableTable) DeleteStatement { func newDeleteStatement(table WritableTable) DeleteStatement {
@ -25,7 +25,7 @@ func newDeleteStatement(table WritableTable) DeleteStatement {
type deleteStatementImpl struct { type deleteStatementImpl struct {
table WritableTable table WritableTable
where BoolExpression where BoolExpression
returning []projection returning []Projection
} }
func (d *deleteStatementImpl) WHERE(expression BoolExpression) DeleteStatement { func (d *deleteStatementImpl) WHERE(expression BoolExpression) DeleteStatement {
@ -33,7 +33,7 @@ func (d *deleteStatementImpl) WHERE(expression BoolExpression) DeleteStatement {
return d return d
} }
func (d *deleteStatementImpl) RETURNING(projections ...projection) DeleteStatement { func (d *deleteStatementImpl) RETURNING(projections ...Projection) DeleteStatement {
d.returning = projections d.returning = projections
return d return d
} }
@ -44,18 +44,18 @@ func (d *deleteStatementImpl) accept(visitor visitor) {
d.table.accept(visitor) d.table.accept(visitor)
} }
func (d *deleteStatementImpl) serializeImpl(out *sqlBuilder) error { func (d *deleteStatementImpl) serializeImpl(out *SqlBuilder) error {
if d == nil { if d == nil {
return errors.New("jet: delete statement is nil") return errors.New("jet: delete statement is nil")
} }
out.newLine() out.newLine()
out.writeString("DELETE FROM") out.WriteString("DELETE FROM")
if d.table == nil { if d.table == nil {
return errors.New("jet: nil tableName") return errors.New("jet: nil tableName")
} }
if err := d.table.serialize(deleteStatement, out); err != nil { if err := d.table.serialize(DeleteStatementType, out); err != nil {
return err return err
} }
@ -63,11 +63,11 @@ func (d *deleteStatementImpl) serializeImpl(out *sqlBuilder) error {
return errors.New("jet: deleting without a WHERE clause") return errors.New("jet: deleting without a WHERE clause")
} }
if err := out.writeWhere(deleteStatement, d.where); err != nil { if err := out.writeWhere(DeleteStatementType, d.where); err != nil {
return err return err
} }
if err := out.writeReturning(deleteStatement, d.returning); err != nil { if err := out.writeReturning(DeleteStatementType, d.returning); err != nil {
return err return err
} }
@ -75,8 +75,8 @@ func (d *deleteStatementImpl) serializeImpl(out *sqlBuilder) error {
} }
func (d *deleteStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) { func (d *deleteStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) {
queryData := &sqlBuilder{ queryData := &SqlBuilder{
dialect: detectDialect(d, dialect...), Dialect: detectDialect(d, dialect...),
} }
err = d.serializeImpl(queryData) err = d.serializeImpl(queryData)

104
internal/jet/dialects.go Normal file
View file

@ -0,0 +1,104 @@
package jet
var ANSII = NewDialect(DialectParams{ // just for tests
AliasQuoteChar: '"',
ArgumentPlaceholder: func(ord int) string {
return "#"
},
})
type Dialect interface {
Name() string
PackageName() string
SerializeOverride(operator string) SerializeOverride
CastOverride() CastOverride
AliasQuoteChar() byte
IdentifierQuoteChar() byte
ArgumentPlaceholder() QueryPlaceholderFunc
UpdateAssigment() func(columns []IColumn, values []Clause, out *SqlBuilder) (err error)
SupportsReturning() bool
}
type SerializeFunc func(statement StatementType, out *SqlBuilder, options ...SerializeOption) error
type SerializeOverride func(expressions ...Expression) SerializeFunc
type QueryPlaceholderFunc func(ord int) string
type CastOverride func(expression Expression, castType string) SerializeFunc
type UpdateAssigmentFunc func(columns []IColumn, values []Clause, out *SqlBuilder) (err error)
type DialectParams struct {
Name string
PackageName string
SerializeOverrides map[string]SerializeOverride
CastOverride CastOverride
AliasQuoteChar byte
IdentifierQuoteChar byte
ArgumentPlaceholder QueryPlaceholderFunc
UpdateAssigment func(columns []IColumn, values []Clause, out *SqlBuilder) (err error)
SupportsReturning bool
}
func NewDialect(params DialectParams) Dialect {
return &dialectImpl{
name: params.Name,
packageName: params.PackageName,
serializeOverrides: params.SerializeOverrides,
castOverride: params.CastOverride,
aliasQuoteChar: params.AliasQuoteChar,
identifierQuoteChar: params.IdentifierQuoteChar,
argumentPlaceholder: params.ArgumentPlaceholder,
updateAssigment: params.UpdateAssigment,
supportsReturning: params.SupportsReturning,
}
}
type dialectImpl struct {
name string
packageName string
serializeOverrides map[string]SerializeOverride
castOverride CastOverride
aliasQuoteChar byte
identifierQuoteChar byte
argumentPlaceholder QueryPlaceholderFunc
updateAssigment UpdateAssigmentFunc
supportsReturning bool
}
func (d *dialectImpl) Name() string {
return d.name
}
func (d *dialectImpl) PackageName() string {
return d.packageName
}
func (d *dialectImpl) SerializeOverride(operator string) SerializeOverride {
return d.serializeOverrides[operator]
}
func (d *dialectImpl) CastOverride() CastOverride {
return d.castOverride
}
func (d *dialectImpl) AliasQuoteChar() byte {
return d.aliasQuoteChar
}
func (d *dialectImpl) IdentifierQuoteChar() byte {
return d.identifierQuoteChar
}
func (d *dialectImpl) ArgumentPlaceholder() QueryPlaceholderFunc {
return d.argumentPlaceholder
}
func (d *dialectImpl) UpdateAssigment() func(columns []IColumn, values []Clause, out *SqlBuilder) (err error) {
return d.updateAssigment
}
func (d *dialectImpl) SupportsReturning() bool {
return d.supportsReturning
}

View file

@ -18,7 +18,7 @@ func NewEnumValue(name string) StringExpression {
return enumValue return enumValue
} }
func (e enumValue) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (e enumValue) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
out.insertConstantArgument(e.name) out.insertConstantArgument(e.name)
return nil return nil
} }

View file

@ -13,8 +13,8 @@ type Expression interface {
} }
type expression interface { type expression interface {
clause Clause
projection Projection
groupByClause groupByClause
orderByClause orderByClause
@ -29,7 +29,7 @@ type expression interface {
NOT_IN(expressions ...Expression) BoolExpression NOT_IN(expressions ...Expression) BoolExpression
// The temporary alias name to assign to the expression // The temporary alias name to assign to the expression
AS(alias string) projection AS(alias string) Projection
// Expression will be used to sort query result in ascending order // Expression will be used to sort query result in ascending order
ASC() orderByClause ASC() orderByClause
@ -41,7 +41,7 @@ type expressionInterfaceImpl struct {
parent Expression parent Expression
} }
func (e *expressionInterfaceImpl) from(subQuery SelectTable) projection { func (e *expressionInterfaceImpl) fromImpl(subQuery SelectTable) Projection {
return e.parent return e.parent
} }
@ -61,7 +61,7 @@ func (e *expressionInterfaceImpl) NOT_IN(expressions ...Expression) BoolExpressi
return newBinaryBoolOperator(e.parent, WRAP(expressions...), "NOT IN") return newBinaryBoolOperator(e.parent, WRAP(expressions...), "NOT IN")
} }
func (e *expressionInterfaceImpl) AS(alias string) projection { func (e *expressionInterfaceImpl) AS(alias string) Projection {
return newAlias(e.parent, alias) return newAlias(e.parent, alias)
} }
@ -73,15 +73,15 @@ func (e *expressionInterfaceImpl) DESC() orderByClause {
return newOrderByClause(e.parent, false) return newOrderByClause(e.parent, false)
} }
func (e *expressionInterfaceImpl) serializeForGroupBy(statement statementType, out *sqlBuilder) error { func (e *expressionInterfaceImpl) serializeForGroupBy(statement StatementType, out *SqlBuilder) error {
return e.parent.serialize(statement, out, noWrap) return e.parent.serialize(statement, out, noWrap)
} }
func (e *expressionInterfaceImpl) serializeForProjection(statement statementType, out *sqlBuilder) error { func (e *expressionInterfaceImpl) serializeForProjection(statement StatementType, out *SqlBuilder) error {
return e.parent.serialize(statement, out, noWrap) return e.parent.serialize(statement, out, noWrap)
} }
func (e *expressionInterfaceImpl) serializeForOrderBy(statement statementType, out *sqlBuilder) error { func (e *expressionInterfaceImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) error {
return e.parent.serialize(statement, out, noWrap) return e.parent.serialize(statement, out, noWrap)
} }
@ -106,7 +106,7 @@ func (c *binaryOpExpression) accept(visitor visitor) {
c.rhs.accept(visitor) c.rhs.accept(visitor)
} }
func (c *binaryOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) (err error) { func (c *binaryOpExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) (err error) {
if c == nil { if c == nil {
return errors.New("jet: binary Expression is nil") return errors.New("jet: binary Expression is nil")
} }
@ -120,10 +120,10 @@ func (c *binaryOpExpression) serialize(statement statementType, out *sqlBuilder,
wrap := !contains(options, noWrap) wrap := !contains(options, noWrap)
if wrap { if wrap {
out.writeString("(") out.WriteString("(")
} }
if serializeOverride := out.dialect.serializeOverride(c.operator); serializeOverride != nil { if serializeOverride := out.Dialect.SerializeOverride(c.operator); serializeOverride != nil {
serializeOverrideFunc := serializeOverride(c.lhs, c.rhs) serializeOverrideFunc := serializeOverride(c.lhs, c.rhs)
err = serializeOverrideFunc(statement, out, options...) err = serializeOverrideFunc(statement, out, options...)
@ -133,7 +133,7 @@ func (c *binaryOpExpression) serialize(statement statementType, out *sqlBuilder,
return err return err
} }
out.writeString(c.operator) out.WriteString(c.operator)
if err := c.rhs.serialize(statement, out); err != nil { if err := c.rhs.serialize(statement, out); err != nil {
return err return err
@ -141,7 +141,7 @@ func (c *binaryOpExpression) serialize(statement statementType, out *sqlBuilder,
} }
if wrap { if wrap {
out.writeString(")") out.WriteString(")")
} }
return err return err
@ -166,13 +166,13 @@ func (p *prefixOpExpression) accept(visitor visitor) {
p.expression.accept(visitor) p.expression.accept(visitor)
} }
func (p *prefixOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (p *prefixOpExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if p == nil { if p == nil {
return errors.New("jet: Prefix Expression is nil") return errors.New("jet: Prefix Expression is nil")
} }
out.writeString("(") out.WriteString("(")
out.writeString(p.operator) out.WriteString(p.operator)
if p.expression == nil { if p.expression == nil {
return errors.New("jet: nil prefix Expression") return errors.New("jet: nil prefix Expression")
@ -181,7 +181,7 @@ func (p *prefixOpExpression) serialize(statement statementType, out *sqlBuilder,
return err return err
} }
out.writeString(")") out.WriteString(")")
return nil return nil
} }
@ -205,7 +205,7 @@ func (p *postfixOpExpression) accept(visitor visitor) {
p.expression.accept(visitor) p.expression.accept(visitor)
} }
func (p *postfixOpExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (p *postfixOpExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if p == nil { if p == nil {
return errors.New("jet: Postifx operator Expression is nil") return errors.New("jet: Postifx operator Expression is nil")
} }
@ -217,7 +217,7 @@ func (p *postfixOpExpression) serialize(statement statementType, out *sqlBuilder
return err return err
} }
out.writeString(p.operator) out.WriteString(p.operator)
return nil return nil
} }

View file

@ -0,0 +1,58 @@
package jet
import (
"testing"
)
func TestExpressionIS_NULL(t *testing.T) {
assertClauseSerialize(t, table2Col3.IS_NULL(), "table2.col3 IS NULL")
assertClauseSerialize(t, table2Col3.ADD(table2Col3).IS_NULL(), "(table2.col3 + table2.col3) IS NULL")
assertClauseSerializeErr(t, table2Col3.ADD(nil), "jet: nil rhs")
}
func TestExpressionIS_NOT_NULL(t *testing.T) {
assertClauseSerialize(t, table2Col3.IS_NOT_NULL(), "table2.col3 IS NOT NULL")
assertClauseSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_NULL(), "(table2.col3 + table2.col3) IS NOT NULL")
}
func TestExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table2Col3.IS_DISTINCT_FROM(table2Col4), "(table2.col3 IS DISTINCT FROM table2.col4)")
assertClauseSerialize(t, table2Col3.ADD(table2Col3).IS_DISTINCT_FROM(Int(23)), "((table2.col3 + table2.col3) IS DISTINCT FROM $1)", int64(23))
}
func TestExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table2Col3.IS_NOT_DISTINCT_FROM(table2Col4), "(table2.col3 IS NOT DISTINCT FROM table2.col4)")
assertClauseSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_DISTINCT_FROM(Int(23)), "((table2.col3 + table2.col3) IS NOT DISTINCT FROM $1)", int64(23))
}
func TestIN(t *testing.T) {
assertClauseSerialize(t, Float(1.11).IN(table1.SELECT(table1Col1)),
`($1 IN ((
SELECT table1.col1 AS "table1.col1"
FROM db.table1
)))`, float64(1.11))
assertClauseSerialize(t, ROW(Int(12), table1Col1).IN(table2.SELECT(table2Col3, table3Col1)),
`(ROW($1, table1.col1) IN ((
SELECT table2.col3 AS "table2.col3",
table3.col1 AS "table3.col1"
FROM db.table2
)))`, int64(12))
}
func TestNOT_IN(t *testing.T) {
assertClauseSerialize(t, Float(1.11).NOT_IN(table1.SELECT(table1Col1)),
`($1 NOT IN ((
SELECT table1.col1 AS "table1.col1"
FROM db.table1
)))`, float64(1.11))
assertClauseSerialize(t, ROW(Int(12), table1Col1).NOT_IN(table2.SELECT(table2Col3, table3Col1)),
`(ROW($1, table1.col1) NOT IN ((
SELECT table2.col3 AS "table2.col3",
table3.col1 AS "table3.col1"
FROM db.table2
)))`, int64(12))
}

View file

@ -0,0 +1,82 @@
package jet
import (
"testing"
)
func TestFloatExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.EQ(table2ColFloat), "(table1.col_float = table2.col_float)")
assertClauseSerialize(t, table1ColFloat.EQ(Float(2.11)), "(table1.col_float = $1)", float64(2.11))
}
func TestFloatExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.NOT_EQ(table2ColFloat), "(table1.col_float != table2.col_float)")
assertClauseSerialize(t, table1ColFloat.NOT_EQ(Float(2.11)), "(table1.col_float != $1)", float64(2.11))
}
func TestFloatExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.IS_DISTINCT_FROM(table2ColFloat), "(table1.col_float IS DISTINCT FROM table2.col_float)")
assertClauseSerialize(t, table1ColFloat.IS_DISTINCT_FROM(Float(2.11)), "(table1.col_float IS DISTINCT FROM $1)", float64(2.11))
}
func TestFloatExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.IS_NOT_DISTINCT_FROM(table2ColFloat), "(table1.col_float IS NOT DISTINCT FROM table2.col_float)")
assertClauseSerialize(t, table1ColFloat.IS_NOT_DISTINCT_FROM(Float(2.11)), "(table1.col_float IS NOT DISTINCT FROM $1)", float64(2.11))
}
func TestFloatExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.GT(table2ColFloat), "(table1.col_float > table2.col_float)")
assertClauseSerialize(t, table1ColFloat.GT(Float(2.11)), "(table1.col_float > $1)", float64(2.11))
}
func TestFloatExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.GT_EQ(table2ColFloat), "(table1.col_float >= table2.col_float)")
assertClauseSerialize(t, table1ColFloat.GT_EQ(Float(2.11)), "(table1.col_float >= $1)", float64(2.11))
}
func TestFloatExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.LT(table2ColFloat), "(table1.col_float < table2.col_float)")
assertClauseSerialize(t, table1ColFloat.LT(Float(2.11)), "(table1.col_float < $1)", float64(2.11))
}
func TestFloatExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.LT_EQ(table2ColFloat), "(table1.col_float <= table2.col_float)")
assertClauseSerialize(t, table1ColFloat.LT_EQ(Float(2.11)), "(table1.col_float <= $1)", float64(2.11))
}
func TestFloatExpressionADD(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.ADD(table2ColFloat), "(table1.col_float + table2.col_float)")
assertClauseSerialize(t, table1ColFloat.ADD(Float(2.11)), "(table1.col_float + $1)", float64(2.11))
}
func TestFloatExpressionSUB(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.SUB(table2ColFloat), "(table1.col_float - table2.col_float)")
assertClauseSerialize(t, table1ColFloat.SUB(Float(2.11)), "(table1.col_float - $1)", float64(2.11))
}
func TestFloatExpressionMUL(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.MUL(table2ColFloat), "(table1.col_float * table2.col_float)")
assertClauseSerialize(t, table1ColFloat.MUL(Float(2.11)), "(table1.col_float * $1)", float64(2.11))
}
func TestFloatExpressionDIV(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.DIV(table2ColFloat), "(table1.col_float / table2.col_float)")
assertClauseSerialize(t, table1ColFloat.DIV(Float(2.11)), "(table1.col_float / $1)", float64(2.11))
}
func TestFloatExpressionMOD(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.MOD(table2ColFloat), "(table1.col_float % table2.col_float)")
assertClauseSerialize(t, table1ColFloat.MOD(Float(2.11)), "(table1.col_float % $1)", float64(2.11))
}
func TestFloatExpressionPOW(t *testing.T) {
assertClauseSerialize(t, table1ColFloat.POW(table2ColFloat), "POW(table1.col_float, table2.col_float)")
assertClauseSerialize(t, table1ColFloat.POW(Float(2.11)), "POW(table1.col_float, $1)", float64(2.11))
}
func TestFloatExp(t *testing.T) {
assertClauseSerialize(t, FloatExp(table1ColInt), "table1.col_int")
assertClauseSerialize(t, FloatExp(table1ColInt.ADD(table3ColInt)), "(table1.col_int + table3.col_int)")
assertClauseSerialize(t, FloatExp(table1ColInt.ADD(table3ColInt)).ADD(Float(11.11)),
"((table1.col_int + table3.col_int) + $1)", float64(11.11))
}

View file

@ -501,7 +501,7 @@ func (f *funcExpressionImpl) accept(visitor visitor) {
} }
} }
func (f *funcExpressionImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (f *funcExpressionImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if f == nil { if f == nil {
return errors.New("jet: Function expressions is nil. ") return errors.New("jet: Function expressions is nil. ")
} }
@ -509,9 +509,9 @@ func (f *funcExpressionImpl) serialize(statement statementType, out *sqlBuilder,
addBrackets := !f.noBrackets || len(f.expressions) > 0 addBrackets := !f.noBrackets || len(f.expressions) > 0
if addBrackets { if addBrackets {
out.writeString(f.name + "(") out.WriteString(f.name + "(")
} else { } else {
out.writeString(f.name) out.WriteString(f.name)
} }
err := serializeExpressionList(statement, f.expressions, ", ", out) err := serializeExpressionList(statement, f.expressions, ", ", out)
@ -520,7 +520,7 @@ func (f *funcExpressionImpl) serialize(statement statementType, out *sqlBuilder,
} }
if addBrackets { if addBrackets {
out.writeString(")") out.WriteString(")")
} }
return nil return nil

View file

@ -0,0 +1,162 @@
package jet
import (
"testing"
)
func TestFuncAVG(t *testing.T) {
assertClauseSerialize(t, AVG(table1ColFloat), "AVG(table1.col_float)")
assertClauseSerialize(t, AVG(table1ColInt), "AVG(table1.col_int)")
}
func TestFuncBIT_AND(t *testing.T) {
assertClauseSerialize(t, BIT_AND(table1ColInt), "BIT_AND(table1.col_int)")
}
func TestFuncBIT_OR(t *testing.T) {
assertClauseSerialize(t, BIT_OR(table1ColInt), "BIT_OR(table1.col_int)")
}
func TestFuncBOOL_AND(t *testing.T) {
assertClauseSerialize(t, BOOL_AND(table1ColBool), "BOOL_AND(table1.col_bool)")
}
func TestFuncBOOL_OR(t *testing.T) {
assertClauseSerialize(t, BOOL_OR(table1ColBool), "BOOL_OR(table1.col_bool)")
}
func TestFuncEVERY(t *testing.T) {
assertClauseSerialize(t, EVERY(table1ColBool), "EVERY(table1.col_bool)")
}
func TestFuncMIN(t *testing.T) {
t.Run("float", func(t *testing.T) {
assertClauseSerialize(t, MINf(table1ColFloat), "MIN(table1.col_float)")
})
t.Run("integer", func(t *testing.T) {
assertClauseSerialize(t, MINi(table1ColInt), "MIN(table1.col_int)")
})
}
func TestFuncMAX(t *testing.T) {
t.Run("float", func(t *testing.T) {
assertClauseSerialize(t, MAXf(table1ColFloat), "MAX(table1.col_float)")
assertClauseSerialize(t, MAXf(Float(11.2222)), "MAX($1)", float64(11.2222))
})
t.Run("integer", func(t *testing.T) {
assertClauseSerialize(t, MAXi(table1ColInt), "MAX(table1.col_int)")
assertClauseSerialize(t, MAXi(Int(11)), "MAX($1)", int64(11))
})
}
func TestFuncSUM(t *testing.T) {
t.Run("float", func(t *testing.T) {
assertClauseSerialize(t, SUMf(table1ColFloat), "SUM(table1.col_float)")
assertClauseSerialize(t, SUMf(Float(11.2222)), "SUM($1)", float64(11.2222))
})
t.Run("integer", func(t *testing.T) {
assertClauseSerialize(t, SUMi(table1ColInt), "SUM(table1.col_int)")
assertClauseSerialize(t, SUMi(Int(11)), "SUM($1)", int64(11))
})
}
func TestFuncCOUNT(t *testing.T) {
assertClauseSerialize(t, COUNT(STAR), "COUNT(*)")
assertClauseSerialize(t, COUNT(table1ColFloat), "COUNT(table1.col_float)")
assertClauseSerialize(t, COUNT(Float(11.2222)), "COUNT($1)", float64(11.2222))
}
func TestFuncABS(t *testing.T) {
t.Run("float", func(t *testing.T) {
assertClauseSerialize(t, ABSf(table1ColFloat), "ABS(table1.col_float)")
assertClauseSerialize(t, ABSf(Float(11.2222)), "ABS($1)", float64(11.2222))
})
t.Run("integer", func(t *testing.T) {
assertClauseSerialize(t, ABSi(table1ColInt), "ABS(table1.col_int)")
assertClauseSerialize(t, ABSi(Int(11)), "ABS($1)", int64(11))
})
}
func TestFuncSQRT(t *testing.T) {
assertClauseSerialize(t, SQRT(table1ColFloat), "SQRT(table1.col_float)")
assertClauseSerialize(t, SQRT(Float(11.2222)), "SQRT($1)", float64(11.2222))
assertClauseSerialize(t, SQRT(table1ColInt), "SQRT(table1.col_int)")
assertClauseSerialize(t, SQRT(Int(11)), "SQRT($1)", int64(11))
}
func TestFuncCBRT(t *testing.T) {
assertClauseSerialize(t, CBRT(table1ColFloat), "CBRT(table1.col_float)")
assertClauseSerialize(t, CBRT(Float(11.2222)), "CBRT($1)", float64(11.2222))
assertClauseSerialize(t, CBRT(table1ColInt), "CBRT(table1.col_int)")
assertClauseSerialize(t, CBRT(Int(11)), "CBRT($1)", int64(11))
}
func TestFuncCEIL(t *testing.T) {
assertClauseSerialize(t, CEIL(table1ColFloat), "CEIL(table1.col_float)")
assertClauseSerialize(t, CEIL(Float(11.2222)), "CEIL($1)", float64(11.2222))
}
func TestFuncFLOOR(t *testing.T) {
assertClauseSerialize(t, FLOOR(table1ColFloat), "FLOOR(table1.col_float)")
assertClauseSerialize(t, FLOOR(Float(11.2222)), "FLOOR($1)", float64(11.2222))
}
func TestFuncROUND(t *testing.T) {
assertClauseSerialize(t, ROUND(table1ColFloat), "ROUND(table1.col_float)")
assertClauseSerialize(t, ROUND(Float(11.2222)), "ROUND($1)", float64(11.2222))
assertClauseSerialize(t, ROUND(table1ColFloat, Int(2)), "ROUND(table1.col_float, $1)", int64(2))
assertClauseSerialize(t, ROUND(Float(11.2222), Int(1)), "ROUND($1, $2)", float64(11.2222), int64(1))
}
func TestFuncSIGN(t *testing.T) {
assertClauseSerialize(t, SIGN(table1ColFloat), "SIGN(table1.col_float)")
assertClauseSerialize(t, SIGN(Float(11.2222)), "SIGN($1)", float64(11.2222))
}
func TestFuncTRUNC(t *testing.T) {
assertClauseSerialize(t, TRUNC(table1ColFloat), "TRUNC(table1.col_float)")
assertClauseSerialize(t, TRUNC(Float(11.2222)), "TRUNC($1)", float64(11.2222))
assertClauseSerialize(t, TRUNC(table1ColFloat, Int(2)), "TRUNC(table1.col_float, $1)", int64(2))
assertClauseSerialize(t, TRUNC(Float(11.2222), Int(1)), "TRUNC($1, $2)", float64(11.2222), int64(1))
}
func TestFuncLN(t *testing.T) {
assertClauseSerialize(t, LN(table1ColFloat), "LN(table1.col_float)")
assertClauseSerialize(t, LN(Float(11.2222)), "LN($1)", float64(11.2222))
}
func TestFuncLOG(t *testing.T) {
assertClauseSerialize(t, LOG(table1ColFloat), "LOG(table1.col_float)")
assertClauseSerialize(t, LOG(Float(11.2222)), "LOG($1)", float64(11.2222))
}
func TestFuncCOALESCE(t *testing.T) {
assertClauseSerialize(t, COALESCE(table1ColFloat), "COALESCE(table1.col_float)")
assertClauseSerialize(t, COALESCE(Float(11.2222), NULL, String("str")), "COALESCE($1, NULL, $2)", float64(11.2222), "str")
}
func TestFuncNULLIF(t *testing.T) {
assertClauseSerialize(t, NULLIF(table1ColFloat, table2ColInt), "NULLIF(table1.col_float, table2.col_int)")
assertClauseSerialize(t, NULLIF(Float(11.2222), NULL), "NULLIF($1, NULL)", float64(11.2222))
}
func TestFuncGREATEST(t *testing.T) {
assertClauseSerialize(t, GREATEST(table1ColFloat), "GREATEST(table1.col_float)")
assertClauseSerialize(t, GREATEST(Float(11.2222), NULL, String("str")), "GREATEST($1, NULL, $2)", float64(11.2222), "str")
}
func TestFuncLEAST(t *testing.T) {
assertClauseSerialize(t, LEAST(table1ColFloat), "LEAST(table1.col_float)")
assertClauseSerialize(t, LEAST(Float(11.2222), NULL, String("str")), "LEAST($1, NULL, $2)", float64(11.2222), "str")
}
func TestTO_ASCII(t *testing.T) {
assertClauseSerialize(t, TO_ASCII(String("Karel")), `TO_ASCII($1)`, "Karel")
assertClauseSerialize(t, TO_ASCII(String("Karel")), `TO_ASCII($1)`, "Karel")
}

View file

@ -0,0 +1,5 @@
package jet
type groupByClause interface {
serializeForGroupBy(statement StatementType, out *SqlBuilder) error
}

View file

@ -22,10 +22,10 @@ type InsertStatement interface {
QUERY(selectStatement SelectStatement) InsertStatement QUERY(selectStatement SelectStatement) InsertStatement
RETURNING(projections ...projection) InsertStatement RETURNING(projections ...Projection) InsertStatement
} }
func newInsertStatement(t WritableTable, columns []column) InsertStatement { func newInsertStatement(t WritableTable, columns []IColumn) InsertStatement {
return &insertStatementImpl{ return &insertStatementImpl{
table: t, table: t,
columns: columns, columns: columns,
@ -34,10 +34,10 @@ func newInsertStatement(t WritableTable, columns []column) InsertStatement {
type insertStatementImpl struct { type insertStatementImpl struct {
table WritableTable table WritableTable
columns []column columns []IColumn
rows [][]clause rows [][]Clause
query SelectStatement query SelectStatement
returning []projection returning []Projection
} }
func (i *insertStatementImpl) VALUES(value interface{}, values ...interface{}) InsertStatement { func (i *insertStatementImpl) VALUES(value interface{}, values ...interface{}) InsertStatement {
@ -55,7 +55,7 @@ func (i *insertStatementImpl) MODELS(data interface{}) InsertStatement {
return i return i
} }
func (i *insertStatementImpl) RETURNING(projections ...projection) InsertStatement { func (i *insertStatementImpl) RETURNING(projections ...Projection) InsertStatement {
i.returning = projections i.returning = projections
return i return i
} }
@ -65,7 +65,7 @@ func (i *insertStatementImpl) QUERY(selectStatement SelectStatement) InsertState
return i return i
} }
func (i *insertStatementImpl) getColumns() []column { func (i *insertStatementImpl) getColumns() []IColumn {
if len(i.columns) > 0 { if len(i.columns) > 0 {
return i.columns return i.columns
} }
@ -84,33 +84,33 @@ func (i *insertStatementImpl) DebugSql(dialect ...Dialect) (query string, err er
} }
func (i *insertStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) { func (i *insertStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) {
out := &sqlBuilder{ out := &SqlBuilder{
dialect: detectDialect(i, dialect...), Dialect: detectDialect(i, dialect...),
} }
out.newLine() out.newLine()
out.writeString("INSERT INTO") out.WriteString("INSERT INTO")
if utils.IsNil(i.table) { if utils.IsNil(i.table) {
return "", nil, errors.New("jet: table is nil") return "", nil, errors.New("jet: table is nil")
} }
err = i.table.serialize(insertStatement, out) err = i.table.serialize(InsertStatementType, out)
if err != nil { if err != nil {
return return
} }
if len(i.columns) > 0 { if len(i.columns) > 0 {
out.writeString("(") out.WriteString("(")
err = serializeColumnNames(i.columns, out) err = SerializeColumnNames(i.columns, out)
if err != nil { if err != nil {
return return
} }
out.writeString(")") out.WriteString(")")
} }
if len(i.rows) == 0 && i.query == nil { if len(i.rows) == 0 && i.query == nil {
@ -122,18 +122,18 @@ func (i *insertStatementImpl) Sql(dialect ...Dialect) (query string, args []inte
} }
if len(i.rows) > 0 { if len(i.rows) > 0 {
out.writeString("VALUES") out.WriteString("VALUES")
for rowIndex, row := range i.rows { for rowIndex, row := range i.rows {
if rowIndex > 0 { if rowIndex > 0 {
out.writeString(",") out.WriteString(",")
} }
out.increaseIdent() out.increaseIdent()
out.newLine() out.newLine()
out.writeString("(") out.WriteString("(")
err = serializeClauseList(insertStatement, row, out) err = SerializeClauseList(InsertStatementType, row, out)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
@ -145,14 +145,14 @@ func (i *insertStatementImpl) Sql(dialect ...Dialect) (query string, args []inte
} }
if i.query != nil { if i.query != nil {
err = i.query.serialize(insertStatement, out) err = i.query.serialize(InsertStatementType, out)
if err != nil { if err != nil {
return return
} }
} }
if err = out.writeReturning(insertStatement, i.returning); err != nil { if err = out.writeReturning(InsertStatementType, i.returning); err != nil {
return return
} }

View file

@ -26,7 +26,7 @@ INSERT INTO db.table1 (col1) VALUES
} }
func TestInsertWithColumnList(t *testing.T) { func TestInsertWithColumnList(t *testing.T) {
columnList := ColumnList{table3ColInt, table3StrCol} columnList := ColumnList(table3ColInt, table3StrCol)
assertStatement(t, table3.INSERT(columnList).VALUES(1, 3), ` assertStatement(t, table3.INSERT(columnList).VALUES(1, 3), `
INSERT INTO db.table3 (col_int, col2) VALUES INSERT INTO db.table3 (col_int, col2) VALUES

View file

@ -0,0 +1,106 @@
package jet
import (
"testing"
)
func TestIntegerExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.EQ(table2ColInt), "(table1.col_int = table2.col_int)")
assertClauseSerialize(t, table1ColInt.EQ(Int(11)), "(table1.col_int = $1)", int64(11))
}
func TestIntegerExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.NOT_EQ(table2ColInt), "(table1.col_int != table2.col_int)")
assertClauseSerialize(t, table1ColInt.NOT_EQ(Int(11)), "(table1.col_int != $1)", int64(11))
}
func TestIntegerExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.GT(table2ColInt), "(table1.col_int > table2.col_int)")
assertClauseSerialize(t, table1ColInt.GT(Int(11)), "(table1.col_int > $1)", int64(11))
}
func TestIntegerExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.GT_EQ(table2ColInt), "(table1.col_int >= table2.col_int)")
assertClauseSerialize(t, table1ColInt.GT_EQ(Int(11)), "(table1.col_int >= $1)", int64(11))
}
func TestIntegerExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.LT(table2ColInt), "(table1.col_int < table2.col_int)")
assertClauseSerialize(t, table1ColInt.LT(Int(11)), "(table1.col_int < $1)", int64(11))
}
func TestIntegerExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.LT_EQ(table2ColInt), "(table1.col_int <= table2.col_int)")
assertClauseSerialize(t, table1ColInt.LT_EQ(Int(11)), "(table1.col_int <= $1)", int64(11))
}
func TestIntegerExpressionADD(t *testing.T) {
assertClauseSerialize(t, table1ColInt.ADD(table2ColInt), "(table1.col_int + table2.col_int)")
assertClauseSerialize(t, table1ColInt.ADD(Int(11)), "(table1.col_int + $1)", int64(11))
}
func TestIntegerExpressionSUB(t *testing.T) {
assertClauseSerialize(t, table1ColInt.SUB(table2ColInt), "(table1.col_int - table2.col_int)")
assertClauseSerialize(t, table1ColInt.SUB(Int(11)), "(table1.col_int - $1)", int64(11))
}
func TestIntegerExpressionMUL(t *testing.T) {
assertClauseSerialize(t, table1ColInt.MUL(table2ColInt), "(table1.col_int * table2.col_int)")
assertClauseSerialize(t, table1ColInt.MUL(Int(11)), "(table1.col_int * $1)", int64(11))
}
func TestIntegerExpressionDIV(t *testing.T) {
assertClauseSerialize(t, table1ColInt.DIV(table2ColInt), "(table1.col_int / table2.col_int)")
assertClauseSerialize(t, table1ColInt.DIV(Int(11)), "(table1.col_int / $1)", int64(11))
}
func TestIntExpressionMOD(t *testing.T) {
assertClauseSerialize(t, table1ColInt.MOD(table2ColInt), "(table1.col_int % table2.col_int)")
assertClauseSerialize(t, table1ColInt.MOD(Int(11)), "(table1.col_int % $1)", int64(11))
}
func TestIntExpressionPOW(t *testing.T) {
assertClauseSerialize(t, table1ColInt.POW(table2ColInt), "POW(table1.col_int, table2.col_int)")
assertClauseSerialize(t, table1ColInt.POW(Int(11)), "POW(table1.col_int, $1)", int64(11))
}
func TestIntExpressionBIT_NOT(t *testing.T) {
assertClauseSerialize(t, BIT_NOT(table2ColInt), "(~ table2.col_int)")
assertClauseSerialize(t, BIT_NOT(Int(11)), "(~ $1)", int64(11))
}
func TestIntExpressionBIT_AND(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_AND(table2ColInt), "(table1.col_int & table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_AND(Int(11)), "(table1.col_int & $1)", int64(11))
}
func TestIntExpressionBIT_OR(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_OR(table2ColInt), "(table1.col_int | table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_OR(Int(11)), "(table1.col_int | $1)", int64(11))
}
func TestIntExpressionBIT_XOR(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_XOR(table2ColInt), "(table1.col_int # table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_XOR(Int(11)), "(table1.col_int # $1)", int64(11))
}
func TestIntExpressionBIT_SHIFT_LEFT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_LEFT(table2ColInt), "(table1.col_int << table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_LEFT(Int(11)), "(table1.col_int << $1)", int64(11))
}
func TestIntExpressionBIT_SHIFT_RIGHT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(table2ColInt), "(table1.col_int >> table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(Int(11)), "(table1.col_int >> $1)", int64(11))
}
func TestIntExpressionIntExp(t *testing.T) {
assertClauseSerialize(t, IntExp(table1ColFloat), "table1.col_float")
assertClauseSerialize(t, IntExp(table1ColFloat.ADD(table2ColFloat)).ADD(Int(11)),
"((table1.col_float + table2.col_float) + $1)", int64(11))
}
func TestIntExpression_MINUSi(t *testing.T) {
assertClauseSerialize(t, MINUSi(table2ColInt), "(- table2.col_int)")
assertClauseSerialize(t, MINUSi(Int(3)), "(- $1)", int64(3))
}

View file

@ -14,8 +14,8 @@ var (
type keywordClause string type keywordClause string
func (k keywordClause) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (k keywordClause) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
out.writeString(string(k)) out.WriteString(string(k))
return nil return nil
} }

View file

@ -30,7 +30,7 @@ func constLiteral(value interface{}) *literalExpression {
return exp return exp
} }
func (l literalExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (l literalExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if l.constant { if l.constant {
out.insertConstantArgument(l.value) out.insertConstantArgument(l.value)
} else { } else {
@ -110,8 +110,8 @@ func newNullLiteral() Expression {
return nullExpression return nullExpression
} }
func (n *nullLiteral) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (n *nullLiteral) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
out.writeString("NULL") out.WriteString("NULL")
return nil return nil
} }
@ -129,8 +129,8 @@ func newStarLiteral() Expression {
return starExpression return starExpression
} }
func (n *starLiteral) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (n *starLiteral) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
out.writeString("*") out.WriteString("*")
return nil return nil
} }
@ -147,10 +147,10 @@ func (n *wrap) accept(visitor visitor) {
} }
} }
func (n *wrap) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (n *wrap) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
out.writeString("(") out.WriteString("(")
err := serializeExpressionList(statement, n.expressions, ", ", out) err := serializeExpressionList(statement, n.expressions, ", ", out)
out.writeString(")") out.WriteString(")")
return err return err
} }
@ -171,8 +171,8 @@ type rawExpression struct {
raw string raw string
} }
func (n *rawExpression) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (n *rawExpression) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
out.writeString(n.raw) out.WriteString(n.raw)
return nil return nil
} }

View file

@ -0,0 +1,7 @@
package jet
import "testing"
func TestRawExpression(t *testing.T) {
assertClauseSerialize(t, RAW("current_database()"), "current_database()")
}

View file

@ -10,29 +10,17 @@ import (
// TableLockMode is a type of possible SQL table lock // TableLockMode is a type of possible SQL table lock
type TableLockMode string type TableLockMode string
// Lock types for LockStatement.
const (
LOCK_ACCESS_SHARE = "ACCESS SHARE"
LOCK_ROW_SHARE = "ROW SHARE"
LOCK_ROW_EXCLUSIVE = "ROW EXCLUSIVE"
LOCK_SHARE_UPDATE_EXCLUSIVE = "SHARE UPDATE EXCLUSIVE"
LOCK_SHARE = "SHARE"
LOCK_SHARE_ROW_EXCLUSIVE = "SHARE ROW EXCLUSIVE"
LOCK_EXCLUSIVE = "EXCLUSIVE"
LOCK_ACCESS_EXCLUSIVE = "ACCESS EXCLUSIVE"
)
// LockStatement interface for SQL LOCK statement // LockStatement interface for SQL LOCK statement
type LockStatement interface { type LockStatement interface {
Statement Statement
IN(lockMode TableLockMode) LockStatement IN(lockMode string) LockStatement
NOWAIT() LockStatement NOWAIT() LockStatement
} }
type lockStatementImpl struct { type lockStatementImpl struct {
tables []WritableTable tables []WritableTable
lockMode TableLockMode lockMode string
nowait bool nowait bool
} }
@ -43,7 +31,7 @@ func LOCK(tables ...WritableTable) LockStatement {
} }
} }
func (l *lockStatementImpl) IN(lockMode TableLockMode) LockStatement { func (l *lockStatementImpl) IN(lockMode string) LockStatement {
l.lockMode = lockMode l.lockMode = lockMode
return l return l
} }
@ -74,19 +62,19 @@ func (l *lockStatementImpl) Sql(dialect ...Dialect) (query string, args []interf
return "", nil, errors.New("jet: There is no table selected to be locked") return "", nil, errors.New("jet: There is no table selected to be locked")
} }
out := &sqlBuilder{ out := &SqlBuilder{
dialect: detectDialect(l, dialect...), Dialect: detectDialect(l, dialect...),
} }
out.newLine() out.newLine()
out.writeString("LOCK TABLE") out.WriteString("LOCK TABLE")
for i, table := range l.tables { for i, table := range l.tables {
if i > 0 { if i > 0 {
out.writeString(", ") out.WriteString(", ")
} }
err := table.serialize(lockStatement, out) err := table.serialize(LockStatementType, out)
if err != nil { if err != nil {
return "", nil, err return "", nil, err
@ -94,13 +82,13 @@ func (l *lockStatementImpl) Sql(dialect ...Dialect) (query string, args []interf
} }
if l.lockMode != "" { if l.lockMode != "" {
out.writeString("IN") out.WriteString("IN")
out.writeString(string(l.lockMode)) out.WriteString(string(l.lockMode))
out.writeString("MODE") out.WriteString("MODE")
} }
if l.nowait { if l.nowait {
out.writeString("NOWAIT") out.WriteString("NOWAIT")
} }
query, args = out.finalize() query, args = out.finalize()

View file

@ -138,12 +138,12 @@ func (c *caseOperatorImpl) accept(visitor visitor) {
} }
} }
func (c *caseOperatorImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (c *caseOperatorImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if c == nil { if c == nil {
return errors.New("jet: Case Expression is nil. ") return errors.New("jet: Case Expression is nil. ")
} }
out.writeString("(CASE") out.WriteString("(CASE")
if c.expression != nil { if c.expression != nil {
err := c.expression.serialize(statement, out) err := c.expression.serialize(statement, out)
@ -162,14 +162,14 @@ func (c *caseOperatorImpl) serialize(statement statementType, out *sqlBuilder, o
} }
for i, when := range c.when { for i, when := range c.when {
out.writeString("WHEN") out.WriteString("WHEN")
err := when.serialize(statement, out, noWrap) err := when.serialize(statement, out, noWrap)
if err != nil { if err != nil {
return err return err
} }
out.writeString("THEN") out.WriteString("THEN")
err = c.then[i].serialize(statement, out, noWrap) err = c.then[i].serialize(statement, out, noWrap)
if err != nil { if err != nil {
@ -178,7 +178,7 @@ func (c *caseOperatorImpl) serialize(statement statementType, out *sqlBuilder, o
} }
if c.els != nil { if c.els != nil {
out.writeString("ELSE") out.WriteString("ELSE")
err := c.els.serialize(statement, out, noWrap) err := c.els.serialize(statement, out, noWrap)
if err != nil { if err != nil {
@ -186,7 +186,7 @@ func (c *caseOperatorImpl) serialize(statement statementType, out *sqlBuilder, o
} }
} }
out.writeString("END)") out.WriteString("END)")
return nil return nil
} }

View file

@ -5,10 +5,10 @@ import "testing"
func TestOperatorNOT(t *testing.T) { func TestOperatorNOT(t *testing.T) {
notExpression := NOT(Int(2).EQ(Int(1))) notExpression := NOT(Int(2).EQ(Int(1)))
AssertPostgreClauseSerialize(t, NOT(table1ColBool), "(NOT table1.col_bool)") assertClauseSerialize(t, NOT(table1ColBool), "(NOT table1.col_bool)")
AssertPostgreClauseSerialize(t, notExpression, "(NOT ($1 = $2))", int64(2), int64(1)) assertClauseSerialize(t, notExpression, "(NOT ($1 = $2))", int64(2), int64(1))
assertProjectionSerialize(t, notExpression.AS("alias_not_expression"), `(NOT ($1 = $2)) AS "alias_not_expression"`, int64(2), int64(1)) assertProjectionSerialize(t, notExpression.AS("alias_not_expression"), `(NOT ($1 = $2)) AS "alias_not_expression"`, int64(2), int64(1))
AssertPostgreClauseSerialize(t, notExpression.AND(Int(4).EQ(Int(5))), `((NOT ($1 = $2)) AND ($3 = $4))`, int64(2), int64(1), int64(4), int64(5)) assertClauseSerialize(t, notExpression.AND(Int(4).EQ(Int(5))), `((NOT ($1 = $2)) AND ($3 = $4))`, int64(2), int64(1), int64(4), int64(5))
} }
func TestCase1(t *testing.T) { func TestCase1(t *testing.T) {
@ -16,7 +16,7 @@ func TestCase1(t *testing.T) {
WHEN(table3Col1.EQ(Int(1))).THEN(table3Col1.ADD(Int(1))). WHEN(table3Col1.EQ(Int(1))).THEN(table3Col1.ADD(Int(1))).
WHEN(table3Col1.EQ(Int(2))).THEN(table3Col1.ADD(Int(2))) WHEN(table3Col1.EQ(Int(2))).THEN(table3Col1.ADD(Int(2)))
AssertPostgreClauseSerialize(t, query, `(CASE WHEN table3.col1 = $1 THEN table3.col1 + $2 WHEN table3.col1 = $3 THEN table3.col1 + $4 END)`, assertClauseSerialize(t, query, `(CASE WHEN table3.col1 = $1 THEN table3.col1 + $2 WHEN table3.col1 = $3 THEN table3.col1 + $4 END)`,
int64(1), int64(1), int64(2), int64(2)) int64(1), int64(1), int64(2), int64(2))
} }
@ -26,6 +26,6 @@ func TestCase2(t *testing.T) {
WHEN(Int(2)).THEN(table3Col1.ADD(Int(2))). WHEN(Int(2)).THEN(table3Col1.ADD(Int(2))).
ELSE(Int(0)) ELSE(Int(0))
AssertPostgreClauseSerialize(t, query, `(CASE table3.col1 WHEN $1 THEN table3.col1 + $2 WHEN $3 THEN table3.col1 + $4 ELSE $5 END)`, assertClauseSerialize(t, query, `(CASE table3.col1 WHEN $1 THEN table3.col1 + $2 WHEN $3 THEN table3.col1 + $4 ELSE $5 END)`,
int64(1), int64(1), int64(2), int64(2), int64(0)) int64(1), int64(1), int64(2), int64(2), int64(0))
} }

View file

@ -4,7 +4,7 @@ import "errors"
// OrderByClause // OrderByClause
type orderByClause interface { type orderByClause interface {
serializeForOrderBy(statement statementType, out *sqlBuilder) error serializeForOrderBy(statement StatementType, out *SqlBuilder) error
} }
type orderByClauseImpl struct { type orderByClauseImpl struct {
@ -12,7 +12,7 @@ type orderByClauseImpl struct {
ascent bool ascent bool
} }
func (o *orderByClauseImpl) serializeForOrderBy(statement statementType, out *sqlBuilder) error { func (o *orderByClauseImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) error {
if o.expression == nil { if o.expression == nil {
return errors.New("jet: nil orderBy by clause") return errors.New("jet: nil orderBy by clause")
} }
@ -22,9 +22,9 @@ func (o *orderByClauseImpl) serializeForOrderBy(statement statementType, out *sq
} }
if o.ascent { if o.ascent {
out.writeString("ASC") out.WriteString("ASC")
} else { } else {
out.writeString("DESC") out.WriteString("DESC")
} }
return nil return nil

View file

@ -0,0 +1,33 @@
package jet
type Projection interface {
serializeForProjection(statement StatementType, out *SqlBuilder) error
fromImpl(subQuery SelectTable) Projection
}
func SerializeForProjection(projection Projection, statementType StatementType, out *SqlBuilder) error {
return projection.serializeForProjection(statementType, out)
}
// ProjectionList is a redefined type, so that ProjectionList can be used as a Projection.
type ProjectionList []Projection
func (cl ProjectionList) fromImpl(subQuery SelectTable) Projection {
newProjectionList := ProjectionList{}
for _, projection := range cl {
newProjectionList = append(newProjectionList, projection.fromImpl(subQuery))
}
return newProjectionList
}
func (cl ProjectionList) serializeForProjection(statement StatementType, out *SqlBuilder) error {
err := SerializeProjectionList(statement, cl, out)
if err != nil {
return err
}
return nil
}

View file

@ -31,12 +31,12 @@ type SelectStatement interface {
AsTable(alias string) SelectTable AsTable(alias string) SelectTable
projections() []projection projections() []Projection
} }
//SELECT creates new SelectStatement with list of projections //SELECT creates new SelectStatement with list of projections
func SELECT(projection1 projection, projections ...projection) SelectStatement { func SELECT(projection1 Projection, projections ...Projection) SelectStatement {
return newSelectStatement(nil, append([]projection{projection1}, projections...)) return newSelectStatement(nil, append([]Projection{projection1}, projections...))
} }
type selectStatementImpl struct { type selectStatementImpl struct {
@ -45,7 +45,7 @@ type selectStatementImpl struct {
table ReadableTable table ReadableTable
distinct bool distinct bool
projectionList []projection projectionList []Projection
where BoolExpression where BoolExpression
groupBy []groupByClause groupBy []groupByClause
having BoolExpression having BoolExpression
@ -56,7 +56,7 @@ type selectStatementImpl struct {
lockFor SelectLock lockFor SelectLock
} }
func newSelectStatement(table ReadableTable, projections []projection) SelectStatement { func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement {
newSelect := &selectStatementImpl{ newSelect := &selectStatementImpl{
table: table, table: table,
projectionList: projections, projectionList: projections,
@ -144,15 +144,15 @@ func (s *selectStatementImpl) EXCEPT_ALL(rhs SelectStatement) SelectStatement {
return EXCEPT_ALL(s.parent, rhs) return EXCEPT_ALL(s.parent, rhs)
} }
func (s *selectStatementImpl) projections() []projection { func (s *selectStatementImpl) projections() []Projection {
return s.projectionList return s.projectionList
} }
func (s *selectStatementImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (s *selectStatementImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if s == nil { if s == nil {
return errors.New("jet: Select expression is nil. ") return errors.New("jet: Select expression is nil. ")
} }
out.writeString("(") out.WriteString("(")
out.increaseIdent() out.increaseIdent()
err := s.serializeImpl(out) err := s.serializeImpl(out)
@ -163,41 +163,41 @@ func (s *selectStatementImpl) serialize(statement statementType, out *sqlBuilder
} }
out.newLine() out.newLine()
out.writeString(")") out.WriteString(")")
return nil return nil
} }
func (s *selectStatementImpl) serializeImpl(out *sqlBuilder) error { func (s *selectStatementImpl) serializeImpl(out *SqlBuilder) error {
if s == nil { if s == nil {
return errors.New("jet: Select expression is nil. ") return errors.New("jet: Select expression is nil. ")
} }
out.newLine() out.newLine()
out.writeString("SELECT") out.WriteString("SELECT")
if s.distinct { if s.distinct {
out.writeString("DISTINCT") out.WriteString("DISTINCT")
} }
if len(s.projectionList) == 0 { if len(s.projectionList) == 0 {
return errors.New("jet: no column selected for projection") return errors.New("jet: no column selected for Projection")
} }
err := out.writeProjections(selectStatement, s.projectionList) err := out.writeProjections(SelectStatementType, s.projectionList)
if err != nil { if err != nil {
return err return err
} }
if s.table != nil { if s.table != nil {
if err := out.writeFrom(selectStatement, s.table); err != nil { if err := out.writeFrom(SelectStatementType, s.table); err != nil {
return err return err
} }
} }
if s.where != nil { if s.where != nil {
err := out.writeWhere(selectStatement, s.where) err := out.writeWhere(SelectStatementType, s.where)
if err != nil { if err != nil {
return nil return nil
@ -205,7 +205,7 @@ func (s *selectStatementImpl) serializeImpl(out *sqlBuilder) error {
} }
if s.groupBy != nil && len(s.groupBy) > 0 { if s.groupBy != nil && len(s.groupBy) > 0 {
err := out.writeGroupBy(selectStatement, s.groupBy) err := out.writeGroupBy(SelectStatementType, s.groupBy)
if err != nil { if err != nil {
return err return err
@ -213,7 +213,7 @@ func (s *selectStatementImpl) serializeImpl(out *sqlBuilder) error {
} }
if s.having != nil { if s.having != nil {
err := out.writeHaving(selectStatement, s.having) err := out.writeHaving(SelectStatementType, s.having)
if err != nil { if err != nil {
return err return err
@ -221,7 +221,7 @@ func (s *selectStatementImpl) serializeImpl(out *sqlBuilder) error {
} }
if s.orderBy != nil { if s.orderBy != nil {
err := out.writeOrderBy(selectStatement, s.orderBy) err := out.writeOrderBy(SelectStatementType, s.orderBy)
if err != nil { if err != nil {
return err return err
@ -230,20 +230,20 @@ func (s *selectStatementImpl) serializeImpl(out *sqlBuilder) error {
if s.limit >= 0 { if s.limit >= 0 {
out.newLine() out.newLine()
out.writeString("LIMIT") out.WriteString("LIMIT")
out.insertParametrizedArgument(s.limit) out.insertParametrizedArgument(s.limit)
} }
if s.offset >= 0 { if s.offset >= 0 {
out.newLine() out.newLine()
out.writeString("OFFSET") out.WriteString("OFFSET")
out.insertParametrizedArgument(s.offset) out.insertParametrizedArgument(s.offset)
} }
if s.lockFor != nil { if s.lockFor != nil {
out.newLine() out.newLine()
out.writeString("FOR") out.WriteString("FOR")
err := s.lockFor.serialize(selectStatement, out) err := s.lockFor.serialize(SelectStatementType, out)
if err != nil { if err != nil {
return err return err
@ -271,8 +271,8 @@ func (s *selectStatementImpl) accept(visitor visitor) {
func (s *selectStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) { func (s *selectStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) {
queryData := &sqlBuilder{ queryData := &SqlBuilder{
dialect: detectDialect(s, dialect...), Dialect: detectDialect(s, dialect...),
} }
err = s.serializeImpl(queryData) err = s.serializeImpl(queryData)
@ -308,7 +308,7 @@ func (s *selectStatementImpl) ExecContext(context context.Context, db execution.
// SelectLock is interface for SELECT statement locks // SelectLock is interface for SELECT statement locks
type SelectLock interface { type SelectLock interface {
clause Clause
NOWAIT() SelectLock NOWAIT() SelectLock
SKIP_LOCKED() SelectLock SKIP_LOCKED() SelectLock
@ -339,15 +339,15 @@ func (s *selectLockImpl) SKIP_LOCKED() SelectLock {
return s return s
} }
func (s *selectLockImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (s *selectLockImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
out.writeString(s.lockStrength) out.WriteString(s.lockStrength)
if s.noWait { if s.noWait {
out.writeString("NOWAIT") out.WriteString("NOWAIT")
} }
if s.skipLocked { if s.skipLocked {
out.writeString("SKIP LOCKED") out.WriteString("SKIP LOCKED")
} }
return nil return nil

View file

@ -3,11 +3,11 @@ package jet
import "testing" import "testing"
func TestInvalidSelect(t *testing.T) { func TestInvalidSelect(t *testing.T) {
assertStatementErr(t, SELECT(nil), "jet: projection is nil") assertStatementErr(t, SELECT(nil), "jet: Projection is nil")
} }
func TestSelectColumnList(t *testing.T) { func TestSelectColumnList(t *testing.T) {
columnList := ColumnList{table2ColInt, table2ColFloat, table3ColInt} columnList := ColumnList(table2ColInt, table2ColFloat, table3ColInt)
assertStatement(t, SELECT(columnList).FROM(table2), ` assertStatement(t, SELECT(columnList).FROM(table2), `
SELECT table2.col_int AS "table2.col_int", SELECT table2.col_int AS "table2.col_int",
@ -17,6 +17,15 @@ FROM db.table2;
`) `)
} }
func TestSelectLiterals(t *testing.T) {
assertStatement(t, SELECT(Int(1), Float(2.2), Bool(false)).FROM(table1), `
SELECT 1,
2.2,
FALSE
FROM db.table1;
`)
}
func TestSelectDistinct(t *testing.T) { func TestSelectDistinct(t *testing.T) {
assertStatement(t, SELECT(table1ColBool).DISTINCT(), ` assertStatement(t, SELECT(table1ColBool).DISTINCT(), `
SELECT DISTINCT table1.col_bool AS "table1.col_bool"; SELECT DISTINCT table1.col_bool AS "table1.col_bool";

View file

@ -16,7 +16,7 @@ type selectTableImpl struct {
selectStmt SelectStatement selectStmt SelectStatement
alias string alias string
projections []projection projections []Projection
} }
func newSelectTable(selectStmt SelectStatement, alias string) SelectTable { func newSelectTable(selectStmt SelectStatement, alias string) SelectTable {
@ -25,7 +25,7 @@ func newSelectTable(selectStmt SelectStatement, alias string) SelectTable {
expTable.readableTableInterfaceImpl.parent = expTable expTable.readableTableInterfaceImpl.parent = expTable
for _, projection := range selectStmt.projections() { for _, projection := range selectStmt.projections() {
newProjection := projection.from(expTable) newProjection := projection.fromImpl(expTable)
expTable.projections = append(expTable.projections, newProjection) expTable.projections = append(expTable.projections, newProjection)
} }
@ -37,7 +37,7 @@ func (s *selectTableImpl) Alias() string {
return s.alias return s.alias
} }
func (s *selectTableImpl) columns() []column { func (s *selectTableImpl) columns() []IColumn {
return nil return nil
} }
@ -54,7 +54,7 @@ func (s *selectTableImpl) AllColumns() ProjectionList {
return s.projections return s.projections
} }
func (s *selectTableImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (s *selectTableImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if s == nil { if s == nil {
return errors.New("jet: Expression table is nil. ") return errors.New("jet: Expression table is nil. ")
} }
@ -65,7 +65,7 @@ func (s *selectTableImpl) serialize(statement statementType, out *sqlBuilder, op
return err return err
} }
out.writeString("AS") out.WriteString("AS")
out.writeIdentifier(s.alias) out.writeIdentifier(s.alias)
return nil return nil

View file

@ -82,14 +82,14 @@ func (s *setStatementImpl) accept(visitor visitor) {
} }
} }
func (s *setStatementImpl) projections() []projection { func (s *setStatementImpl) projections() []Projection {
if len(s.selects) > 0 { if len(s.selects) > 0 {
return s.selects[0].projections() return s.selects[0].projections()
} }
return []projection{} return []Projection{}
} }
func (s *setStatementImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (s *setStatementImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if s == nil { if s == nil {
return errors.New("jet: Set expression is nil. ") return errors.New("jet: Set expression is nil. ")
} }
@ -97,7 +97,7 @@ func (s *setStatementImpl) serialize(statement statementType, out *sqlBuilder, o
wrap := s.orderBy != nil || s.limit >= 0 || s.offset >= 0 wrap := s.orderBy != nil || s.limit >= 0 || s.offset >= 0
if wrap { if wrap {
out.writeString("(") out.WriteString("(")
out.increaseIdent() out.increaseIdent()
} }
@ -110,13 +110,13 @@ func (s *setStatementImpl) serialize(statement statementType, out *sqlBuilder, o
if wrap { if wrap {
out.decreaseIdent() out.decreaseIdent()
out.newLine() out.newLine()
out.writeString(")") out.WriteString(")")
} }
return nil return nil
} }
func (s *setStatementImpl) serializeImpl(out *sqlBuilder) error { func (s *setStatementImpl) serializeImpl(out *SqlBuilder) error {
if s == nil { if s == nil {
return errors.New("jet: Set expression is nil. ") return errors.New("jet: Set expression is nil. ")
} }
@ -126,16 +126,16 @@ func (s *setStatementImpl) serializeImpl(out *sqlBuilder) error {
} }
out.newLine() out.newLine()
out.writeString("(") out.WriteString("(")
out.increaseIdent() out.increaseIdent()
for i, selectStmt := range s.selects { for i, selectStmt := range s.selects {
out.newLine() out.newLine()
if i > 0 { if i > 0 {
out.writeString(s.operator) out.WriteString(s.operator)
if s.all { if s.all {
out.writeString("ALL") out.WriteString("ALL")
} }
out.newLine() out.newLine()
} }
@ -144,7 +144,7 @@ func (s *setStatementImpl) serializeImpl(out *sqlBuilder) error {
return errors.New("jet: select statement is nil") return errors.New("jet: select statement is nil")
} }
err := selectStmt.serialize(setStatement, out) err := selectStmt.serialize(SetStatementType, out)
if err != nil { if err != nil {
return err return err
@ -153,10 +153,10 @@ func (s *setStatementImpl) serializeImpl(out *sqlBuilder) error {
out.decreaseIdent() out.decreaseIdent()
out.newLine() out.newLine()
out.writeString(")") out.WriteString(")")
if s.orderBy != nil { if s.orderBy != nil {
err := out.writeOrderBy(setStatement, s.orderBy) err := out.writeOrderBy(SetStatementType, s.orderBy)
if err != nil { if err != nil {
return err return err
} }
@ -164,13 +164,13 @@ func (s *setStatementImpl) serializeImpl(out *sqlBuilder) error {
if s.limit >= 0 { if s.limit >= 0 {
out.newLine() out.newLine()
out.writeString("LIMIT") out.WriteString("LIMIT")
out.insertParametrizedArgument(s.limit) out.insertParametrizedArgument(s.limit)
} }
if s.offset >= 0 { if s.offset >= 0 {
out.newLine() out.newLine()
out.writeString("OFFSET") out.WriteString("OFFSET")
out.insertParametrizedArgument(s.offset) out.insertParametrizedArgument(s.offset)
} }
@ -178,8 +178,8 @@ func (s *setStatementImpl) serializeImpl(out *sqlBuilder) error {
} }
func (s *setStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) { func (s *setStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) {
queryData := &sqlBuilder{ queryData := &SqlBuilder{
dialect: detectDialect(s, dialect...), Dialect: detectDialect(s, dialect...),
} }
err = s.serializeImpl(queryData) err = s.serializeImpl(queryData)

View file

@ -39,14 +39,26 @@ func debugSql(statement Statement, overrideDialect ...Dialect) (string, error) {
return "", err return "", err
} }
//debugSQLQuery := sqlQuery
//
//for i, arg := range args {
// argPlaceholder := dialect.ArgumentPlaceholder()(i + 1)
// debugSQLQuery = strings.Replace(debugSQLQuery, argPlaceholder, argToString(arg), 1)
//}
//
//return debugSQLQuery, nil
return queryStringToDebugString(sqlQuery, args, dialect), nil
}
func queryStringToDebugString(sqlQuery string, args []interface{}, dialect Dialect) string {
debugSQLQuery := sqlQuery debugSQLQuery := sqlQuery
for i, arg := range args { for i, arg := range args {
argPlaceholder := dialect.ArgumentPlaceholder(i + 1) argPlaceholder := dialect.ArgumentPlaceholder()(i + 1)
debugSQLQuery = strings.Replace(debugSQLQuery, argPlaceholder, argToString(arg), 1) debugSQLQuery = strings.Replace(debugSQLQuery, argPlaceholder, argToString(arg), 1)
} }
return debugSQLQuery, nil return debugSQLQuery
} }
func query(statement Statement, db execution.DB, destination interface{}) error { func query(statement Statement, db execution.DB, destination interface{}) error {

View file

@ -0,0 +1,82 @@
package jet
import (
"testing"
)
func TestStringEQ(t *testing.T) {
exp := table3StrCol.EQ(table2ColStr)
assertClauseSerialize(t, exp, "(table3.col2 = table2.col_str)")
exp = table3StrCol.EQ(String("JOHN"))
assertClauseSerialize(t, exp, "(table3.col2 = $1)", "JOHN")
}
func TestStringNOT_EQ(t *testing.T) {
exp := table3StrCol.NOT_EQ(table2ColStr)
assertClauseSerialize(t, exp, "(table3.col2 != table2.col_str)")
assertClauseSerialize(t, table3StrCol.NOT_EQ(String("JOHN")), "(table3.col2 != $1)", "JOHN")
}
func TestStringExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table3StrCol.IS_DISTINCT_FROM(table2ColStr), "(table3.col2 IS DISTINCT FROM table2.col_str)")
assertClauseSerialize(t, table3StrCol.IS_DISTINCT_FROM(String("JOHN")), "(table3.col2 IS DISTINCT FROM $1)", "JOHN")
}
func TestStringExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table3StrCol.IS_NOT_DISTINCT_FROM(table2ColStr), "(table3.col2 IS NOT DISTINCT FROM table2.col_str)")
assertClauseSerialize(t, table3StrCol.IS_NOT_DISTINCT_FROM(String("JOHN")), "(table3.col2 IS NOT DISTINCT FROM $1)", "JOHN")
}
func TestStringGT(t *testing.T) {
exp := table3StrCol.GT(table2ColStr)
assertClauseSerialize(t, exp, "(table3.col2 > table2.col_str)")
assertClauseSerialize(t, table3StrCol.GT(String("JOHN")), "(table3.col2 > $1)", "JOHN")
}
func TestStringGT_EQ(t *testing.T) {
exp := table3StrCol.GT_EQ(table2ColStr)
assertClauseSerialize(t, exp, "(table3.col2 >= table2.col_str)")
assertClauseSerialize(t, table3StrCol.GT_EQ(String("JOHN")), "(table3.col2 >= $1)", "JOHN")
}
func TestStringLT(t *testing.T) {
exp := table3StrCol.LT(table2ColStr)
assertClauseSerialize(t, exp, "(table3.col2 < table2.col_str)")
assertClauseSerialize(t, table3StrCol.LT(String("JOHN")), "(table3.col2 < $1)", "JOHN")
}
func TestStringLT_EQ(t *testing.T) {
exp := table3StrCol.LT_EQ(table2ColStr)
assertClauseSerialize(t, exp, "(table3.col2 <= table2.col_str)")
assertClauseSerialize(t, table3StrCol.LT_EQ(String("JOHN")), "(table3.col2 <= $1)", "JOHN")
}
func TestStringCONCAT(t *testing.T) {
assertClauseSerialize(t, table3StrCol.CONCAT(table2ColStr), "(table3.col2 || table2.col_str)")
assertClauseSerialize(t, table3StrCol.CONCAT(String("JOHN")), "(table3.col2 || $1)", "JOHN")
}
func TestStringLIKE(t *testing.T) {
assertClauseSerialize(t, table3StrCol.LIKE(table2ColStr), "(table3.col2 LIKE table2.col_str)")
assertClauseSerialize(t, table3StrCol.LIKE(String("JOHN")), "(table3.col2 LIKE $1)", "JOHN")
}
func TestStringNOT_LIKE(t *testing.T) {
assertClauseSerialize(t, table3StrCol.NOT_LIKE(table2ColStr), "(table3.col2 NOT LIKE table2.col_str)")
assertClauseSerialize(t, table3StrCol.NOT_LIKE(String("JOHN")), "(table3.col2 NOT LIKE $1)", "JOHN")
}
func TestStringSIMILAR_TO(t *testing.T) {
assertClauseSerialize(t, table3StrCol.SIMILAR_TO(table2ColStr), "(table3.col2 SIMILAR TO table2.col_str)")
assertClauseSerialize(t, table3StrCol.SIMILAR_TO(String("JOHN")), "(table3.col2 SIMILAR TO $1)", "JOHN")
}
func TestStringNOT_SIMILAR_TO(t *testing.T) {
assertClauseSerialize(t, table3StrCol.NOT_SIMILAR_TO(table2ColStr), "(table3.col2 NOT SIMILAR TO table2.col_str)")
assertClauseSerialize(t, table3StrCol.NOT_SIMILAR_TO(String("JOHN")), "(table3.col2 NOT SIMILAR TO $1)", "JOHN")
}
func TestStringExp(t *testing.T) {
assertClauseSerialize(t, StringExp(table2ColFloat), "table2.col_float")
assertClauseSerialize(t, StringExp(table2ColFloat).NOT_LIKE(String("abc")), "(table2.col_float NOT LIKE $1)", "abc")
}

View file

@ -7,12 +7,12 @@ import (
type table interface { type table interface {
dialect() Dialect dialect() Dialect
columns() []column columns() []IColumn
} }
type readableTable interface { type readableTable interface {
// Generates a select query on the current tableName. // Generates a select query on the current tableName.
SELECT(projection projection, projections ...projection) SelectStatement SELECT(projection Projection, projections ...Projection) SelectStatement
// Creates a inner join tableName Expression using onCondition. // Creates a inner join tableName Expression using onCondition.
INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
@ -31,8 +31,8 @@ type readableTable interface {
} }
type writableTable interface { type writableTable interface {
INSERT(columns ...column) InsertStatement INSERT(columns ...IColumn) InsertStatement
UPDATE(column column, columns ...column) UpdateStatement UPDATE(column IColumn, columns ...IColumn) UpdateStatement
DELETE() DeleteStatement DELETE() DeleteStatement
LOCK() LockStatement LOCK() LockStatement
@ -42,7 +42,7 @@ type writableTable interface {
type ReadableTable interface { type ReadableTable interface {
table table
readableTable readableTable
clause Clause
acceptsVisitor acceptsVisitor
} }
@ -50,7 +50,7 @@ type ReadableTable interface {
type WritableTable interface { type WritableTable interface {
table table
writableTable writableTable
clause Clause
acceptsVisitor acceptsVisitor
} }
@ -59,7 +59,7 @@ type Table interface {
table table
readableTable readableTable
writableTable writableTable
clause Clause
acceptsVisitor acceptsVisitor
SchemaName() string SchemaName() string
@ -72,8 +72,8 @@ type readableTableInterfaceImpl struct {
} }
// Generates a select query on the current tableName. // Generates a select query on the current tableName.
func (r *readableTableInterfaceImpl) SELECT(projection1 projection, projections ...projection) SelectStatement { func (r *readableTableInterfaceImpl) SELECT(projection1 Projection, projections ...Projection) SelectStatement {
return newSelectStatement(r.parent, append([]projection{projection1}, projections...)) return newSelectStatement(r.parent, append([]Projection{projection1}, projections...))
} }
// Creates a inner join tableName Expression using onCondition. // Creates a inner join tableName Expression using onCondition.
@ -103,11 +103,11 @@ type writableTableInterfaceImpl struct {
parent WritableTable parent WritableTable
} }
func (w *writableTableInterfaceImpl) INSERT(columns ...column) InsertStatement { func (w *writableTableInterfaceImpl) INSERT(columns ...IColumn) InsertStatement {
return newInsertStatement(w.parent, unwidColumnList(columns)) return newInsertStatement(w.parent, unwidColumnList(columns))
} }
func (w *writableTableInterfaceImpl) UPDATE(column column, columns ...column) UpdateStatement { func (w *writableTableInterfaceImpl) UPDATE(column IColumn, columns ...IColumn) UpdateStatement {
return newUpdateStatement(w.parent, unwindColumns(column, columns...)) return newUpdateStatement(w.parent, unwindColumns(column, columns...))
} }
@ -129,7 +129,7 @@ func NewTable(Dialect Dialect, schemaName, name string, columns ...Column) Table
columnList: columns, columnList: columns,
} }
for _, c := range columns { for _, c := range columns {
c.setTableName(name) c.SetTableName(name)
} }
t.readableTableInterfaceImpl.parent = t t.readableTableInterfaceImpl.parent = t
@ -153,7 +153,7 @@ func (t *tableImpl) AS(alias string) {
t.alias = alias t.alias = alias
for _, c := range t.columnList { for _, c := range t.columnList {
c.setTableName(alias) c.SetTableName(alias)
} }
} }
@ -165,8 +165,8 @@ func (t *tableImpl) TableName() string {
return t.name return t.name
} }
func (t *tableImpl) columns() []column { func (t *tableImpl) columns() []IColumn {
ret := []column{} ret := []IColumn{}
for _, col := range t.columnList { for _, col := range t.columnList {
ret = append(ret, col) ret = append(ret, col)
@ -183,17 +183,17 @@ func (t *tableImpl) accept(visitor visitor) {
visitor.visit(t) visitor.visit(t)
} }
func (t *tableImpl) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) error { func (t *tableImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
if t == nil { if t == nil {
return errors.New("jet: tableImpl is nil. ") return errors.New("jet: tableImpl is nil. ")
} }
out.writeIdentifier(t.schemaName) out.writeIdentifier(t.schemaName)
out.writeString(".") out.WriteString(".")
out.writeIdentifier(t.name) out.writeIdentifier(t.name)
if len(t.alias) > 0 { if len(t.alias) > 0 {
out.writeString("AS") out.WriteString("AS")
out.writeIdentifier(t.alias) out.writeIdentifier(t.alias)
} }
@ -246,7 +246,7 @@ func (t *joinTable) TableName() string {
return "" return ""
} }
func (t *joinTable) columns() []column { func (t *joinTable) columns() []IColumn {
return append(t.lhs.columns(), t.rhs.columns()...) return append(t.lhs.columns(), t.rhs.columns()...)
} }
@ -259,7 +259,7 @@ func (t *joinTable) dialect() Dialect {
return detectDialect(t) return detectDialect(t)
} }
func (t *joinTable) serialize(statement statementType, out *sqlBuilder, options ...serializeOption) (err error) { func (t *joinTable) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) (err error) {
if t == nil { if t == nil {
return errors.New("jet: Join table is nil. ") return errors.New("jet: Join table is nil. ")
} }
@ -276,15 +276,15 @@ func (t *joinTable) serialize(statement statementType, out *sqlBuilder, options
switch t.joinType { switch t.joinType {
case innerJoin: case innerJoin:
out.writeString("INNER JOIN") out.WriteString("INNER JOIN")
case leftJoin: case leftJoin:
out.writeString("LEFT JOIN") out.WriteString("LEFT JOIN")
case rightJoin: case rightJoin:
out.writeString("RIGHT JOIN") out.WriteString("RIGHT JOIN")
case fullJoin: case fullJoin:
out.writeString("FULL JOIN") out.WriteString("FULL JOIN")
case crossJoin: case crossJoin:
out.writeString("CROSS JOIN") out.WriteString("CROSS JOIN")
} }
if utils.IsNil(t.rhs) { if utils.IsNil(t.rhs) {
@ -300,7 +300,7 @@ func (t *joinTable) serialize(statement statementType, out *sqlBuilder, options
} }
if t.onCondition != nil { if t.onCondition != nil {
out.writeString("ON") out.WriteString("ON")
if err = t.onCondition.serialize(statement, out); err != nil { if err = t.onCondition.serialize(statement, out); err != nil {
return return
} }
@ -309,11 +309,11 @@ func (t *joinTable) serialize(statement statementType, out *sqlBuilder, options
return nil return nil
} }
func unwindColumns(column1 column, columns ...column) []column { func unwindColumns(column1 IColumn, columns ...IColumn) []IColumn {
columnList := []column{} columnList := []IColumn{}
if val, ok := column1.(ColumnList); ok { if val, ok := column1.(IColumnList); ok {
for _, col := range val { for _, col := range val.Columns() {
columnList = append(columnList, col) columnList = append(columnList, col)
} }
columnList = append(columnList, columns...) columnList = append(columnList, columns...)
@ -325,12 +325,12 @@ func unwindColumns(column1 column, columns ...column) []column {
return columnList return columnList
} }
func unwidColumnList(columns []column) []column { func unwidColumnList(columns []IColumn) []IColumn {
ret := []column{} ret := []IColumn{}
for _, col := range columns { for _, col := range columns {
if columnList, ok := col.(ColumnList); ok { if columnList, ok := col.(IColumnList); ok {
for _, c := range columnList { for _, c := range columnList.Columns() {
ret = append(ret, c) ret = append(ret, c)
} }
} else { } else {

View file

@ -12,17 +12,17 @@ func TestJoinNilInputs(t *testing.T) {
} }
func TestINNER_JOIN(t *testing.T) { func TestINNER_JOIN(t *testing.T) {
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
INNER_JOIN(table2, table1ColInt.EQ(table2ColInt)), INNER_JOIN(table2, table1ColInt.EQ(table2ColInt)),
`db.table1 `db.table1
INNER JOIN db.table2 ON (table1.col_int = table2.col_int)`) INNER JOIN db.table2 ON (table1.col_int = table2.col_int)`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
INNER_JOIN(table2, table1ColInt.EQ(table2ColInt)). INNER_JOIN(table2, table1ColInt.EQ(table2ColInt)).
INNER_JOIN(table3, table1ColInt.EQ(table3ColInt)), INNER_JOIN(table3, table1ColInt.EQ(table3ColInt)),
`db.table1 `db.table1
INNER JOIN db.table2 ON (table1.col_int = table2.col_int) INNER JOIN db.table2 ON (table1.col_int = table2.col_int)
INNER JOIN db.table3 ON (table1.col_int = table3.col_int)`) INNER JOIN db.table3 ON (table1.col_int = table3.col_int)`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
INNER_JOIN(table2, table1ColInt.EQ(Int(1))). INNER_JOIN(table2, table1ColInt.EQ(Int(1))).
INNER_JOIN(table3, table1ColInt.EQ(Int(2))), INNER_JOIN(table3, table1ColInt.EQ(Int(2))),
`db.table1 `db.table1
@ -31,17 +31,17 @@ INNER JOIN db.table3 ON (table1.col_int = $2)`, int64(1), int64(2))
} }
func TestLEFT_JOIN(t *testing.T) { func TestLEFT_JOIN(t *testing.T) {
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
LEFT_JOIN(table2, table1ColInt.EQ(table2ColInt)), LEFT_JOIN(table2, table1ColInt.EQ(table2ColInt)),
`db.table1 `db.table1
LEFT JOIN db.table2 ON (table1.col_int = table2.col_int)`) LEFT JOIN db.table2 ON (table1.col_int = table2.col_int)`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
LEFT_JOIN(table2, table1ColInt.EQ(table2ColInt)). LEFT_JOIN(table2, table1ColInt.EQ(table2ColInt)).
LEFT_JOIN(table3, table1ColInt.EQ(table3ColInt)), LEFT_JOIN(table3, table1ColInt.EQ(table3ColInt)),
`db.table1 `db.table1
LEFT JOIN db.table2 ON (table1.col_int = table2.col_int) LEFT JOIN db.table2 ON (table1.col_int = table2.col_int)
LEFT JOIN db.table3 ON (table1.col_int = table3.col_int)`) LEFT JOIN db.table3 ON (table1.col_int = table3.col_int)`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
LEFT_JOIN(table2, table1ColInt.EQ(Int(1))). LEFT_JOIN(table2, table1ColInt.EQ(Int(1))).
LEFT_JOIN(table3, table1ColInt.EQ(Int(2))), LEFT_JOIN(table3, table1ColInt.EQ(Int(2))),
`db.table1 `db.table1
@ -50,17 +50,17 @@ LEFT JOIN db.table3 ON (table1.col_int = $2)`, int64(1), int64(2))
} }
func TestRIGHT_JOIN(t *testing.T) { func TestRIGHT_JOIN(t *testing.T) {
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
RIGHT_JOIN(table2, table1ColInt.EQ(table2ColInt)), RIGHT_JOIN(table2, table1ColInt.EQ(table2ColInt)),
`db.table1 `db.table1
RIGHT JOIN db.table2 ON (table1.col_int = table2.col_int)`) RIGHT JOIN db.table2 ON (table1.col_int = table2.col_int)`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
RIGHT_JOIN(table2, table1ColInt.EQ(table2ColInt)). RIGHT_JOIN(table2, table1ColInt.EQ(table2ColInt)).
RIGHT_JOIN(table3, table1ColInt.EQ(table3ColInt)), RIGHT_JOIN(table3, table1ColInt.EQ(table3ColInt)),
`db.table1 `db.table1
RIGHT JOIN db.table2 ON (table1.col_int = table2.col_int) RIGHT JOIN db.table2 ON (table1.col_int = table2.col_int)
RIGHT JOIN db.table3 ON (table1.col_int = table3.col_int)`) RIGHT JOIN db.table3 ON (table1.col_int = table3.col_int)`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
RIGHT_JOIN(table2, table1ColInt.EQ(Int(1))). RIGHT_JOIN(table2, table1ColInt.EQ(Int(1))).
RIGHT_JOIN(table3, table1ColInt.EQ(Int(2))), RIGHT_JOIN(table3, table1ColInt.EQ(Int(2))),
`db.table1 `db.table1
@ -69,17 +69,17 @@ RIGHT JOIN db.table3 ON (table1.col_int = $2)`, int64(1), int64(2))
} }
func TestFULL_JOIN(t *testing.T) { func TestFULL_JOIN(t *testing.T) {
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
FULL_JOIN(table2, table1ColInt.EQ(table2ColInt)), FULL_JOIN(table2, table1ColInt.EQ(table2ColInt)),
`db.table1 `db.table1
FULL JOIN db.table2 ON (table1.col_int = table2.col_int)`) FULL JOIN db.table2 ON (table1.col_int = table2.col_int)`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
FULL_JOIN(table2, table1ColInt.EQ(table2ColInt)). FULL_JOIN(table2, table1ColInt.EQ(table2ColInt)).
FULL_JOIN(table3, table1ColInt.EQ(table3ColInt)), FULL_JOIN(table3, table1ColInt.EQ(table3ColInt)),
`db.table1 `db.table1
FULL JOIN db.table2 ON (table1.col_int = table2.col_int) FULL JOIN db.table2 ON (table1.col_int = table2.col_int)
FULL JOIN db.table3 ON (table1.col_int = table3.col_int)`) FULL JOIN db.table3 ON (table1.col_int = table3.col_int)`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
FULL_JOIN(table2, table1ColInt.EQ(Int(1))). FULL_JOIN(table2, table1ColInt.EQ(Int(1))).
FULL_JOIN(table3, table1ColInt.EQ(Int(2))), FULL_JOIN(table3, table1ColInt.EQ(Int(2))),
`db.table1 `db.table1
@ -88,11 +88,11 @@ FULL JOIN db.table3 ON (table1.col_int = $2)`, int64(1), int64(2))
} }
func TestCROSS_JOIN(t *testing.T) { func TestCROSS_JOIN(t *testing.T) {
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
CROSS_JOIN(table2), CROSS_JOIN(table2),
`db.table1 `db.table1
CROSS JOIN db.table2`) CROSS JOIN db.table2`)
AssertPostgreClauseSerialize(t, table1. assertClauseSerialize(t, table1.
CROSS_JOIN(table2). CROSS_JOIN(table2).
CROSS_JOIN(table3), CROSS_JOIN(table3),
`db.table1 `db.table1

View file

@ -1,6 +1,7 @@
package jet package jet
import ( import (
"fmt"
"gotest.tools/assert" "gotest.tools/assert"
"testing" "testing"
) )
@ -17,7 +18,7 @@ var table1ColBool = BoolColumn("col_bool")
var table1ColDate = DateColumn("col_date") var table1ColDate = DateColumn("col_date")
var table1 = NewTable( var table1 = NewTable(
PostgreSQL, ANSII,
"db", "db",
"table1", "table1",
table1Col1, table1Col1,
@ -45,7 +46,7 @@ var table2ColTimestampz = TimestampzColumn("col_timestampz")
var table2ColDate = DateColumn("col_date") var table2ColDate = DateColumn("col_date")
var table2 = NewTable( var table2 = NewTable(
PostgreSQL, ANSII,
"db", "db",
"table2", "table2",
table2Col3, table2Col3,
@ -65,73 +66,62 @@ var table3Col1 = IntegerColumn("col1")
var table3ColInt = IntegerColumn("col_int") var table3ColInt = IntegerColumn("col_int")
var table3StrCol = StringColumn("col2") var table3StrCol = StringColumn("col2")
var table3 = NewTable( var table3 = NewTable(
PostgreSQL, ANSII,
"db", "db",
"table3", "table3",
table3Col1, table3Col1,
table3ColInt, table3ColInt,
table3StrCol) table3StrCol)
func AssertClauseSerialize(t *testing.T, clause clause, query string, args ...interface{}) { func assertClauseSerialize(t *testing.T, clause Clause, query string, args ...interface{}) {
out := sqlBuilder{dialect: Default} out := SqlBuilder{Dialect: ANSII}
err := clause.serialize(selectStatement, &out) err := clause.serialize(SelectStatementType, &out)
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, out.buff.String(), query) assert.DeepEqual(t, out.DebugSQL(), query)
assert.DeepEqual(t, out.args, args)
if len(args) > 0 {
assert.DeepEqual(t, out.Args, args)
} }
func AssertPostgreClauseSerialize(t *testing.T, clause clause, query string, args ...interface{}) {
out := sqlBuilder{dialect: PostgreSQL}
err := clause.serialize(selectStatement, &out)
assert.NilError(t, err)
assert.DeepEqual(t, out.buff.String(), query)
assert.DeepEqual(t, out.args, args)
} }
func AssertMySQLClauseSerialize(t *testing.T, clause clause, query string, args ...interface{}) { func assertClauseSerializeErr(t *testing.T, clause Clause, errString string) {
out := sqlBuilder{dialect: MySQL} out := SqlBuilder{Dialect: ANSII}
err := clause.serialize(selectStatement, &out) err := clause.serialize(SelectStatementType, &out)
assert.NilError(t, err)
assert.DeepEqual(t, out.buff.String(), query)
assert.DeepEqual(t, out.args, args)
}
func assertClauseSerializeErr(t *testing.T, clause clause, errString string) {
out := sqlBuilder{dialect: PostgreSQL}
err := clause.serialize(selectStatement, &out)
//fmt.Println(out.buff.String()) //fmt.Println(out.buff.String())
assert.Assert(t, err != nil) assert.Assert(t, err != nil)
assert.Error(t, err, errString) assert.Error(t, err, errString)
} }
func assertProjectionSerialize(t *testing.T, projection projection, query string, args ...interface{}) { func assertProjectionSerialize(t *testing.T, projection Projection, query string, args ...interface{}) {
out := sqlBuilder{dialect: PostgreSQL} out := SqlBuilder{Dialect: ANSII}
err := projection.serializeForProjection(selectStatement, &out) err := projection.serializeForProjection(SelectStatementType, &out)
assert.NilError(t, err) assert.NilError(t, err)
assert.DeepEqual(t, out.buff.String(), query) assert.DeepEqual(t, out.DebugSQL(), query)
assert.DeepEqual(t, out.args, args)
if len(args) > 0 {
assert.DeepEqual(t, out.Args, args)
}
} }
func assertStatement(t *testing.T, query Statement, expectedQuery string, expectedArgs ...interface{}) { func assertStatement(t *testing.T, query Statement, expectedQuery string, expectedArgs ...interface{}) {
queryStr, args, err := query.Sql(PostgreSQL) queryStr, err := query.DebugSql()
assert.NilError(t, err) assert.NilError(t, err)
fmt.Println(queryStr)
//fmt.Println(queryStr) //fmt.Println(queryStr)
assert.Equal(t, queryStr, expectedQuery) assert.Equal(t, queryStr, expectedQuery)
assert.DeepEqual(t, args, expectedArgs) //assert.DeepEqual(t, args, expectedArgs)
} }
func assertStatementErr(t *testing.T, stmt Statement, errorStr string) { func assertStatementErr(t *testing.T, stmt Statement, errorStr string) {
_, _, err := stmt.Sql(PostgreSQL) _, _, err := stmt.Sql(ANSII)
assert.Assert(t, err != nil) assert.Assert(t, err != nil)
assert.Error(t, err, errorStr) assert.Error(t, err, errorStr)

View file

@ -0,0 +1,53 @@
package jet
import (
"testing"
)
var timeVar = Time(10, 20, 0, 0)
func TestTimeExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColTime.EQ(table2ColTime), "(table1.col_time = table2.col_time)")
assertClauseSerialize(t, table1ColTime.EQ(timeVar), "(table1.col_time = $1)", "10:20:00.000")
}
func TestTimeExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTime.NOT_EQ(table2ColTime), "(table1.col_time != table2.col_time)")
assertClauseSerialize(t, table1ColTime.NOT_EQ(timeVar), "(table1.col_time != $1)", "10:20:00.000")
}
func TestTimeExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTime.IS_DISTINCT_FROM(table2ColTime), "(table1.col_time IS DISTINCT FROM table2.col_time)")
assertClauseSerialize(t, table1ColTime.IS_DISTINCT_FROM(timeVar), "(table1.col_time IS DISTINCT FROM $1)", "10:20:00.000")
}
func TestTimeExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTime.IS_NOT_DISTINCT_FROM(table2ColTime), "(table1.col_time IS NOT DISTINCT FROM table2.col_time)")
assertClauseSerialize(t, table1ColTime.IS_NOT_DISTINCT_FROM(timeVar), "(table1.col_time IS NOT DISTINCT FROM $1)", "10:20:00.000")
}
func TestTimeExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColTime.LT(table2ColTime), "(table1.col_time < table2.col_time)")
assertClauseSerialize(t, table1ColTime.LT(timeVar), "(table1.col_time < $1)", "10:20:00.000")
}
func TestTimeExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTime.LT_EQ(table2ColTime), "(table1.col_time <= table2.col_time)")
assertClauseSerialize(t, table1ColTime.LT_EQ(timeVar), "(table1.col_time <= $1)", "10:20:00.000")
}
func TestTimeExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColTime.GT(table2ColTime), "(table1.col_time > table2.col_time)")
assertClauseSerialize(t, table1ColTime.GT(timeVar), "(table1.col_time > $1)", "10:20:00.000")
}
func TestTimeExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTime.GT_EQ(table2ColTime), "(table1.col_time >= table2.col_time)")
assertClauseSerialize(t, table1ColTime.GT_EQ(timeVar), "(table1.col_time >= $1)", "10:20:00.000")
}
func TestTimeExp(t *testing.T) {
assertClauseSerialize(t, TimeExp(table1ColFloat), "table1.col_float")
assertClauseSerialize(t, TimeExp(table1ColFloat).LT(Time(1, 1, 1, 1)),
"(table1.col_float < $1)", string("01:01:01.001"))
}

View file

@ -0,0 +1,52 @@
package jet
import "testing"
var timestamp = Timestamp(2000, 1, 31, 10, 20, 0, 0)
func TestTimestampExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.EQ(table2ColTimestamp), "(table1.col_timestamp = table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.EQ(timestamp),
"(table1.col_timestamp = $1)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.NOT_EQ(table2ColTimestamp), "(table1.col_timestamp != table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.NOT_EQ(timestamp), "(table1.col_timestamp != $1)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.IS_DISTINCT_FROM(table2ColTimestamp), "(table1.col_timestamp IS DISTINCT FROM table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.IS_DISTINCT_FROM(timestamp), "(table1.col_timestamp IS DISTINCT FROM $1)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.IS_NOT_DISTINCT_FROM(table2ColTimestamp), "(table1.col_timestamp IS NOT DISTINCT FROM table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.IS_NOT_DISTINCT_FROM(timestamp), "(table1.col_timestamp IS NOT DISTINCT FROM $1)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.LT(table2ColTimestamp), "(table1.col_timestamp < table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.LT(timestamp), "(table1.col_timestamp < $1)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.LT_EQ(table2ColTimestamp), "(table1.col_timestamp <= table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.LT_EQ(timestamp), "(table1.col_timestamp <= $1)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.GT(table2ColTimestamp), "(table1.col_timestamp > table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.GT(timestamp), "(table1.col_timestamp > $1)", "2000-01-31 10:20:00.000")
}
func TestTimestampExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestamp.GT_EQ(table2ColTimestamp), "(table1.col_timestamp >= table2.col_timestamp)")
assertClauseSerialize(t, table1ColTimestamp.GT_EQ(timestamp), "(table1.col_timestamp >= $1)", "2000-01-31 10:20:00.000")
}
func TestTimestampExp(t *testing.T) {
assertClauseSerialize(t, TimestampExp(table1ColFloat), "table1.col_float")
assertClauseSerialize(t, TimestampExp(table1ColFloat).LT(timestamp),
"(table1.col_float < $1)", "2000-01-31 10:20:00.000")
}

View file

@ -0,0 +1,54 @@
// +build todo
package jet
import "testing"
var timestampz = Timestampz(2000, 1, 31, 10, 20, 0, 0, 2)
func TestTimestampzExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestampz.EQ(table2ColTimestampz), "(table1.col_timestampz = table2.col_timestampz)")
assertClauseSerialize(t, table1ColTimestampz.EQ(timestampz),
"(table1.col_timestampz = $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}
func TestTimestampzExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestampz.NOT_EQ(table2ColTimestampz), "(table1.col_timestampz != table2.col_timestampz)")
assertClauseSerialize(t, table1ColTimestampz.NOT_EQ(timestampz), "(table1.col_timestampz != $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}
func TestTimestampzExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTimestampz.IS_DISTINCT_FROM(table2ColTimestampz), "(table1.col_timestampz IS DISTINCT FROM table2.col_timestampz)")
assertClauseSerialize(t, table1ColTimestampz.IS_DISTINCT_FROM(timestampz), "(table1.col_timestampz IS DISTINCT FROM $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}
func TestTimestampzExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTimestampz.IS_NOT_DISTINCT_FROM(table2ColTimestampz), "(table1.col_timestampz IS NOT DISTINCT FROM table2.col_timestampz)")
assertClauseSerialize(t, table1ColTimestampz.IS_NOT_DISTINCT_FROM(timestampz), "(table1.col_timestampz IS NOT DISTINCT FROM $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}
func TestTimestampzExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColTimestampz.LT(table2ColTimestampz), "(table1.col_timestampz < table2.col_timestampz)")
assertClauseSerialize(t, table1ColTimestampz.LT(timestampz), "(table1.col_timestampz < $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}
func TestTimestampzExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestampz.LT_EQ(table2ColTimestampz), "(table1.col_timestampz <= table2.col_timestampz)")
assertClauseSerialize(t, table1ColTimestampz.LT_EQ(timestampz), "(table1.col_timestampz <= $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}
func TestTimestampzExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColTimestampz.GT(table2ColTimestampz), "(table1.col_timestampz > table2.col_timestampz)")
assertClauseSerialize(t, table1ColTimestampz.GT(timestampz), "(table1.col_timestampz > $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}
func TestTimestampzExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimestampz.GT_EQ(table2ColTimestampz), "(table1.col_timestampz >= table2.col_timestampz)")
assertClauseSerialize(t, table1ColTimestampz.GT_EQ(timestampz), "(table1.col_timestampz >= $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}
func TestTimestampzExp(t *testing.T) {
assertClauseSerialize(t, TimestampzExp(table1ColFloat), "table1.col_float")
assertClauseSerialize(t, TimestampzExp(table1ColFloat).LT(timestampz),
"(table1.col_float < $1::timestamp with time zone)", "2000-01-31 10:20:00.000 +002")
}

View file

@ -0,0 +1,53 @@
// +build TODO
package jet
import "testing"
var timezVar = Timez(10, 20, 0, 0, 4)
func TestTimezExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimez.EQ(table2ColTimez), "(table1.col_timez = table2.col_timez)")
assertClauseSerialize(t, table1ColTimez.EQ(timezVar), "(table1.col_timez = $1::time with time zone)", "10:20:00.000 +04")
}
func TestTimezExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimez.NOT_EQ(table2ColTimez), "(table1.col_timez != table2.col_timez)")
assertClauseSerialize(t, table1ColTimez.NOT_EQ(timezVar), "(table1.col_timez != $1::time with time zone)", "10:20:00.000 +04")
}
func TestTimezExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTimez.IS_DISTINCT_FROM(table2ColTimez), "(table1.col_timez IS DISTINCT FROM table2.col_timez)")
assertClauseSerialize(t, table1ColTimez.IS_DISTINCT_FROM(timezVar), "(table1.col_timez IS DISTINCT FROM $1::time with time zone)", "10:20:00.000 +04")
}
func TestTimezExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColTimez.IS_NOT_DISTINCT_FROM(table2ColTimez), "(table1.col_timez IS NOT DISTINCT FROM table2.col_timez)")
assertClauseSerialize(t, table1ColTimez.IS_NOT_DISTINCT_FROM(timezVar), "(table1.col_timez IS NOT DISTINCT FROM $1::time with time zone)", "10:20:00.000 +04")
}
func TestTimezExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColTimez.LT(table2ColTimez), "(table1.col_timez < table2.col_timez)")
assertClauseSerialize(t, table1ColTimez.LT(timezVar), "(table1.col_timez < $1::time with time zone)", "10:20:00.000 +04")
}
func TestTimezExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimez.LT_EQ(table2ColTimez), "(table1.col_timez <= table2.col_timez)")
assertClauseSerialize(t, table1ColTimez.LT_EQ(timezVar), "(table1.col_timez <= $1::time with time zone)", "10:20:00.000 +04")
}
func TestTimezExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColTimez.GT(table2ColTimez), "(table1.col_timez > table2.col_timez)")
assertClauseSerialize(t, table1ColTimez.GT(timezVar), "(table1.col_timez > $1::time with time zone)", "10:20:00.000 +04")
}
func TestTimezExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColTimez.GT_EQ(table2ColTimez), "(table1.col_timez >= table2.col_timez)")
assertClauseSerialize(t, table1ColTimez.GT_EQ(timezVar), "(table1.col_timez >= $1::time with time zone)", "10:20:00.000 +04")
}
func TestTimezExp(t *testing.T) {
assertClauseSerialize(t, TimezExp(table1ColFloat), "table1.col_float")
assertClauseSerialize(t, TimezExp(table1ColFloat).LT(Timez(1, 1, 1, 1, 4)),
"(table1.col_float < $1::time with time zone)", string("01:01:01.001 +04"))
}

View file

@ -16,23 +16,23 @@ type UpdateStatement interface {
MODEL(data interface{}) UpdateStatement MODEL(data interface{}) UpdateStatement
WHERE(expression BoolExpression) UpdateStatement WHERE(expression BoolExpression) UpdateStatement
RETURNING(projections ...projection) UpdateStatement RETURNING(projections ...Projection) UpdateStatement
} }
func newUpdateStatement(table WritableTable, columns []column) UpdateStatement { func newUpdateStatement(table WritableTable, columns []IColumn) UpdateStatement {
return &updateStatementImpl{ return &updateStatementImpl{
table: table, table: table,
columns: columns, columns: columns,
values: make([]clause, 0, len(columns)), values: make([]Clause, 0, len(columns)),
} }
} }
type updateStatementImpl struct { type updateStatementImpl struct {
table WritableTable table WritableTable
columns []column columns []IColumn
values []clause values []Clause
where BoolExpression where BoolExpression
returning []projection returning []Projection
} }
func (u *updateStatementImpl) SET(value interface{}, values ...interface{}) UpdateStatement { func (u *updateStatementImpl) SET(value interface{}, values ...interface{}) UpdateStatement {
@ -52,7 +52,7 @@ func (u *updateStatementImpl) WHERE(expression BoolExpression) UpdateStatement {
return u return u
} }
func (u *updateStatementImpl) RETURNING(projections ...projection) UpdateStatement { func (u *updateStatementImpl) RETURNING(projections ...Projection) UpdateStatement {
u.returning = projections u.returning = projections
return u return u
} }
@ -63,18 +63,18 @@ func (u *updateStatementImpl) accept(visitor visitor) {
} }
func (u *updateStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) { func (u *updateStatementImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) {
out := &sqlBuilder{ out := &SqlBuilder{
dialect: detectDialect(u, dialect...), Dialect: detectDialect(u, dialect...),
} }
out.newLine() out.newLine()
out.writeString("UPDATE") out.WriteString("UPDATE")
if utils.IsNil(u.table) { if utils.IsNil(u.table) {
return "", nil, errors.New("jet: table to update is nil") return "", nil, errors.New("jet: table to update is nil")
} }
if err = u.table.serialize(updateStatement, out); err != nil { if err = u.table.serialize(UpdateStatementType, out); err != nil {
return return
} }
@ -87,9 +87,9 @@ func (u *updateStatementImpl) Sql(dialect ...Dialect) (query string, args []inte
} }
out.newLine() out.newLine()
out.writeString("SET") out.WriteString("SET")
if err = out.dialect.UpdateAssigment(u.columns, u.values, out); err != nil { if err = out.Dialect.UpdateAssigment()(u.columns, u.values, out); err != nil {
return return
} }
@ -97,11 +97,11 @@ func (u *updateStatementImpl) Sql(dialect ...Dialect) (query string, args []inte
return "", nil, errors.New("jet: WHERE clause not set") return "", nil, errors.New("jet: WHERE clause not set")
} }
if err = out.writeWhere(updateStatement, u.where); err != nil { if err = out.writeWhere(UpdateStatementType, u.where); err != nil {
return return
} }
if err = out.writeReturning(updateStatement, u.returning); err != nil { if err = out.writeReturning(UpdateStatementType, u.returning); err != nil {
return return
} }

View file

@ -7,11 +7,11 @@ import (
"strings" "strings"
) )
func serializeOrderByClauseList(statement statementType, orderByClauses []orderByClause, out *sqlBuilder) error { func serializeOrderByClauseList(statement StatementType, orderByClauses []orderByClause, out *SqlBuilder) error {
for i, value := range orderByClauses { for i, value := range orderByClauses {
if i > 0 { if i > 0 {
out.writeString(", ") out.WriteString(", ")
} }
err := value.serializeForOrderBy(statement, out) err := value.serializeForOrderBy(statement, out)
@ -24,11 +24,11 @@ func serializeOrderByClauseList(statement statementType, orderByClauses []orderB
return nil return nil
} }
func serializeGroupByClauseList(statement statementType, clauses []groupByClause, out *sqlBuilder) (err error) { func serializeGroupByClauseList(statement StatementType, clauses []groupByClause, out *SqlBuilder) (err error) {
for i, c := range clauses { for i, c := range clauses {
if i > 0 { if i > 0 {
out.writeString(", ") out.WriteString(", ")
} }
if c == nil { if c == nil {
@ -43,11 +43,11 @@ func serializeGroupByClauseList(statement statementType, clauses []groupByClause
return nil return nil
} }
func serializeClauseList(statement statementType, clauses []clause, out *sqlBuilder) (err error) { func SerializeClauseList(statement StatementType, clauses []Clause, out *SqlBuilder) (err error) {
for i, c := range clauses { for i, c := range clauses {
if i > 0 { if i > 0 {
out.writeString(", ") out.WriteString(", ")
} }
if c == nil { if c == nil {
@ -62,11 +62,11 @@ func serializeClauseList(statement statementType, clauses []clause, out *sqlBuil
return nil return nil
} }
func serializeExpressionList(statement statementType, expressions []Expression, separator string, out *sqlBuilder) error { func serializeExpressionList(statement StatementType, expressions []Expression, separator string, out *SqlBuilder) error {
for i, value := range expressions { for i, value := range expressions {
if i > 0 { if i > 0 {
out.writeString(separator) out.WriteString(separator)
} }
err := value.serialize(statement, out) err := value.serialize(statement, out)
@ -79,15 +79,15 @@ func serializeExpressionList(statement statementType, expressions []Expression,
return nil return nil
} }
func serializeProjectionList(statement statementType, projections []projection, out *sqlBuilder) error { func SerializeProjectionList(statement StatementType, projections []Projection, out *SqlBuilder) error {
for i, col := range projections { for i, col := range projections {
if i > 0 { if i > 0 {
out.writeString(",") out.WriteString(",")
out.newLine() out.newLine()
} }
if col == nil { if col == nil {
return errors.New("jet: projection is nil") return errors.New("jet: Projection is nil")
} }
if err := col.serializeForProjection(statement, out); err != nil { if err := col.serializeForProjection(statement, out); err != nil {
@ -98,24 +98,24 @@ func serializeProjectionList(statement statementType, projections []projection,
return nil return nil
} }
func serializeColumnNames(columns []column, out *sqlBuilder) error { func SerializeColumnNames(columns []IColumn, out *SqlBuilder) error {
for i, col := range columns { for i, col := range columns {
if i > 0 { if i > 0 {
out.writeString(", ") out.WriteString(", ")
} }
if col == nil { if col == nil {
return errors.New("jet: nil column in columns list") return errors.New("jet: nil column in columns list")
} }
out.writeString(col.Name()) out.WriteString(col.Name())
} }
return nil return nil
} }
func columnListToProjectionList(columns []Column) []projection { func ColumnListToProjectionList(columns []Column) []Projection {
var ret []projection var ret []Projection
for _, column := range columns { for _, column := range columns {
ret = append(ret, column) ret = append(ret, column)
@ -124,18 +124,18 @@ func columnListToProjectionList(columns []Column) []projection {
return ret return ret
} }
func valueToClause(value interface{}) clause { func valueToClause(value interface{}) Clause {
if clause, ok := value.(clause); ok { if clause, ok := value.(Clause); ok {
return clause return clause
} }
return literal(value) return literal(value)
} }
func unwindRowFromModel(columns []column, data interface{}) []clause { func unwindRowFromModel(columns []IColumn, data interface{}) []Clause {
structValue := reflect.Indirect(reflect.ValueOf(data)) structValue := reflect.Indirect(reflect.ValueOf(data))
row := []clause{} row := []Clause{}
mustBe(structValue, reflect.Struct) mustBe(structValue, reflect.Struct)
@ -163,11 +163,11 @@ func unwindRowFromModel(columns []column, data interface{}) []clause {
return row return row
} }
func unwindRowsFromModels(columns []column, data interface{}) [][]clause { func unwindRowsFromModels(columns []IColumn, data interface{}) [][]Clause {
sliceValue := reflect.Indirect(reflect.ValueOf(data)) sliceValue := reflect.Indirect(reflect.ValueOf(data))
mustBe(sliceValue, reflect.Slice) mustBe(sliceValue, reflect.Slice)
rows := [][]clause{} rows := [][]Clause{}
for i := 0; i < sliceValue.Len(); i++ { for i := 0; i < sliceValue.Len(); i++ {
structValue := sliceValue.Index(i) structValue := sliceValue.Index(i)
@ -178,8 +178,8 @@ func unwindRowsFromModels(columns []column, data interface{}) [][]clause {
return rows return rows
} }
func unwindRowFromValues(value interface{}, values []interface{}) []clause { func unwindRowFromValues(value interface{}, values []interface{}) []Clause {
row := []clause{} row := []Clause{}
allValues := append([]interface{}{value}, values...) allValues := append([]interface{}{value}, values...)

View file

@ -47,7 +47,7 @@ func (f *DialectFinder) visit(element acceptsVisitor) {
if table, ok := element.(table); ok { if table, ok := element.(table); ok {
dialect := table.dialect() dialect := table.dialect()
f.dialects[dialect.Name] = dialect f.dialects[dialect.Name()] = dialect
} }
} }

View file

@ -4,8 +4,8 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/go-jet/jet"
"github.com/go-jet/jet/execution" "github.com/go-jet/jet/execution"
"github.com/go-jet/jet/internal/jet"
"gotest.tools/assert" "gotest.tools/assert"
"io/ioutil" "io/ioutil"
"runtime" "runtime"

View file

@ -1,7 +0,0 @@
package jet
import "testing"
func TestRawExpression(t *testing.T) {
AssertPostgreClauseSerialize(t, RAW("current_database()"), "current_database()")
}

View file

@ -1,32 +0,0 @@
package jet
import (
"testing"
)
func TestLockTable(t *testing.T) {
assertStatement(t, table1.LOCK().IN(LOCK_ACCESS_SHARE), `
LOCK TABLE db.table1 IN ACCESS SHARE MODE;
`)
assertStatement(t, table1.LOCK().IN(LOCK_ROW_SHARE), `
LOCK TABLE db.table1 IN ROW SHARE MODE;
`)
assertStatement(t, table1.LOCK().IN(LOCK_ROW_EXCLUSIVE), `
LOCK TABLE db.table1 IN ROW EXCLUSIVE MODE;
`)
assertStatement(t, table1.LOCK().IN(LOCK_SHARE_UPDATE_EXCLUSIVE), `
LOCK TABLE db.table1 IN SHARE UPDATE EXCLUSIVE MODE;
`)
assertStatement(t, table1.LOCK().IN(LOCK_SHARE), `
LOCK TABLE db.table1 IN SHARE MODE;
`)
assertStatement(t, table1.LOCK().IN(LOCK_SHARE_ROW_EXCLUSIVE), `
LOCK TABLE db.table1 IN SHARE ROW EXCLUSIVE MODE;
`)
assertStatement(t, table1.LOCK().IN(LOCK_EXCLUSIVE), `
LOCK TABLE db.table1 IN EXCLUSIVE MODE;
`)
assertStatement(t, table1.LOCK().IN(LOCK_ACCESS_EXCLUSIVE), `
LOCK TABLE db.table1 IN ACCESS EXCLUSIVE MODE;
`)
}

View file

@ -0,0 +1,89 @@
package mysql
import (
"testing"
)
func TestBoolExpressionEQ(t *testing.T) {
assertClauseSerializeErr(t, table1ColBool.EQ(nil), "jet: nil rhs")
assertClauseSerialize(t, table1ColBool.EQ(table2ColBool), "(table1.col_bool = table2.col_bool)")
assertClauseSerialize(t, table1ColBool.EQ(Bool(true)), "(table1.col_bool = ?)", true)
}
func TestBoolExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColBool.NOT_EQ(table2ColBool), "(table1.col_bool != table2.col_bool)")
assertClauseSerialize(t, table1ColBool.NOT_EQ(Bool(true)), "(table1.col_bool != ?)", true)
}
func TestBoolExpressionIS_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(table2ColBool), "(NOT table1.col_bool <=> table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_DISTINCT_FROM(Bool(false)), "(NOT table1.col_bool <=> ?)", false)
}
func TestBoolExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(table2ColBool), "(table1.col_bool <=> table2.col_bool)")
assertClauseSerialize(t, table1ColBool.IS_NOT_DISTINCT_FROM(Bool(false)), "(table1.col_bool <=> ?)", false)
}
func TestBoolExpressionIS_TRUE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_TRUE(), "table1.col_bool IS TRUE")
assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE(),
`(? = table1.col_int) IS TRUE`, int64(2))
assertClauseSerialize(t, (Int(2).EQ(table1ColInt)).IS_TRUE().AND(Int(4).EQ(table2ColInt)),
`((? = table1.col_int) IS TRUE AND (? = table2.col_int))`, int64(2), int64(4))
}
func TestBoolExpressionIS_NOT_TRUE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_TRUE(), "table1.col_bool IS NOT TRUE")
}
func TestBoolExpressionIS_FALSE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_FALSE(), "table1.col_bool IS FALSE")
}
func TestBoolExpressionIS_NOT_FALSE(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_FALSE(), "table1.col_bool IS NOT FALSE")
}
func TestBoolExpressionIS_UNKNOWN(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_UNKNOWN(), "table1.col_bool IS UNKNOWN")
}
func TestBoolExpressionIS_NOT_UNKNOWN(t *testing.T) {
assertClauseSerialize(t, table1ColBool.IS_NOT_UNKNOWN(), "table1.col_bool IS NOT UNKNOWN")
}
func TestBinaryBoolExpressionAsProjection(t *testing.T) {
boolExpression := Int(2).EQ(Int(3))
assertProjectionSerialize(t, boolExpression, "? = ?", int64(2), int64(3))
assertProjectionSerialize(t, boolExpression.AS("alias_eq_expression"),
`(? = ?) AS "alias_eq_expression"`, int64(2), int64(3))
}
func TestBoolLiteral(t *testing.T) {
assertClauseSerialize(t, Bool(true), "?", true)
assertClauseSerialize(t, Bool(false), "?", false)
}
//
//func TestExists(t *testing.T) {
//
// assertClauseSerialize(t, EXISTS(
// table2.
// SELECT(Int(1)).
// WHERE(table1Col1.EQ(table2Col3)),
// ),
// `(EXISTS (
// SELECT ?
// FROM db.table2
// WHERE table1.col1 = table2.col3
//))`, int64(1))
//}
//
//func TestBoolExp(t *testing.T) {
// assertClauseSerialize(t, BoolExp(String("true")), "?", "true")
// assertClauseSerialize(t, BoolExp(String("true")).IS_TRUE(), "? IS TRUE", "true")
//}

View file

@ -1,7 +1,7 @@
package mysql package mysql
import ( import (
"github.com/go-jet/jet" "github.com/go-jet/jet/internal/jet"
) )
type cast interface { type cast interface {

9
mysql/cast_test.go Normal file
View file

@ -0,0 +1,9 @@
package mysql
import (
"testing"
)
func TestCAST_AS_DATE(t *testing.T) {
assertClauseSerialize(t, CAST(Int(22)).AS_DATE(), `CAST(? AS DATE)`, int64(22))
}

9
mysql/column.go Normal file
View file

@ -0,0 +1,9 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
type Column jet.Column
type IColumnList jet.IColumnList
var ColumnList = jet.ColumnList

139
mysql/dialect.go Normal file
View file

@ -0,0 +1,139 @@
package mysql
import (
"errors"
"github.com/go-jet/jet/internal/jet"
)
var Dialect = NewDialect()
func NewDialect() jet.Dialect {
serializeOverrides := map[string]jet.SerializeOverride{}
serializeOverrides["IS DISTINCT FROM"] = mysql_IS_DISTINCT_FROM
serializeOverrides["IS NOT DISTINCT FROM"] = mysql_IS_NOT_DISTINCT_FROM
serializeOverrides["/"] = mysql_DIVISION
serializeOverrides["#"] = mysql_BIT_XOR
mySQLDialectParams := jet.DialectParams{
Name: "MySQL",
PackageName: "mysql",
SerializeOverrides: serializeOverrides,
AliasQuoteChar: '"',
IdentifierQuoteChar: '`',
ArgumentPlaceholder: func(int) string {
return "?"
},
UpdateAssigment: mysqlUpdateAssigment,
SupportsReturning: false,
}
return jet.NewDialect(mySQLDialectParams)
}
func mysqlUpdateAssigment(columns []jet.IColumn, values []jet.Clause, out *jet.SqlBuilder) (err error) {
if len(columns) != len(values) {
return errors.New("jet: mismatch in numers of columns and values")
}
for i, column := range columns {
if i > 0 {
out.WriteString(", ")
}
out.WriteString(column.Name())
out.WriteString(" = ")
if err = jet.Serialize(values[i], jet.UpdateStatementType, out); err != nil {
return err
}
}
return nil
}
func mysql_BIT_XOR(expressions ...jet.Expression) jet.SerializeFunc {
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
if len(expressions) != 2 {
return errors.New("jet: invalid number of expressions for operator")
}
lhs := expressions[0]
rhs := expressions[1]
if err := jet.Serialize(lhs, statement, out, options...); err != nil {
return err
}
out.WriteString("^")
if err := jet.Serialize(rhs, statement, out, options...); err != nil {
return err
}
return nil
}
}
func mysql_DIVISION(expressions ...jet.Expression) jet.SerializeFunc {
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
if len(expressions) != 2 {
return errors.New("jet: invalid number of expressions for operator")
}
lhs := expressions[0]
rhs := expressions[1]
if err := jet.Serialize(lhs, statement, out, options...); err != nil {
return err
}
_, isLhsInt := lhs.(IntegerExpression)
_, isRhsInt := rhs.(IntegerExpression)
if isLhsInt && isRhsInt {
out.WriteString("DIV")
} else {
out.WriteString("/")
}
if err := jet.Serialize(rhs, statement, out, options...); err != nil {
return err
}
return nil
}
}
func mysql_IS_NOT_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc {
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
if len(expressions) != 2 {
return errors.New("jet: invalid number of expressions for operator")
}
if err := jet.Serialize(expressions[0], statement, out); err != nil {
return err
}
out.WriteString("<=>")
if err := jet.Serialize(expressions[1], statement, out); err != nil {
return err
}
return nil
}
}
func mysql_IS_DISTINCT_FROM(expressions ...jet.Expression) jet.SerializeFunc {
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
out.WriteString("NOT")
err := mysql_IS_NOT_DISTINCT_FROM(expressions...)(statement, out, options...)
if err != nil {
return err
}
return nil
}
}

21
mysql/expressions.go Normal file
View file

@ -0,0 +1,21 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
type Expression jet.Expression
type BoolExpression jet.BoolExpression
type StringExpression jet.StringExpression
type IntegerExpression jet.IntegerExpression
type FloatExpression jet.FloatExpression
type DateExpression jet.DateExpression
type DateTimeExpression jet.TimestampExpression
type TimestampExpression jet.TimestampExpression
type TimeExpression jet.TimeExpression

View file

@ -0,0 +1,107 @@
package mysql
import (
"testing"
)
func TestIntegerExpressionEQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.EQ(table2ColInt), "(table1.col_int = table2.col_int)")
assertClauseSerialize(t, table1ColInt.EQ(Int(11)), "(table1.col_int = ?)", int64(11))
}
func TestIntegerExpressionNOT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.NOT_EQ(table2ColInt), "(table1.col_int != table2.col_int)")
assertClauseSerialize(t, table1ColInt.NOT_EQ(Int(11)), "(table1.col_int != ?)", int64(11))
}
func TestIntegerExpressionGT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.GT(table2ColInt), "(table1.col_int > table2.col_int)")
assertClauseSerialize(t, table1ColInt.GT(Int(11)), "(table1.col_int > ?)", int64(11))
}
func TestIntegerExpressionGT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.GT_EQ(table2ColInt), "(table1.col_int >= table2.col_int)")
assertClauseSerialize(t, table1ColInt.GT_EQ(Int(11)), "(table1.col_int >= ?)", int64(11))
}
func TestIntegerExpressionLT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.LT(table2ColInt), "(table1.col_int < table2.col_int)")
assertClauseSerialize(t, table1ColInt.LT(Int(11)), "(table1.col_int < ?)", int64(11))
}
func TestIntegerExpressionLT_EQ(t *testing.T) {
assertClauseSerialize(t, table1ColInt.LT_EQ(table2ColInt), "(table1.col_int <= table2.col_int)")
assertClauseSerialize(t, table1ColInt.LT_EQ(Int(11)), "(table1.col_int <= ?)", int64(11))
}
func TestIntegerExpressionADD(t *testing.T) {
assertClauseSerialize(t, table1ColInt.ADD(table2ColInt), "(table1.col_int + table2.col_int)")
assertClauseSerialize(t, table1ColInt.ADD(Int(11)), "(table1.col_int + ?)", int64(11))
}
func TestIntegerExpressionSUB(t *testing.T) {
assertClauseSerialize(t, table1ColInt.SUB(table2ColInt), "(table1.col_int - table2.col_int)")
assertClauseSerialize(t, table1ColInt.SUB(Int(11)), "(table1.col_int - ?)", int64(11))
}
func TestIntegerExpressionMUL(t *testing.T) {
assertClauseSerialize(t, table1ColInt.MUL(table2ColInt), "(table1.col_int * table2.col_int)")
assertClauseSerialize(t, table1ColInt.MUL(Int(11)), "(table1.col_int * ?)", int64(11))
}
func TestIntegerExpressionDIV(t *testing.T) {
assertClauseSerialize(t, table1ColInt.DIV(table2ColInt), "(table1.col_int DIV table2.col_int)")
assertClauseSerialize(t, table1ColInt.DIV(Int(11)), "(table1.col_int DIV ?)", int64(11))
}
func TestIntExpressionMOD(t *testing.T) {
assertClauseSerialize(t, table1ColInt.MOD(table2ColInt), "(table1.col_int % table2.col_int)")
assertClauseSerialize(t, table1ColInt.MOD(Int(11)), "(table1.col_int % ?)", int64(11))
}
func TestIntExpressionPOW(t *testing.T) {
assertClauseSerialize(t, table1ColInt.POW(table2ColInt), "POW(table1.col_int, table2.col_int)")
assertClauseSerialize(t, table1ColInt.POW(Int(11)), "POW(table1.col_int, ?)", int64(11))
}
func TestIntExpressionBIT_NOT(t *testing.T) {
assertClauseSerialize(t, BIT_NOT(table2ColInt), "(~ table2.col_int)")
assertClauseSerialize(t, BIT_NOT(Int(11)), "(~ ?)", int64(11))
}
func TestIntExpressionBIT_AND(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_AND(table2ColInt), "(table1.col_int & table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_AND(Int(11)), "(table1.col_int & ?)", int64(11))
}
func TestIntExpressionBIT_OR(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_OR(table2ColInt), "(table1.col_int | table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_OR(Int(11)), "(table1.col_int | ?)", int64(11))
}
func TestIntExpressionBIT_XOR(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_XOR(table2ColInt), "(table1.col_int ^ table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_XOR(Int(11)), "(table1.col_int ^ ?)", int64(11))
}
func TestIntExpressionBIT_SHIFT_LEFT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_LEFT(table2ColInt), "(table1.col_int << table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_LEFT(Int(11)), "(table1.col_int << ?)", int64(11))
}
func TestIntExpressionBIT_SHIFT_RIGHT(t *testing.T) {
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(table2ColInt), "(table1.col_int >> table2.col_int)")
assertClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(Int(11)), "(table1.col_int >> ?)", int64(11))
}
//
//func TestIntExpressionIntExp(t *testing.T) {
// assertClauseSerialize(t, IntExp(table1ColFloat), "table1.col_float")
// assertClauseSerialize(t, IntExp(table1ColFloat.ADD(table2ColFloat)).ADD(Int(11)),
// "((table1.col_float + table2.col_float) + ?)", int64(11))
//}
func TestIntExpression_MINUSi(t *testing.T) {
assertClauseSerialize(t, MINUSi(table2ColInt), "(- table2.col_int)")
assertClauseSerialize(t, MINUSi(Int(3)), "(- ?)", int64(3))
}

View file

@ -1,11 +0,0 @@
package mysql
import (
"github.com/go-jet/jet"
"testing"
)
func TestCAST_AS_DATE(t *testing.T) {
jet.AssertMySQLClauseSerialize(t, CAST(Int(22)).AS_DATE(), `CAST(? AS DATE)`, int64(22))
}

9
mysql/table.go Normal file
View file

@ -0,0 +1,9 @@
package mysql
import "github.com/go-jet/jet/internal/jet"
type Table jet.Table
func NewTable(schemaName, name string, columns ...jet.Column) Table {
return jet.NewTable(Dialect, schemaName, name, columns...)
}

104
mysql/testutils.go Normal file
View file

@ -0,0 +1,104 @@
package mysql
import (
"github.com/go-jet/jet/internal/jet"
"gotest.tools/assert"
"testing"
)
var table1Col1 = IntegerColumn("col1")
var table1ColInt = IntegerColumn("col_int")
var table1ColFloat = FloatColumn("col_float")
var table1Col3 = IntegerColumn("col3")
var table1ColTimestamp = TimestampColumn("col_timestamp")
var table1ColBool = BoolColumn("col_bool")
var table1ColDate = DateColumn("col_date")
var table1 = NewTable(
"db",
"table1",
table1Col1,
table1ColInt,
table1ColFloat,
table1Col3,
table1ColBool,
table1ColDate,
table1ColTimestamp,
)
var table2Col3 = IntegerColumn("col3")
var table2Col4 = IntegerColumn("col4")
var table2ColInt = IntegerColumn("col_int")
var table2ColFloat = FloatColumn("col_float")
var table2ColStr = StringColumn("col_str")
var table2ColBool = BoolColumn("col_bool")
var table2ColTimestamp = TimestampColumn("col_timestamp")
var table2ColDate = DateColumn("col_date")
var table2 = NewTable(
"db",
"table2",
table2Col3,
table2Col4,
table2ColInt,
table2ColFloat,
table2ColStr,
table2ColBool,
table2ColDate,
table2ColTimestamp,
)
var table3Col1 = IntegerColumn("col1")
var table3ColInt = IntegerColumn("col_int")
var table3StrCol = StringColumn("col2")
var table3 = NewTable(
"db",
"table3",
table3Col1,
table3ColInt,
table3StrCol)
func assertClauseSerialize(t *testing.T, clause jet.Clause, query string, args ...interface{}) {
out := jet.SqlBuilder{Dialect: Dialect}
err := jet.Serialize(clause, jet.SelectStatementType, &out)
assert.NilError(t, err)
assert.DeepEqual(t, out.Buff.String(), query)
assert.DeepEqual(t, out.Args, args)
}
func assertClauseSerializeErr(t *testing.T, clause jet.Clause, errString string) {
out := jet.SqlBuilder{Dialect: Dialect}
err := jet.Serialize(clause, jet.SelectStatementType, &out)
//fmt.Println(out.buff.String())
assert.Assert(t, err != nil)
assert.Error(t, err, errString)
}
func assertProjectionSerialize(t *testing.T, projection jet.Projection, query string, args ...interface{}) {
out := jet.SqlBuilder{Dialect: Dialect}
err := jet.SerializeForProjection(projection, jet.SelectStatementType, &out)
assert.NilError(t, err)
assert.DeepEqual(t, out.Buff.String(), query)
assert.DeepEqual(t, out.Args, args)
}
func assertStatement(t *testing.T, query jet.Statement, expectedQuery string, expectedArgs ...interface{}) {
queryStr, args, err := query.Sql()
assert.NilError(t, err)
//fmt.Println(queryStr)
assert.Equal(t, queryStr, expectedQuery)
assert.DeepEqual(t, args, expectedArgs)
}
func assertStatementErr(t *testing.T, stmt jet.Statement, errorStr string) {
_, _, err := stmt.Sql()
assert.Assert(t, err != nil)
assert.Error(t, err, errorStr)
}

View file

@ -1,53 +1,42 @@
package mysql package mysql
import "github.com/go-jet/jet" import "github.com/go-jet/jet/internal/jet"
type Expression jet.Expression
type ColumnBool jet.ColumnBool type ColumnBool jet.ColumnBool
type BoolExpression jet.BoolExpression
var BoolColumn = jet.BoolColumn var BoolColumn = jet.BoolColumn
var Bool = jet.Bool var Bool = jet.Bool
type ColumnString jet.ColumnString type ColumnString jet.ColumnString
type StringExpression jet.StringExpression
var StringColumn = jet.StringColumn var StringColumn = jet.StringColumn
var String = jet.String var String = jet.String
type ColumnInteger jet.ColumnInteger type ColumnInteger jet.ColumnInteger
type IntegerExpression jet.IntegerExpression
var IntegerColumn = jet.IntegerColumn var IntegerColumn = jet.IntegerColumn
var Int = jet.Int var Int = jet.Int
type ColumnFloat jet.ColumnFloat type ColumnFloat jet.ColumnFloat
type FloatExpression jet.FloatExpression
var FloatColumn = jet.FloatColumn var FloatColumn = jet.FloatColumn
var Float = jet.Float var Float = jet.Float
type ColumnDate jet.ColumnDate type ColumnDate jet.ColumnDate
type DateExpression jet.DateExpression
var DateColumn = jet.DateColumn var DateColumn = jet.DateColumn
var Date = jet.Date var Date = jet.Date
type ColumnDateTime jet.ColumnTimestamp type ColumnDateTime jet.ColumnTimestamp
type DateTimeExpression jet.TimestampExpression
var DateTimeColumn = jet.TimestampColumn var DateTimeColumn = jet.TimestampColumn
var DateTime = jet.Timestamp var DateTime = jet.Timestamp
type ColumnTimestamp jet.ColumnTimestamp type ColumnTimestamp jet.ColumnTimestamp
type TimestampExpression jet.TimestampExpression
var TimestampColumn = jet.TimestampColumn var TimestampColumn = jet.TimestampColumn
var Timestamp = jet.Timestamp var Timestamp = jet.Timestamp
type TimeExpression jet.TimeExpression
// ----------------- FUNCTIONS ----------------------// // ----------------- FUNCTIONS ----------------------//
var ABSf = jet.ABSf var ABSf = jet.ABSf

View file

@ -1,48 +1,47 @@
package postgres package postgres
import ( import (
"github.com/go-jet/jet"
"testing" "testing"
) )
var dateVar = Date(2000, 12, 30) var dateVar = Date(2000, 12, 30)
func TestDateExpressionEQ(t *testing.T) { func TestDateExpressionEQ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.EQ(table2ColDate), "(table1.col_date = table2.col_date)") assertClauseSerialize(t, table1ColDate.EQ(table2ColDate), "(table1.col_date = table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.EQ(dateVar), "(table1.col_date = $1::DATE)", "2000-12-30") assertClauseSerialize(t, table1ColDate.EQ(dateVar), "(table1.col_date = $1::DATE)", "2000-12-30")
} }
func TestDateExpressionNOT_EQ(t *testing.T) { func TestDateExpressionNOT_EQ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.NOT_EQ(table2ColDate), "(table1.col_date != table2.col_date)") assertClauseSerialize(t, table1ColDate.NOT_EQ(table2ColDate), "(table1.col_date != table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.NOT_EQ(dateVar), "(table1.col_date != $1::DATE)", "2000-12-30") assertClauseSerialize(t, table1ColDate.NOT_EQ(dateVar), "(table1.col_date != $1::DATE)", "2000-12-30")
} }
func TestDateExpressionIS_DISTINCT_FROM(t *testing.T) { func TestDateExpressionIS_DISTINCT_FROM(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_DISTINCT_FROM(table2ColDate), "(table1.col_date IS DISTINCT FROM table2.col_date)") assertClauseSerialize(t, table1ColDate.IS_DISTINCT_FROM(table2ColDate), "(table1.col_date IS DISTINCT FROM table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_DISTINCT_FROM(dateVar), "(table1.col_date IS DISTINCT FROM $1::DATE)", "2000-12-30") assertClauseSerialize(t, table1ColDate.IS_DISTINCT_FROM(dateVar), "(table1.col_date IS DISTINCT FROM $1::DATE)", "2000-12-30")
} }
func TestDateExpressionIS_NOT_DISTINCT_FROM(t *testing.T) { func TestDateExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_NOT_DISTINCT_FROM(table2ColDate), "(table1.col_date IS NOT DISTINCT FROM table2.col_date)") assertClauseSerialize(t, table1ColDate.IS_NOT_DISTINCT_FROM(table2ColDate), "(table1.col_date IS NOT DISTINCT FROM table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.IS_NOT_DISTINCT_FROM(dateVar), "(table1.col_date IS NOT DISTINCT FROM $1::DATE)", "2000-12-30") assertClauseSerialize(t, table1ColDate.IS_NOT_DISTINCT_FROM(dateVar), "(table1.col_date IS NOT DISTINCT FROM $1::DATE)", "2000-12-30")
} }
func TestDateExpressionGT(t *testing.T) { func TestDateExpressionGT(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.GT(table2ColDate), "(table1.col_date > table2.col_date)") assertClauseSerialize(t, table1ColDate.GT(table2ColDate), "(table1.col_date > table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.GT(dateVar), "(table1.col_date > $1::DATE)", "2000-12-30") assertClauseSerialize(t, table1ColDate.GT(dateVar), "(table1.col_date > $1::DATE)", "2000-12-30")
} }
func TestDateExpressionGT_EQ(t *testing.T) { func TestDateExpressionGT_EQ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.GT_EQ(table2ColDate), "(table1.col_date >= table2.col_date)") assertClauseSerialize(t, table1ColDate.GT_EQ(table2ColDate), "(table1.col_date >= table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.GT_EQ(dateVar), "(table1.col_date >= $1::DATE)", "2000-12-30") assertClauseSerialize(t, table1ColDate.GT_EQ(dateVar), "(table1.col_date >= $1::DATE)", "2000-12-30")
} }
func TestDateExpressionLT(t *testing.T) { func TestDateExpressionLT(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.LT(table2ColDate), "(table1.col_date < table2.col_date)") assertClauseSerialize(t, table1ColDate.LT(table2ColDate), "(table1.col_date < table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.LT(dateVar), "(table1.col_date < $1::DATE)", "2000-12-30") assertClauseSerialize(t, table1ColDate.LT(dateVar), "(table1.col_date < $1::DATE)", "2000-12-30")
} }
func TestDateExpressionLT_EQ(t *testing.T) { func TestDateExpressionLT_EQ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, table1ColDate.LT_EQ(table2ColDate), "(table1.col_date <= table2.col_date)") assertClauseSerialize(t, table1ColDate.LT_EQ(table2ColDate), "(table1.col_date <= table2.col_date)")
jet.AssertPostgreClauseSerialize(t, table1ColDate.LT_EQ(dateVar), "(table1.col_date <= $1::DATE)", "2000-12-30") assertClauseSerialize(t, table1ColDate.LT_EQ(dateVar), "(table1.col_date <= $1::DATE)", "2000-12-30")
} }

70
postgres/dialect.go Normal file
View file

@ -0,0 +1,70 @@
package postgres
import (
"github.com/go-jet/jet/internal/jet"
"strconv"
)
var Dialect = NewDialect()
func NewDialect() jet.Dialect {
dialectParams := jet.DialectParams{
Name: "PostgreSQL",
PackageName: "postgres",
CastOverride: castFunc,
AliasQuoteChar: '"',
IdentifierQuoteChar: '"',
ArgumentPlaceholder: func(ord int) string {
return "$" + strconv.Itoa(ord)
},
UpdateAssigment: postgresUpdateAssigment,
SupportsReturning: true,
}
return jet.NewDialect(dialectParams)
}
func castFunc(expression jet.Expression, castType string) jet.SerializeFunc {
return func(statement jet.StatementType, out *jet.SqlBuilder, options ...jet.SerializeOption) error {
if err := jet.Serialize(expression, statement, out, options...); err != nil {
return err
}
out.WriteString("::" + castType)
return nil
}
}
func postgresUpdateAssigment(columns []jet.IColumn, values []jet.Clause, out *jet.SqlBuilder) (err error) {
if len(columns) > 1 {
out.WriteString("(")
}
err = jet.SerializeColumnNames(columns, out)
if err != nil {
return
}
if len(columns) > 1 {
out.WriteString(")")
}
out.WriteString("=")
if len(values) > 1 {
out.WriteString("(")
}
err = jet.SerializeClauseList(jet.UpdateStatementType, values, out)
if err != nil {
return
}
if len(values) > 1 {
out.WriteString(")")
}
return
}

5
postgres/expressions.go Normal file
View file

@ -0,0 +1,5 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
type Expression jet.Expression

View file

@ -2,7 +2,7 @@ package postgres
import ( import (
"fmt" "fmt"
"github.com/go-jet/jet" "github.com/go-jet/jet/internal/jet"
) )
type cast interface { type cast interface {
@ -37,7 +37,7 @@ type castImpl struct {
jet.CastImpl jet.CastImpl
} }
func CAST(expr jet.Expression) cast { func CAST(expr Expression) cast {
castImpl := &castImpl{} castImpl := &castImpl{}
castImpl.CastImpl = jet.NewCastImpl(expr) castImpl.CastImpl = jet.NewCastImpl(expr)

View file

@ -1,65 +1,64 @@
package postgres package postgres
import ( import (
"github.com/go-jet/jet"
"testing" "testing"
) )
func TestExpressionCAST_AS(t *testing.T) { func TestExpressionCAST_AS(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(String("test")).AS("text"), `$1::text`, "test") assertClauseSerialize(t, CAST(String("test")).AS("text"), `$1::text`, "test")
} }
func TestExpressionCAST_AS_BOOL(t *testing.T) { func TestExpressionCAST_AS_BOOL(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(Int(1)).AS_BOOL(), "$1::boolean", int64(1)) assertClauseSerialize(t, CAST(Int(1)).AS_BOOL(), "$1::boolean", int64(1))
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_BOOL(), "table2.col3::boolean") assertClauseSerialize(t, CAST(table2Col3).AS_BOOL(), "table2.col3::boolean")
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3.ADD(table2Col3)).AS_BOOL(), "(table2.col3 + table2.col3)::boolean") assertClauseSerialize(t, CAST(table2Col3.ADD(table2Col3)).AS_BOOL(), "(table2.col3 + table2.col3)::boolean")
} }
func TestExpressionCAST_AS_SMALLINT(t *testing.T) { func TestExpressionCAST_AS_SMALLINT(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_SMALLINT(), "table2.col3::smallint") assertClauseSerialize(t, CAST(table2Col3).AS_SMALLINT(), "table2.col3::smallint")
} }
func TestExpressionCAST_AS_INTEGER(t *testing.T) { func TestExpressionCAST_AS_INTEGER(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_INTEGER(), "table2.col3::integer") assertClauseSerialize(t, CAST(table2Col3).AS_INTEGER(), "table2.col3::integer")
} }
func TestExpressionCAST_AS_BIGINT(t *testing.T) { func TestExpressionCAST_AS_BIGINT(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_BIGINT(), "table2.col3::bigint") assertClauseSerialize(t, CAST(table2Col3).AS_BIGINT(), "table2.col3::bigint")
} }
func TestExpressionCAST_AS_NUMERIC(t *testing.T) { func TestExpressionCAST_AS_NUMERIC(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_NUMERIC(11, 11), "table2.col3::numeric(11, 11)") assertClauseSerialize(t, CAST(table2Col3).AS_NUMERIC(11, 11), "table2.col3::numeric(11, 11)")
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_NUMERIC(11), "table2.col3::numeric(11)") assertClauseSerialize(t, CAST(table2Col3).AS_NUMERIC(11), "table2.col3::numeric(11)")
} }
func TestExpressionCAST_AS_REAL(t *testing.T) { func TestExpressionCAST_AS_REAL(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_REAL(), "table2.col3::real") assertClauseSerialize(t, CAST(table2Col3).AS_REAL(), "table2.col3::real")
} }
func TestExpressionCAST_AS_DOUBLE(t *testing.T) { func TestExpressionCAST_AS_DOUBLE(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_DOUBLE(), "table2.col3::double precision") assertClauseSerialize(t, CAST(table2Col3).AS_DOUBLE(), "table2.col3::double precision")
} }
func TestExpressionCAST_AS_TEXT(t *testing.T) { func TestExpressionCAST_AS_TEXT(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_TEXT(), "table2.col3::text") assertClauseSerialize(t, CAST(table2Col3).AS_TEXT(), "table2.col3::text")
} }
func TestExpressionCAST_AS_DATE(t *testing.T) { func TestExpressionCAST_AS_DATE(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_DATE(), "table2.col3::DATE") assertClauseSerialize(t, CAST(table2Col3).AS_DATE(), "table2.col3::DATE")
} }
func TestExpressionCAST_AS_TIME(t *testing.T) { func TestExpressionCAST_AS_TIME(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_TIME(), "table2.col3::time without time zone") assertClauseSerialize(t, CAST(table2Col3).AS_TIME(), "table2.col3::time without time zone")
} }
func TestExpressionCAST_AS_TIMEZ(t *testing.T) { func TestExpressionCAST_AS_TIMEZ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_TIMEZ(), "table2.col3::time with time zone") assertClauseSerialize(t, CAST(table2Col3).AS_TIMEZ(), "table2.col3::time with time zone")
} }
func TestExpressionCAST_AS_TIMESTAMP(t *testing.T) { func TestExpressionCAST_AS_TIMESTAMP(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_TIMESTAMP(), "table2.col3::timestamp without time zone") assertClauseSerialize(t, CAST(table2Col3).AS_TIMESTAMP(), "table2.col3::timestamp without time zone")
} }
func TestExpressionCAST_AS_TIMESTAMPZ(t *testing.T) { func TestExpressionCAST_AS_TIMESTAMPZ(t *testing.T) {
jet.AssertPostgreClauseSerialize(t, CAST(table2Col3).AS_TIMESTAMPZ(), "table2.col3::timestamp with time zone") assertClauseSerialize(t, CAST(table2Col3).AS_TIMESTAMPZ(), "table2.col3::timestamp with time zone")
} }

View file

@ -0,0 +1,9 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
type Column jet.Column
type IColumnList jet.IColumnList
var ColumnList = jet.ColumnList

View file

@ -0,0 +1,5 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
var NewEnumValue = jet.NewEnumValue

View file

@ -0,0 +1,5 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
var RAW = jet.RAW

View file

@ -0,0 +1,93 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
var ROW = jet.ROW
// ------------------ Mathematical functions ---------------//
var ABSf = jet.ABSf
var ABSi = jet.ABSi
var POW = jet.POW
var POWER = jet.POWER
var SQRT = jet.SQRT
var CBRT = jet.CBRT
var CEIL = jet.CEIL
var FLOOR = jet.FLOOR
var ROUND = jet.ROUND
var SIGN = jet.SIGN
var TRUNC = jet.TRUNC
var LN = jet.LN
var LOG = jet.LOG
// ----------------- Aggregate functions -------------------//
var AVG = jet.AVG
var BIT_AND = jet.BIT_AND
var BIT_OR = jet.BIT_OR
var BOOL_AND = jet.BOOL_AND
var BOOL_OR = jet.BOOL_OR
var COUNT = jet.COUNT
var EVERY = jet.EVERY
var MAXf = jet.MAXf
var MAXi = jet.MAXi
var MINf = jet.MINf
var MINi = jet.MINi
var SUMf = jet.SUMf
var SUMi = jet.SUMi
//--------------------- String functions ------------------//
var BIT_LENGTH = jet.BIT_LENGTH
var CHAR_LENGTH = jet.CHAR_LENGTH
var OCTET_LENGTH = jet.OCTET_LENGTH
var LOWER = jet.LOWER
var UPPER = jet.UPPER
var BTRIM = jet.BTRIM
var LTRIM = jet.LTRIM
var RTRIM = jet.RTRIM
var CHR = jet.CHR
var CONVERT = jet.CONVERT
var CONVERT_FROM = jet.CONVERT_FROM
var CONVERT_TO = jet.CONVERT_TO
var ENCODE = jet.ENCODE
var DECODE = jet.DECODE
var INITCAP = jet.INITCAP
var LEFT = jet.LEFT
var RIGHT = jet.RIGHT
var LENGTH = jet.LENGTH
var LPAD = jet.LPAD
var RPAD = jet.RPAD
var MD5 = jet.MD5
var REPEAT = jet.REPEAT
var REPLACE = jet.REPLACE
var REVERSE = jet.REVERSE
var STRPOS = jet.STRPOS
var SUBSTR = jet.SUBSTR
var TO_ASCII = jet.TO_ASCII
var TO_HEX = jet.TO_HEX
//----------Data Type Formatting Functions ----------------------//
var TO_CHAR = jet.TO_CHAR
var TO_DATE = jet.TO_DATE
var TO_NUMBER = jet.TO_NUMBER
var TO_TIMESTAMP = jet.TO_TIMESTAMP
//----------------- Date/Time Functions and Operators ------------//
var CURRENT_DATE = jet.CURRENT_DATE
var CURRENT_TIME = jet.CURRENT_TIME
var CURRENT_TIMESTAMP = jet.CURRENT_TIMESTAMP
var LOCALTIME = jet.LOCALTIME
var LOCALTIMESTAMP = jet.LOCALTIMESTAMP
var NOW = jet.NOW
// --------------- Conditional Expressions Functions -------------//
var COALESCE = jet.COALESCE
var NULLIF = jet.NULLIF
var GREATEST = jet.GREATEST
var LEAST = jet.LEAST
var EXISTS = jet.EXISTS
var CASE = jet.CASE

View file

@ -0,0 +1,15 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
const (
// DEFAULT is jet equivalent of SQL DEFAULT
DEFAULT = jet.DEFAULT
)
var (
// NULL is jet equivalent of SQL NULL
NULL = jet.NULL
// STAR is jet equivalent of SQL *
STAR = jet.STAR
)

View file

@ -0,0 +1,27 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
var Bool = jet.Bool
var Int = jet.Int
var Float = jet.Float
var String = jet.String
var Date = func(year, month, day int) DateExpression {
return CAST(jet.Date(year, month, day)).AS_DATE()
}
var Time = func(hour, minute, second, milliseconds int) TimeExpression {
return CAST(jet.Time(hour, minute, second, milliseconds)).AS_TIME()
}
var Timez = func(hour, minute, second, milliseconds int, timezone int) TimezExpression {
return CAST(jet.Timez(hour, minute, second, milliseconds, timezone)).AS_TIMEZ()
}
var Timestamp = func(year, month, day, hour, minute, second, milliseconds int) TimestampExpression {
return CAST(jet.Timestamp(year, month, day, hour, minute, second, milliseconds)).AS_TIMESTAMP()
}
var Timestampz = func(year, month, day, hour, minute, second, milliseconds int, timezone int) TimestampzExpression {
return CAST(jet.Timestampz(year, month, day, hour, minute, second, milliseconds, timezone)).AS_TIMESTAMPZ()
}

21
postgres/postgres_lock.go Normal file
View file

@ -0,0 +1,21 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
type TableLockMode jet.TableLockMode
// Lock types for LockStatement.
const (
LOCK_ACCESS_SHARE = "ACCESS SHARE"
LOCK_ROW_SHARE = "ROW SHARE"
LOCK_ROW_EXCLUSIVE = "ROW EXCLUSIVE"
LOCK_SHARE_UPDATE_EXCLUSIVE = "SHARE UPDATE EXCLUSIVE"
LOCK_SHARE = "SHARE"
LOCK_SHARE_ROW_EXCLUSIVE = "SHARE ROW EXCLUSIVE"
LOCK_EXCLUSIVE = "EXCLUSIVE"
LOCK_ACCESS_EXCLUSIVE = "ACCESS EXCLUSIVE"
)
type LockStatement jet.LockStatement
var LOCK = jet.LOCK

View file

@ -0,0 +1,13 @@
package postgres
import "github.com/go-jet/jet/internal/jet"
// --------- Arithmetic operators -------------//
var MINUSi = jet.MINUSi
var MINUSf = jet.MINUSf
//----------- Logical operators ---------------//
var NOT = jet.NOT
var BIT_NOT = jet.BIT_NOT

Some files were not shown because too many files have changed in this diff Show more