Package structure refactor.
This commit is contained in:
parent
3d8e872336
commit
23fd973699
125 changed files with 2401 additions and 1818 deletions
|
|
@ -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")
|
|
||||||
}
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
232
dialects.go
232
dialects.go
|
|
@ -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
|
|
||||||
|
|
@ -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"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -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))
|
|
||||||
}
|
|
||||||
|
|
@ -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))
|
|
||||||
}
|
|
||||||
|
|
@ -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")
|
|
||||||
}
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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}}
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
package jet
|
|
||||||
|
|
||||||
type groupByClause interface {
|
|
||||||
serializeForGroupBy(statement statementType, out *sqlBuilder) error
|
|
||||||
}
|
|
||||||
|
|
@ -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))
|
|
||||||
}
|
|
||||||
|
|
@ -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
|
||||||
90
internal/jet/bool_expression_test.go
Normal file
90
internal/jet/bool_expression_test.go
Normal 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")
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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 {
|
||||||
|
|
@ -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 "" }
|
||||||
|
|
@ -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"`)
|
||||||
}
|
}
|
||||||
|
|
@ -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.
|
||||||
|
|
@ -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"`)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -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
104
internal/jet/dialects.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
58
internal/jet/expression_test.go
Normal file
58
internal/jet/expression_test.go
Normal 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))
|
||||||
|
}
|
||||||
82
internal/jet/float_expression_test.go
Normal file
82
internal/jet/float_expression_test.go
Normal 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))
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
162
internal/jet/func_expression_test.go
Normal file
162
internal/jet/func_expression_test.go
Normal 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")
|
||||||
|
}
|
||||||
5
internal/jet/group_by_clause.go
Normal file
5
internal/jet/group_by_clause.go
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
package jet
|
||||||
|
|
||||||
|
type groupByClause interface {
|
||||||
|
serializeForGroupBy(statement StatementType, out *SqlBuilder) error
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
106
internal/jet/integer_expression_test.go
Normal file
106
internal/jet/integer_expression_test.go
Normal 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))
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
7
internal/jet/literal_expression_test.go
Normal file
7
internal/jet/literal_expression_test.go
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
package jet
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestRawExpression(t *testing.T) {
|
||||||
|
assertClauseSerialize(t, RAW("current_database()"), "current_database()")
|
||||||
|
}
|
||||||
|
|
@ -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()
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
|
|
@ -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
|
||||||
33
internal/jet/projection.go
Normal file
33
internal/jet/projection.go
Normal 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
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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";
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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)
|
||||||
|
|
@ -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 {
|
||||||
82
internal/jet/string_expression_test.go
Normal file
82
internal/jet/string_expression_test.go
Normal 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")
|
||||||
|
}
|
||||||
|
|
@ -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 {
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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{}) {
|
func assertClauseSerializeErr(t *testing.T, clause Clause, errString string) {
|
||||||
out := sqlBuilder{dialect: PostgreSQL}
|
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 AssertMySQLClauseSerialize(t *testing.T, clause clause, query string, args ...interface{}) {
|
|
||||||
out := sqlBuilder{dialect: MySQL}
|
|
||||||
err := clause.serialize(selectStatement, &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)
|
||||||
53
internal/jet/time_expression_test.go
Normal file
53
internal/jet/time_expression_test.go
Normal 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"))
|
||||||
|
}
|
||||||
52
internal/jet/timestamp_expression_test.go
Normal file
52
internal/jet/timestamp_expression_test.go
Normal 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")
|
||||||
|
}
|
||||||
54
internal/jet/timestampz_expression_test.go
Normal file
54
internal/jet/timestampz_expression_test.go
Normal 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")
|
||||||
|
}
|
||||||
53
internal/jet/timez_expression_test.go
Normal file
53
internal/jet/timez_expression_test.go
Normal 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"))
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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...)
|
||||||
|
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
package jet
|
|
||||||
|
|
||||||
import "testing"
|
|
||||||
|
|
||||||
func TestRawExpression(t *testing.T) {
|
|
||||||
AssertPostgreClauseSerialize(t, RAW("current_database()"), "current_database()")
|
|
||||||
}
|
|
||||||
|
|
@ -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;
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
89
mysql/bool_expression_test.go
Normal file
89
mysql/bool_expression_test.go
Normal 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")
|
||||||
|
//}
|
||||||
|
|
@ -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
9
mysql/cast_test.go
Normal 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
9
mysql/column.go
Normal 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
139
mysql/dialect.go
Normal 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
21
mysql/expressions.go
Normal 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
|
||||||
107
mysql/integer_expression_test.go
Normal file
107
mysql/integer_expression_test.go
Normal 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))
|
||||||
|
}
|
||||||
|
|
@ -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
9
mysql/table.go
Normal 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
104
mysql/testutils.go
Normal 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)
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
70
postgres/dialect.go
Normal 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
5
postgres/expressions.go
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
package postgres
|
||||||
|
|
||||||
|
import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
|
type Expression jet.Expression
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
9
postgres/postgres_column.go
Normal file
9
postgres/postgres_column.go
Normal 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
|
||||||
5
postgres/postgres_enum.go
Normal file
5
postgres/postgres_enum.go
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
package postgres
|
||||||
|
|
||||||
|
import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
|
var NewEnumValue = jet.NewEnumValue
|
||||||
5
postgres/postgres_expressions.go
Normal file
5
postgres/postgres_expressions.go
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
package postgres
|
||||||
|
|
||||||
|
import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
|
var RAW = jet.RAW
|
||||||
93
postgres/postgres_functions.go
Normal file
93
postgres/postgres_functions.go
Normal 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
|
||||||
15
postgres/postgres_keywords.go
Normal file
15
postgres/postgres_keywords.go
Normal 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
|
||||||
|
)
|
||||||
27
postgres/postgres_literal.go
Normal file
27
postgres/postgres_literal.go
Normal 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
21
postgres/postgres_lock.go
Normal 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
|
||||||
13
postgres/postgres_operators.go
Normal file
13
postgres/postgres_operators.go
Normal 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
Loading…
Add table
Add a link
Reference in a new issue