From 3c5553b3dcb35bab74a3fe25844e95b6d09b6860 Mon Sep 17 00:00:00 2001 From: zer0sub Date: Fri, 7 Jun 2019 14:23:14 +0200 Subject: [PATCH] Explicit sqlbuilder cast. --- sqlbuilder/bool_expresion.go | 17 +++++++ sqlbuilder/bool_expression_test.go | 6 +++ sqlbuilder/cast.go | 8 +-- sqlbuilder/date_expression.go | 17 +++++++ sqlbuilder/expression.go | 71 ++++++++++++++++++--------- sqlbuilder/expression_test.go | 37 ++++++++++---- sqlbuilder/float_expression.go | 29 +++-------- sqlbuilder/float_expression_test.go | 7 +++ sqlbuilder/integer_expression.go | 19 +++++++ sqlbuilder/integer_expression_test.go | 6 +++ sqlbuilder/literal_expression.go | 10 ++-- sqlbuilder/select_statement.go | 4 -- sqlbuilder/string_expression.go | 17 +++++++ sqlbuilder/string_expression_test.go | 5 ++ sqlbuilder/time_expression.go | 17 +++++++ sqlbuilder/time_expression_test.go | 6 +++ sqlbuilder/timestamp_expression.go | 17 +++++++ sqlbuilder/timestampz_expression.go | 17 +++++++ sqlbuilder/timez_expression.go | 17 +++++++ tests/select_test.go | 47 +++++++----------- tests/types_test.go | 23 +++++---- 21 files changed, 293 insertions(+), 104 deletions(-) diff --git a/sqlbuilder/bool_expresion.go b/sqlbuilder/bool_expresion.go index 5f95eea..703cfd9 100644 --- a/sqlbuilder/bool_expresion.go +++ b/sqlbuilder/bool_expresion.go @@ -124,3 +124,20 @@ func newPostifxBoolExpression(expression Expression, operator string) BoolExpres return &exp } + +//---------------------------------------------------// + +type boolExpressionWrapper struct { + boolInterfaceImpl + Expression +} + +func newBoolExpressionWrap(expression Expression) BoolExpression { + boolExpressionWrap := boolExpressionWrapper{Expression: expression} + boolExpressionWrap.boolInterfaceImpl.parent = &boolExpressionWrap + return &boolExpressionWrap +} + +func BoolExp(expression Expression) BoolExpression { + return newBoolExpressionWrap(expression) +} diff --git a/sqlbuilder/bool_expression_test.go b/sqlbuilder/bool_expression_test.go index a8e0bf5..fc84c9b 100644 --- a/sqlbuilder/bool_expression_test.go +++ b/sqlbuilder/bool_expression_test.go @@ -53,6 +53,7 @@ func TestBinaryBoolExpression(t *testing.T) { assertClauseSerialize(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) { assertClauseSerialize(t, Bool(true), "$1", true) assertClauseSerialize(t, Bool(false), "$1", false) @@ -71,3 +72,8 @@ func TestExists(t *testing.T) { WHERE table1.col1 = table2.col3 )`, int64(1)) } + +func TestBoolExp(t *testing.T) { + assertClauseSerialize(t, BoolExp(String("true")), "$1", "true") + assertClauseSerialize(t, BoolExp(String("true")).IS_TRUE(), "$1 IS TRUE", "true") +} diff --git a/sqlbuilder/cast.go b/sqlbuilder/cast.go index 3fa73b2..829ceeb 100644 --- a/sqlbuilder/cast.go +++ b/sqlbuilder/cast.go @@ -39,8 +39,8 @@ type integerCast struct { cast } -func newIntegerCast(expression Expression) IntegerExpression { - integerCast := &integerCast{cast: *newCast(expression, "integer")} +func newIntegerCast(expression Expression, intType string) IntegerExpression { + integerCast := &integerCast{cast: *newCast(expression, intType)} integerCast.integerInterfaceImpl.parent = integerCast integerCast.expressionInterfaceImpl.parent = integerCast @@ -54,8 +54,8 @@ type floatCast struct { cast } -func newDoubleCast(expression Expression) FloatExpression { - floatCast := &floatCast{cast: *newCast(expression, "double precision")} +func newFloatCast(expression Expression, floatType string) FloatExpression { + floatCast := &floatCast{cast: *newCast(expression, floatType)} floatCast.floatInterfaceImpl.parent = floatCast floatCast.expressionInterfaceImpl.parent = floatCast diff --git a/sqlbuilder/date_expression.go b/sqlbuilder/date_expression.go index a9e0b92..7f31a0a 100644 --- a/sqlbuilder/date_expression.go +++ b/sqlbuilder/date_expression.go @@ -49,3 +49,20 @@ func (t *dateInterfaceImpl) GT(rhs DateExpression) BoolExpression { func (t *dateInterfaceImpl) GT_EQ(rhs DateExpression) BoolExpression { return GT_EQ(t.parent, rhs) } + +//---------------------------------------------------// + +type DateExpressionWrapper struct { + dateInterfaceImpl + Expression +} + +func newDateExpressionWrap(expression Expression) DateExpression { + dateExpressionWrap := DateExpressionWrapper{Expression: expression} + dateExpressionWrap.dateInterfaceImpl.parent = &dateExpressionWrap + return &dateExpressionWrap +} + +func DateExp(expression Expression) DateExpression { + return newDateExpressionWrap(expression) +} diff --git a/sqlbuilder/expression.go b/sqlbuilder/expression.go index 3eebb54..5ef4987 100644 --- a/sqlbuilder/expression.go +++ b/sqlbuilder/expression.go @@ -2,6 +2,7 @@ package sqlbuilder import ( "errors" + "fmt" ) // An Expression @@ -22,16 +23,20 @@ type Expression interface { ASC() OrderByClause DESC() OrderByClause - CAST_TO(dbType string) Expression - CAST_TO_BOOL() BoolExpression - CAST_TO_INTEGER() IntegerExpression - CAST_TO_DOUBLE() FloatExpression - CAST_TO_TEXT() StringExpression - CAST_TO_DATE() DateExpression - CAST_TO_TIME() TimeExpression - CAST_TO_TIMEZ() TimezExpression - CAST_TO_TIMESTAMP() TimestampExpression - CAST_TO_TIMESTAMPZ() TimestampzExpression + TO(dbType string) Expression + TO_BOOL() BoolExpression + TO_SMALLINT() IntegerExpression + TO_INTEGER() IntegerExpression + TO_BIGINT() IntegerExpression + TO_NUMERIC(precision int, scale ...int) FloatExpression + TO_REAL() FloatExpression + TO_DOUBLE() FloatExpression + TO_TEXT() StringExpression + TO_DATE() DateExpression + TO_TIME() TimeExpression + TO_TIMEZ() TimezExpression + TO_TIMESTAMP() TimestampExpression + TO_TIMESTAMPZ() TimestampzExpression } type expressionInterfaceImpl struct { @@ -66,43 +71,65 @@ func (e *expressionInterfaceImpl) DESC() OrderByClause { return &orderByClauseImpl{expression: e.parent, ascent: false} } -func (e *expressionInterfaceImpl) CAST_TO(dbType string) Expression { +func (e *expressionInterfaceImpl) TO(dbType string) Expression { return newCast(e.parent, dbType) } -func (e *expressionInterfaceImpl) CAST_TO_BOOL() BoolExpression { +func (e *expressionInterfaceImpl) TO_BOOL() BoolExpression { return newBoolCast(e.parent) } -func (e *expressionInterfaceImpl) CAST_TO_INTEGER() IntegerExpression { - return newIntegerCast(e.parent) +func (e *expressionInterfaceImpl) TO_SMALLINT() IntegerExpression { + return newIntegerCast(e.parent, "smallint") } -func (e *expressionInterfaceImpl) CAST_TO_DOUBLE() FloatExpression { - return newDoubleCast(e.parent) +func (e *expressionInterfaceImpl) TO_INTEGER() IntegerExpression { + return newIntegerCast(e.parent, "integer") } -func (e *expressionInterfaceImpl) CAST_TO_TEXT() StringExpression { +func (e *expressionInterfaceImpl) TO_BIGINT() IntegerExpression { + return newIntegerCast(e.parent, "bigint") +} + +func (e *expressionInterfaceImpl) TO_NUMERIC(precision int, scale ...int) FloatExpression { + var castType string + if len(scale) > 0 { + castType = fmt.Sprintf("numeric(%d, %d)", precision, scale[0]) + } else { + castType = fmt.Sprintf("numeric(%d)", precision) + } + return newFloatCast(e.parent, castType) +} + +func (e *expressionInterfaceImpl) TO_REAL() FloatExpression { + return newFloatCast(e.parent, "real") +} + +func (e *expressionInterfaceImpl) TO_DOUBLE() FloatExpression { + return newFloatCast(e.parent, "double precision") +} + +func (e *expressionInterfaceImpl) TO_TEXT() StringExpression { return newTextCast(e.parent) } -func (e *expressionInterfaceImpl) CAST_TO_DATE() DateExpression { +func (e *expressionInterfaceImpl) TO_DATE() DateExpression { return newDateCast(e.parent) } -func (e *expressionInterfaceImpl) CAST_TO_TIME() TimeExpression { +func (e *expressionInterfaceImpl) TO_TIME() TimeExpression { return newTimeCast(e.parent) } -func (e *expressionInterfaceImpl) CAST_TO_TIMEZ() TimezExpression { +func (e *expressionInterfaceImpl) TO_TIMEZ() TimezExpression { return newTimezCast(e.parent) } -func (e *expressionInterfaceImpl) CAST_TO_TIMESTAMP() TimestampExpression { +func (e *expressionInterfaceImpl) TO_TIMESTAMP() TimestampExpression { return newTimestampCast(e.parent) } -func (e *expressionInterfaceImpl) CAST_TO_TIMESTAMPZ() TimestampzExpression { +func (e *expressionInterfaceImpl) TO_TIMESTAMPZ() TimestampzExpression { return newTimestampzCast(e.parent) } diff --git a/sqlbuilder/expression_test.go b/sqlbuilder/expression_test.go index 126b147..7edbd3e 100644 --- a/sqlbuilder/expression_test.go +++ b/sqlbuilder/expression_test.go @@ -25,40 +25,57 @@ func TestExpressionIS_NOT_DISTINCT_FROM(t *testing.T) { } func TestExpressionCAST_TO_BOOL(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_BOOL(), "table2.col3::boolean") - assertClauseSerialize(t, table2Col3.ADD(table2Col3).CAST_TO_BOOL(), "(table2.col3 + table2.col3)::boolean") + assertClauseSerialize(t, table2Col3.TO_BOOL(), "table2.col3::boolean") + assertClauseSerialize(t, table2Col3.ADD(table2Col3).TO_BOOL(), "(table2.col3 + table2.col3)::boolean") +} + +func TestExpressionCAST_TO_SMALLINT(t *testing.T) { + assertClauseSerialize(t, table2Col3.TO_SMALLINT(), "table2.col3::smallint") } func TestExpressionCAST_TO_INTEGER(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_INTEGER(), "table2.col3::integer") + assertClauseSerialize(t, table2Col3.TO_INTEGER(), "table2.col3::integer") +} + +func TestExpressionCAST_TO_BIGINT(t *testing.T) { + assertClauseSerialize(t, table2Col3.TO_BIGINT(), "table2.col3::bigint") +} + +func TestExpressionCAST_TO_NUMERIC(t *testing.T) { + assertClauseSerialize(t, table2Col3.TO_NUMERIC(11, 11), "table2.col3::numeric(11, 11)") + assertClauseSerialize(t, table2Col3.TO_NUMERIC(11), "table2.col3::numeric(11)") +} + +func TestExpressionCAST_TO_REAL(t *testing.T) { + assertClauseSerialize(t, table2Col3.TO_REAL(), "table2.col3::real") } func TestExpressionCAST_TO_DOUBLE(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_DOUBLE(), "table2.col3::double precision") + assertClauseSerialize(t, table2Col3.TO_DOUBLE(), "table2.col3::double precision") } func TestExpressionCAST_TO_TEXT(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_TEXT(), "table2.col3::text") + assertClauseSerialize(t, table2Col3.TO_TEXT(), "table2.col3::text") } func TestExpressionCAST_TO_DATE(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_DATE(), "table2.col3::date") + assertClauseSerialize(t, table2Col3.TO_DATE(), "table2.col3::date") } func TestExpressionCAST_TO_TIME(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_TIME(), "table2.col3::time without time zone") + assertClauseSerialize(t, table2Col3.TO_TIME(), "table2.col3::time without time zone") } func TestExpressionCAST_TO_TIMEZ(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_TIMEZ(), "table2.col3::time with time zone") + assertClauseSerialize(t, table2Col3.TO_TIMEZ(), "table2.col3::time with time zone") } func TestExpressionCAST_TO_TIMESTAMP(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_TIMESTAMP(), "table2.col3::timestamp without time zone") + assertClauseSerialize(t, table2Col3.TO_TIMESTAMP(), "table2.col3::timestamp without time zone") } func TestExpressionCAST_TO_TIMESTAMPZ(t *testing.T) { - assertClauseSerialize(t, table2Col3.CAST_TO_TIMESTAMPZ(), "table2.col3::timestamp with time zone") + assertClauseSerialize(t, table2Col3.TO_TIMESTAMPZ(), "table2.col3::timestamp with time zone") } func TestIN(t *testing.T) { diff --git a/sqlbuilder/float_expression.go b/sqlbuilder/float_expression.go index b7dcb74..cc18e0b 100644 --- a/sqlbuilder/float_expression.go +++ b/sqlbuilder/float_expression.go @@ -1,7 +1,5 @@ package sqlbuilder -import "errors" - type FloatExpression interface { Expression @@ -102,32 +100,19 @@ func newBinaryFloatExpression(lhs, rhs FloatExpression, operator string) FloatEx return &floatExpression } -////---------------------------------------------------// -type floatExpressionWrapper struct { - expressionInterfaceImpl - floatInterfaceImpl +//---------------------------------------------------// - expression Expression +type floatExpressionWrapper struct { + floatInterfaceImpl + Expression } func newFloatExpressionWrap(expression Expression) FloatExpression { - floatExpressionWrap := floatExpressionWrapper{} - - floatExpressionWrap.expression = expression - - floatExpressionWrap.expressionInterfaceImpl.parent = &floatExpressionWrap + floatExpressionWrap := floatExpressionWrapper{Expression: expression} floatExpressionWrap.floatInterfaceImpl.parent = &floatExpressionWrap - return &floatExpressionWrap } -func (n *floatExpressionWrapper) serialize(statement statementType, out *queryData, options ...serializeOption) error { - if n == nil { - return errors.New("Float expressions wrapper is nil. ") - } - //out.writeString("(") - err := n.expression.serialize(statement, out) - //out.writeString(")") - - return err +func FloatExp(expression Expression) FloatExpression { + return newFloatExpressionWrap(expression) } diff --git a/sqlbuilder/float_expression_test.go b/sqlbuilder/float_expression_test.go index 5ff05e4..aef441e 100644 --- a/sqlbuilder/float_expression_test.go +++ b/sqlbuilder/float_expression_test.go @@ -63,3 +63,10 @@ func TestFloatExpressionPOW(t *testing.T) { assertClauseSerialize(t, table1ColFloat.POW(table2ColFloat), "(table1.colFloat ^ table2.colFloat)") assertClauseSerialize(t, table1ColFloat.POW(Float(2.11)), "(table1.colFloat ^ $1)", float64(2.11)) } + +func TestFloatExp(t *testing.T) { + assertClauseSerialize(t, FloatExp(table1ColInt), "table1.colInt") + assertClauseSerialize(t, FloatExp(table1ColInt.ADD(table3ColInt)), "(table1.colInt + table3.colInt)") + assertClauseSerialize(t, FloatExp(table1ColInt.ADD(table3ColInt)).ADD(Float(11.11)), + "((table1.colInt + table3.colInt) + $1)", float64(11.11)) +} diff --git a/sqlbuilder/integer_expression.go b/sqlbuilder/integer_expression.go index d9e1ba8..a146c72 100644 --- a/sqlbuilder/integer_expression.go +++ b/sqlbuilder/integer_expression.go @@ -148,3 +148,22 @@ func newPrefixIntegerOpExpression(expression IntegerExpression, operator string) return &integerExpression } + +//---------------------------------------------------// +type integerExpressionWrapper struct { + integerInterfaceImpl + + Expression +} + +func newIntExpressionWrap(expression Expression) IntegerExpression { + intExpressionWrap := integerExpressionWrapper{Expression: expression} + + intExpressionWrap.integerInterfaceImpl.parent = &intExpressionWrap + + return &intExpressionWrap +} + +func IntExp(expression Expression) IntegerExpression { + return newIntExpressionWrap(expression) +} diff --git a/sqlbuilder/integer_expression_test.go b/sqlbuilder/integer_expression_test.go index af0cffa..57677a2 100644 --- a/sqlbuilder/integer_expression_test.go +++ b/sqlbuilder/integer_expression_test.go @@ -73,3 +73,9 @@ func TestIntExpressionBIT_SHIFT_RIGHT(t *testing.T) { assertClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(table2ColInt), "(table1.colInt >> table2.colInt)") assertClauseSerialize(t, table1ColInt.BIT_SHIFT_RIGHT(Int(11)), "(table1.colInt >> $1)", int64(11)) } + +func TestIntExpressionIntExp(t *testing.T) { + assertClauseSerialize(t, IntExp(table1ColFloat), "table1.colFloat") + assertClauseSerialize(t, IntExp(table1ColFloat.ADD(table2ColFloat)).ADD(Int(11)), + "((table1.colFloat + table2.colFloat) + $1)", int64(11)) +} diff --git a/sqlbuilder/literal_expression.go b/sqlbuilder/literal_expression.go index ca86605..ff1412d 100644 --- a/sqlbuilder/literal_expression.go +++ b/sqlbuilder/literal_expression.go @@ -107,7 +107,7 @@ func Time(hour, minute, second, milliseconds int) TimeExpression { timeLiteral.timeInterfaceImpl.parent = &timeLiteral - return timeLiteral.CAST_TO_TIME() + return timeLiteral.TO_TIME() } //---------------------------------------------------// @@ -123,7 +123,7 @@ func Timez(hour, minute, second, milliseconds, timezone int) TimezExpression { timezLiteral.timezInterfaceImpl.parent = &timezLiteral - return timezLiteral.CAST_TO_TIMEZ() + return timezLiteral.TO_TIMEZ() } //---------------------------------------------------// @@ -139,7 +139,7 @@ func Timestamp(year, month, day, hour, minute, second, milliseconds int) Timesta timestampLiteral.timestampInterfaceImpl.parent = ×tampLiteral - return timestampLiteral.CAST_TO_TIMESTAMP() + return timestampLiteral.TO_TIMESTAMP() } //---------------------------------------------------// @@ -157,7 +157,7 @@ func Timestampz(year, month, day, hour, minute, second, milliseconds, timezone i timestampzLiteral.timestampzInterfaceImpl.parent = ×tampzLiteral - return timestampzLiteral.CAST_TO_TIMESTAMPZ() + return timestampzLiteral.TO_TIMESTAMPZ() } //---------------------------------------------------// @@ -173,7 +173,7 @@ func Date(year, month, day int) DateExpression { dateLiteral.literalExpression = *literal(timeStr) dateLiteral.dateInterfaceImpl.parent = &dateLiteral - return dateLiteral.CAST_TO_DATE() + return dateLiteral.TO_DATE() } //--------------------------------------------------// diff --git a/sqlbuilder/select_statement.go b/sqlbuilder/select_statement.go index 65f20b4..1c82f38 100644 --- a/sqlbuilder/select_statement.go +++ b/sqlbuilder/select_statement.go @@ -257,7 +257,3 @@ func (s *selectStatementImpl) Query(db execution.Db, destination interface{}) er func (s *selectStatementImpl) Execute(db execution.Db) (res sql.Result, err error) { return Execute(s, db) } - -func NumExp(expression Expression) FloatExpression { - return newFloatExpressionWrap(expression) -} diff --git a/sqlbuilder/string_expression.go b/sqlbuilder/string_expression.go index e5b6e99..5793062 100644 --- a/sqlbuilder/string_expression.go +++ b/sqlbuilder/string_expression.go @@ -94,3 +94,20 @@ func newBinaryStringExpression(lhs, rhs Expression, operator string) StringExpre return &boolExpression } + +//---------------------------------------------------// + +type stringExpressionWrapper struct { + stringInterfaceImpl + Expression +} + +func newStringExpressionWrap(expression Expression) StringExpression { + stringExpressionWrap := stringExpressionWrapper{Expression: expression} + stringExpressionWrap.stringInterfaceImpl.parent = &stringExpressionWrap + return &stringExpressionWrap +} + +func StringExp(expression Expression) StringExpression { + return newStringExpressionWrap(expression) +} diff --git a/sqlbuilder/string_expression_test.go b/sqlbuilder/string_expression_test.go index 366324b..38014e1 100644 --- a/sqlbuilder/string_expression_test.go +++ b/sqlbuilder/string_expression_test.go @@ -65,3 +65,8 @@ func TestStringNOT_SIMILAR_TO(t *testing.T) { assertClauseSerialize(t, table3StrCol.NOT_SIMILAR_TO(table2ColStr), "(table3.col2 NOT SIMILAR TO table2.colStr)") 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.colFloat") + assertClauseSerialize(t, StringExp(table2ColFloat).NOT_LIKE(String("abc")), "(table2.colFloat NOT LIKE $1)", "abc") +} diff --git a/sqlbuilder/time_expression.go b/sqlbuilder/time_expression.go index d257ad2..2e63066 100644 --- a/sqlbuilder/time_expression.go +++ b/sqlbuilder/time_expression.go @@ -71,3 +71,20 @@ func newPrefixTimeExpression(operator string, expression Expression) TimeExpress func INTERVAL(interval string) Expression { return newPrefixTimeExpression("INTERVAL", literal(interval)) } + +//---------------------------------------------------// + +type timeExpressionWrapper struct { + timeInterfaceImpl + Expression +} + +func newTimeExpressionWrap(expression Expression) TimeExpression { + timeExpressionWrap := timeExpressionWrapper{Expression: expression} + timeExpressionWrap.timeInterfaceImpl.parent = &timeExpressionWrap + return &timeExpressionWrap +} + +func TimeExp(expression Expression) TimeExpression { + return newTimeExpressionWrap(expression) +} diff --git a/sqlbuilder/time_expression_test.go b/sqlbuilder/time_expression_test.go index 5b35c55..842da6c 100644 --- a/sqlbuilder/time_expression_test.go +++ b/sqlbuilder/time_expression_test.go @@ -33,3 +33,9 @@ func TestTimeExpressionGT_EQ(t *testing.T) { assertClauseSerialize(t, table1ColTime.GT_EQ(table2ColTime), "(table1.colTime >= table2.colTime)") assertClauseSerialize(t, table1ColTime.GT_EQ(Time(10, 20, 0, 0)), "(table1.colTime >= $1::time without time zone)", "10:20:00.000") } + +func TestTimeExp(t *testing.T) { + assertClauseSerialize(t, TimeExp(table1ColFloat), "table1.colFloat") + assertClauseSerialize(t, TimeExp(table1ColFloat).LT(Time(1, 1, 1, 1)), + "(table1.colFloat < $1::time without time zone)", string("01:01:01.001")) +} diff --git a/sqlbuilder/timestamp_expression.go b/sqlbuilder/timestamp_expression.go index 9b69925..3f64e7b 100644 --- a/sqlbuilder/timestamp_expression.go +++ b/sqlbuilder/timestamp_expression.go @@ -49,3 +49,20 @@ func (t *timestampInterfaceImpl) GT(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) GT_EQ(rhs TimestampExpression) BoolExpression { return GT_EQ(t.parent, rhs) } + +//------------------------------------------------- + +type timestampExpressionWrapper struct { + timestampInterfaceImpl + Expression +} + +func newTimestampExpressionWrap(expression Expression) TimestampExpression { + timestampExpressionWrap := timestampExpressionWrapper{Expression: expression} + timestampExpressionWrap.timestampInterfaceImpl.parent = ×tampExpressionWrap + return ×tampExpressionWrap +} + +func TimestampExp(expression Expression) TimestampExpression { + return newTimestampExpressionWrap(expression) +} diff --git a/sqlbuilder/timestampz_expression.go b/sqlbuilder/timestampz_expression.go index 20d9c0a..36bbb33 100644 --- a/sqlbuilder/timestampz_expression.go +++ b/sqlbuilder/timestampz_expression.go @@ -49,3 +49,20 @@ func (t *timestampzInterfaceImpl) GT(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) GT_EQ(rhs TimestampzExpression) BoolExpression { return GT_EQ(t.parent, rhs) } + +//------------------------------------------------- + +type timestampzExpressionWrapper struct { + timestampzInterfaceImpl + Expression +} + +func newTimestampzExpressionWrap(expression Expression) TimestampzExpression { + timestampzExpressionWrap := timestampzExpressionWrapper{Expression: expression} + timestampzExpressionWrap.timestampzInterfaceImpl.parent = ×tampzExpressionWrap + return ×tampzExpressionWrap +} + +func TimestampzExp(expression Expression) TimestampExpression { + return newTimestampExpressionWrap(expression) +} diff --git a/sqlbuilder/timez_expression.go b/sqlbuilder/timez_expression.go index 9d385a4..56decc9 100644 --- a/sqlbuilder/timez_expression.go +++ b/sqlbuilder/timez_expression.go @@ -67,3 +67,20 @@ func newPrefixTimezExpression(operator string, expression Expression) TimezExpre return &timeExpr } + +//---------------------------------------------------// + +type timezExpressionWrapper struct { + timezInterfaceImpl + Expression +} + +func newTimezExpressionWrap(expression Expression) TimezExpression { + timezExpressionWrap := timezExpressionWrapper{Expression: expression} + timezExpressionWrap.timezInterfaceImpl.parent = &timezExpressionWrap + return &timezExpressionWrap +} + +func TimezExp(expression Expression) TimeExpression { + return newTimeExpressionWrap(expression) +} diff --git a/tests/select_test.go b/tests/select_test.go index a6534ea..d088cb1 100644 --- a/tests/select_test.go +++ b/tests/select_test.go @@ -700,27 +700,6 @@ LIMIT 1000; //} func TestSubQuery(t *testing.T) { - - //selectStmtTable := Actor.SELECT(Actor.FirstName, Actor.LastName).AsTable("table_expression") - // - //query := selectStmtTable.SELECT( - // selectStmtTable.RefStringColumn(Actor.FirstName).AS("nesto"), - // selectStmtTable.RefIntColumnName("actor.last_name").AS("nesto2"), - // ) - // - //queryStr, args, err := query.Sql() - // - //assert.NilError(t, err) - // - //fmt.Println(queryStr) - // - //avrgCustomer := NumExp(Customer.SELECT(Customer.LastName).LIMIT(1)) - // - //Customer. - // innerJoin(selectStmtTable, Customer.LastName.EQ(selectStmtTable.RefStringColumn(Actor.FirstName))). - // SELECT(Customer.AllColumns, selectStmtTable.RefIntColumnName("first_name")). - // WHERE(Actor.LastName.Neq(avrgCustomer)) - expectedQuery := ` SELECT actor.actor_id AS "actor.actor_id", actor.first_name AS "actor.first_name", @@ -742,12 +721,20 @@ FROM dvds.actor ) AS films ON (film_actor.film_id = films."film.film_id"); ` - rFilmsOnly := Film.SELECT(Film.FilmID, Film.Title, Film.Rating). + rFilmsOnly := Film. + SELECT( + Film.FilmID, + Film.Title, + Film.Rating, + ). WHERE(Film.Rating.EQ(enum.MpaaRating.R)). AsTable("films") - query := Actor.INNER_JOIN(FilmActor, Actor.ActorID.EQ(FilmActor.FilmID)). - INNER_JOIN(rFilmsOnly, FilmActor.FilmID.EQ(rFilmsOnly.RefIntColumn(Film.FilmID))). + rFilmId := rFilmsOnly.RefIntColumn(Film.FilmID) + + query := Actor. + INNER_JOIN(FilmActor, Actor.ActorID.EQ(FilmActor.FilmID)). + INNER_JOIN(rFilmsOnly, FilmActor.FilmID.EQ(rFilmId)). SELECT( Actor.AllColumns, FilmActor.AllColumns, @@ -806,11 +793,11 @@ FROM dvds.film WHERE film.rental_rate = ( SELECT MAX(film.rental_rate) FROM dvds.film - ) + )::double precision ORDER BY film.film_id ASC; ` - maxFilmRentalRate := NumExp(Film.SELECT(MAXf(Film.RentalRate))) + maxFilmRentalRate := Film.SELECT(MAXf(Film.RentalRate)).TO_DOUBLE() query := Film. SELECT(Film.AllColumns). @@ -936,10 +923,14 @@ ORDER BY customer_payment_sum.amount_sum ASC; customersPaymentTable := customersPaymentSubQuery.AsTable("customer_payment_sum") amountSumColumn := customersPaymentTable.RefIntColumnName("amount_sum") + customerId := customersPaymentTable.RefIntColumn(Payment.CustomerID) query := Customer. - INNER_JOIN(customersPaymentTable, Customer.CustomerID.EQ(customersPaymentTable.RefIntColumn(Payment.CustomerID))). - SELECT(Customer.AllColumns, amountSumColumn.AS("customer_with_amounts.amount_sum")). + INNER_JOIN(customersPaymentTable, Customer.CustomerID.EQ(customerId)). + SELECT( + Customer.AllColumns, + amountSumColumn.AS("customer_with_amounts.amount_sum"), + ). ORDER_BY(amountSumColumn.ASC()) assertQuery(t, query, expectedSql) diff --git a/tests/types_test.go b/tests/types_test.go index a143667..ed47697 100644 --- a/tests/types_test.go +++ b/tests/types_test.go @@ -34,15 +34,20 @@ func TestExpressionOperators(t *testing.T) { AllTypes.SmallintPtr.NOT_IN(Int(11), Int(22), NULL), AllTypes.SmallintPtr.NOT_IN(AllTypes.SELECT(AllTypes.IntegerPtr)), - String("TRUE").CAST_TO_BOOL(), - String("111").CAST_TO_INTEGER(), - String("11.23").CAST_TO_DOUBLE(), - Int(234).CAST_TO_TEXT(), - String("1/8/1999").CAST_TO_DATE(), - String("04:05:06.789").CAST_TO_TIME(), - String("04:05:06 PST").CAST_TO_TIMEZ(), - String("1999-01-08 04:05:06").CAST_TO_TIMESTAMP(), - String("January 8 04:05:06 1999 PST").CAST_TO_TIMESTAMPZ(), + String("TRUE").TO_BOOL(), + String("111").TO_SMALLINT(), + String("111").TO_INTEGER(), + String("111").TO_BIGINT(), + String("11.23").TO_NUMERIC(30, 10), + String("11.23").TO_NUMERIC(30), + String("11.23").TO_REAL(), + String("11.23").TO_DOUBLE(), + Int(234).TO_TEXT(), + String("1/8/1999").TO_DATE(), + String("04:05:06.789").TO_TIME(), + String("04:05:06 PST").TO_TIMEZ(), + String("1999-01-08 04:05:06").TO_TIMESTAMP(), + String("January 8 04:05:06 1999 PST").TO_TIMESTAMPZ(), TO_CHAR(AllTypes.Timestamp, String("HH12:MI:SS")), TO_CHAR(AllTypes.Integer, String("999")),