Time, Timez, Timestamp, Timestampz, Date column types added.

This commit is contained in:
zer0sub 2019-05-30 14:49:36 +02:00
parent 7b89caa7e0
commit 7f5ba98819
20 changed files with 620 additions and 60 deletions

View file

@ -20,8 +20,16 @@ func (c ColumnInfo) SqlBuilderColumnType() string {
return "BoolColumn" return "BoolColumn"
case "smallint", "integer", "bigint": case "smallint", "integer", "bigint":
return "IntegerColumn" return "IntegerColumn"
case "date", "timestamp without time zone", "timestamp with time zone", "time with time zone", "time without time zone": case "date":
return "DateColumn"
case "timestamp without time zone":
return "TimestampColumn"
case "timestamp with time zone":
return "TimestampzColumn"
case "time without time zone":
return "TimeColumn" return "TimeColumn"
case "time with time zone":
return "TimezColumn"
case "USER-DEFINED", "text", "character", "character varying", "bytea", "uuid", case "USER-DEFINED", "text", "character", "character varying", "bytea", "uuid",
"tsvector", "bit", "bit varying", "money", "json", "jsonb", "xml", "point", "interval", "line", "ARRAY": "tsvector", "bit", "bit varying", "money", "json", "jsonb", "xml", "point", "interval", "line", "ARRAY":
return "StringColumn" return "StringColumn"

View file

@ -5,6 +5,8 @@ type boolExpression interface {
EQ(expression boolExpression) boolExpression EQ(expression boolExpression) boolExpression
NOT_EQ(expression boolExpression) boolExpression NOT_EQ(expression boolExpression) boolExpression
IS_DISTINCT_FROM(rhs boolExpression) boolExpression
IS_NOT_DISTINCT_FROM(rhs boolExpression) boolExpression
IS_TRUE() boolExpression IS_TRUE() boolExpression
IS_NOT_TRUE() boolExpression IS_NOT_TRUE() boolExpression
@ -29,6 +31,14 @@ func (b *boolInterfaceImpl) NOT_EQ(expression boolExpression) boolExpression {
return NOT_EQ(b.parent, expression) return NOT_EQ(b.parent, expression)
} }
func (b *boolInterfaceImpl) IS_DISTINCT_FROM(rhs boolExpression) boolExpression {
return IS_DISTINCT_FROM(b.parent, rhs)
}
func (b *boolInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs boolExpression) boolExpression {
return IS_NOT_DISTINCT_FROM(b.parent, rhs)
}
func (b *boolInterfaceImpl) AND(expression boolExpression) boolExpression { func (b *boolInterfaceImpl) AND(expression boolExpression) boolExpression {
return And(b.parent, expression) return And(b.parent, expression)
} }

View file

@ -192,10 +192,8 @@ func ArgToString(value interface{}) string {
case string: case string:
return `'` + bindVal + `'` return `'` + bindVal + `'`
case []byte: case []byte:
return string(bindVal) return `'` + string(bindVal) + `'`
//TODO: implement //TODO: implement
//case time.Time:
// return bindVal.String())
default: default:
return "[Unknown type]" return "[Unknown type]"
} }

View file

@ -85,13 +85,89 @@ type TimeColumn struct {
// Representation of any integer column // Representation of any integer column
// This function will panic if name is not valid // This function will panic if name is not valid
func NewTimeColumn(name string, nullable NullableColumn) *TimeColumn { func NewTimeColumn(name string, nullable NullableColumn) *TimeColumn {
stringColumn := &TimeColumn{} timeColumn := &TimeColumn{}
stringColumn.timeInterfaceImpl.parent = stringColumn timeColumn.timeInterfaceImpl.parent = timeColumn
stringColumn.baseColumn = newBaseColumn(name, nullable, "", stringColumn) timeColumn.baseColumn = newBaseColumn(name, nullable, "", timeColumn)
return stringColumn return timeColumn
}
//------------------------------------------------------//
type TimezColumn struct {
timezInterfaceImpl
baseColumn
}
// Representation of any integer column
// This function will panic if name is not valid
func NewTimezColumn(name string, nullable NullableColumn) *TimezColumn {
timezColumn := &TimezColumn{}
timezColumn.timezInterfaceImpl.parent = timezColumn
timezColumn.baseColumn = newBaseColumn(name, nullable, "", timezColumn)
return timezColumn
}
//------------------------------------------------------//
type TimestampColumn struct {
timestampInterfaceImpl
baseColumn
}
// Representation of any integer column
// This function will panic if name is not valid
func NewTimestampColumn(name string, nullable NullableColumn) *TimestampColumn {
timestampColumn := &TimestampColumn{}
timestampColumn.timestampInterfaceImpl.parent = timestampColumn
timestampColumn.baseColumn = newBaseColumn(name, nullable, "", timestampColumn)
return timestampColumn
}
//------------------------------------------------------//
type TimestampzColumn struct {
timestampzInterfaceImpl
baseColumn
}
// Representation of any integer column
// This function will panic if name is not valid
func NewTimestampzColumn(name string, nullable NullableColumn) *TimestampzColumn {
timestampzColumn := &TimestampzColumn{}
timestampzColumn.timestampzInterfaceImpl.parent = timestampzColumn
timestampzColumn.baseColumn = newBaseColumn(name, nullable, "", timestampzColumn)
return timestampzColumn
}
//------------------------------------------------------//
type DateColumn struct {
dateInterfaceImpl
baseColumn
}
// Representation of any integer column
// This function will panic if name is not valid
func NewDateColumn(name string, nullable NullableColumn) *DateColumn {
dateColumn := &DateColumn{}
dateColumn.dateInterfaceImpl.parent = dateColumn
dateColumn.baseColumn = newBaseColumn(name, nullable, "", dateColumn)
return dateColumn
} }
// ------------------------------------------------------// // ------------------------------------------------------//

View file

@ -0,0 +1,51 @@
package sqlbuilder
type DateExpression interface {
expression
EQ(rhs DateExpression) boolExpression
NOT_EQ(rhs DateExpression) boolExpression
IS_DISTINCT_FROM(rhs DateExpression) boolExpression
IS_NOT_DISTINCT_FROM(rhs DateExpression) boolExpression
LT(rhs DateExpression) boolExpression
LT_EQ(rhs DateExpression) boolExpression
GT(rhs DateExpression) boolExpression
GT_EQ(rhs DateExpression) boolExpression
}
type dateInterfaceImpl struct {
parent DateExpression
}
func (t *dateInterfaceImpl) EQ(rhs DateExpression) boolExpression {
return EQ(t.parent, rhs)
}
func (t *dateInterfaceImpl) NOT_EQ(rhs DateExpression) boolExpression {
return NOT_EQ(t.parent, rhs)
}
func (t *dateInterfaceImpl) IS_DISTINCT_FROM(rhs DateExpression) boolExpression {
return IS_DISTINCT_FROM(t.parent, rhs)
}
func (t *dateInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs DateExpression) boolExpression {
return IS_NOT_DISTINCT_FROM(t.parent, rhs)
}
func (t *dateInterfaceImpl) LT(rhs DateExpression) boolExpression {
return LT(t.parent, rhs)
}
func (t *dateInterfaceImpl) LT_EQ(rhs DateExpression) boolExpression {
return LT_EQ(t.parent, rhs)
}
func (t *dateInterfaceImpl) GT(rhs DateExpression) boolExpression {
return GT(t.parent, rhs)
}
func (t *dateInterfaceImpl) GT_EQ(rhs DateExpression) boolExpression {
return GT_EQ(t.parent, rhs)
}

View file

@ -13,8 +13,6 @@ type expression interface {
IS_NULL() boolExpression IS_NULL() boolExpression
IS_NOT_NULL() boolExpression IS_NOT_NULL() boolExpression
IS_DISTINCT_FROM(expression expression) boolExpression
IS_NOT_DISTINCT_FROM(expression expression) boolExpression
IN(subQuery selectStatement) boolExpression IN(subQuery selectStatement) boolExpression
NOT_IN(subQuery selectStatement) boolExpression NOT_IN(subQuery selectStatement) boolExpression
@ -37,14 +35,6 @@ func (e *expressionInterfaceImpl) IS_NOT_NULL() boolExpression {
return newPostifxBoolExpression(e.parent, "IS NOT NULL") return newPostifxBoolExpression(e.parent, "IS NOT NULL")
} }
func (e *expressionInterfaceImpl) IS_DISTINCT_FROM(expression expression) boolExpression {
return newBinaryBoolExpression(e.parent, expression, "IS DISTINCT FROM")
}
func (e *expressionInterfaceImpl) IS_NOT_DISTINCT_FROM(expression expression) boolExpression {
return newBinaryBoolExpression(e.parent, expression, "IS NOT DISTINCT FROM")
}
func (e *expressionInterfaceImpl) IN(subQuery selectStatement) boolExpression { func (e *expressionInterfaceImpl) IN(subQuery selectStatement) boolExpression {
return newBinaryBoolExpression(e.parent, subQuery, "IN") return newBinaryBoolExpression(e.parent, subQuery, "IN")
} }

View file

@ -16,11 +16,11 @@ func TestExpressionIS_NOT_NULL(t *testing.T) {
} }
func TestExpressionIS_DISTINCT_FROM(t *testing.T) { func TestExpressionIS_DISTINCT_FROM(t *testing.T) {
assert.Equal(t, getTestSerialize(t, table2Col3.IS_DISTINCT_FROM(table2StrCol)), "table2.col3 IS DISTINCT FROM table2.col4") assert.Equal(t, getTestSerialize(t, table2Col3.IS_DISTINCT_FROM(table2Col4)), "table2.col3 IS DISTINCT FROM table2.col4")
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_DISTINCT_FROM(Int(23))), "(table2.col3 + table2.col3 IS DISTINCT FROM $1)") assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_DISTINCT_FROM(Int(23))), "(table2.col3 + table2.col3 IS DISTINCT FROM $1)")
} }
func TestExpressionIS_NOT_DISTINCT_FROM(t *testing.T) { func TestExpressionIS_NOT_DISTINCT_FROM(t *testing.T) {
assert.Equal(t, getTestSerialize(t, table2Col3.IS_NOT_DISTINCT_FROM(table2StrCol)), "table2.col3 IS NOT DISTINCT FROM table2.col4") assert.Equal(t, getTestSerialize(t, table2Col3.IS_NOT_DISTINCT_FROM(table2Col4)), "table2.col3 IS NOT DISTINCT FROM table2.col4")
assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_DISTINCT_FROM(Int(23))), "(table2.col3 + table2.col3 IS NOT DISTINCT FROM $1)") assert.Equal(t, getTestSerialize(t, table2Col3.ADD(table2Col3).IS_NOT_DISTINCT_FROM(Int(23))), "(table2.col3 + table2.col3 IS NOT DISTINCT FROM $1)")
} }

View file

@ -1,6 +1,6 @@
package sqlbuilder package sqlbuilder
import "time" import "fmt"
// Representation of an escaped literal // Representation of an escaped literal
type literalExpression struct { type literalExpression struct {
@ -88,11 +88,78 @@ type timeLiteral struct {
literalExpression literalExpression
} }
func Time(value time.Time) timeExpression { func Time(hour, minute, second, milliseconds int) timeExpression {
timeLiteral := timeLiteral{} timeLiteral := timeLiteral{}
timeLiteral.literalExpression = *Literal(value) timeStr := fmt.Sprintf("%02d:%02d:%02d.%03d", hour, minute, second, milliseconds)
timeLiteral.literalExpression = *Literal(timeStr)
timeLiteral.timeInterfaceImpl.parent = &timeLiteral timeLiteral.timeInterfaceImpl.parent = &timeLiteral
return &timeLiteral return &timeLiteral
} }
//---------------------------------------------------//
type timezLiteral struct {
timezInterfaceImpl
literalExpression
}
func Timez(hour, minute, second, milliseconds, timezone int) timezExpression {
timezLiteral := timezLiteral{}
timeStr := fmt.Sprintf("%02d:%02d:%02d.%03d %+03d", hour, minute, second, milliseconds, timezone)
timezLiteral.literalExpression = *Literal(timeStr)
timezLiteral.timezInterfaceImpl.parent = &timezLiteral
return &timezLiteral
}
//---------------------------------------------------//
type timestampLiteral struct {
timestampInterfaceImpl
literalExpression
}
func Timestamp(year, month, day, hour, minute, second, milliseconds int) TimestampExpression {
timestampLiteral := timestampLiteral{}
timeStr := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d.%03d", year, month, day, hour, minute, second, milliseconds)
timestampLiteral.literalExpression = *Literal(timeStr)
timestampLiteral.timestampInterfaceImpl.parent = &timestampLiteral
return &timestampLiteral
}
//---------------------------------------------------//
type timestampzLiteral struct {
timestampzInterfaceImpl
literalExpression
}
func Timestampz(year, month, day, hour, minute, second, milliseconds, timezone int) TimestampzExpression {
timestampzLiteral := timestampzLiteral{}
timeStr := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d.%03d %+04d",
year, month, day, hour, minute, second, milliseconds, timezone)
timestampzLiteral.literalExpression = *Literal(timeStr)
timestampzLiteral.timestampzInterfaceImpl.parent = &timestampzLiteral
return &timestampzLiteral
}
//---------------------------------------------------//
type dateLiteral struct {
dateInterfaceImpl
literalExpression
}
func Date(year, month, day int) DateExpression {
dateLiteral := dateLiteral{}
timeStr := fmt.Sprintf("%04d-%02d-%02d", year, month, day)
dateLiteral.literalExpression = *Literal(timeStr)
dateLiteral.dateInterfaceImpl.parent = &dateLiteral
return &dateLiteral
}

View file

@ -5,37 +5,48 @@ import "errors"
type numericExpression interface { type numericExpression interface {
expression expression
EQ(expression numericExpression) boolExpression EQ(rhs numericExpression) boolExpression
NOT_EQ(expression numericExpression) boolExpression NOT_EQ(rhs numericExpression) boolExpression
IS_DISTINCT_FROM(rhs numericExpression) boolExpression
IS_NOT_DISTINCT_FROM(rhs numericExpression) boolExpression
LT(rhs numericExpression) boolExpression LT(rhs numericExpression) boolExpression
LT_EQ(rhs numericExpression) boolExpression LT_EQ(rhs numericExpression) boolExpression
GT(rhs numericExpression) boolExpression GT(rhs numericExpression) boolExpression
GT_EQ(rhs numericExpression) boolExpression GT_EQ(rhs numericExpression) boolExpression
ADD(expression numericExpression) numericExpression ADD(rhs numericExpression) numericExpression
SUB(expression numericExpression) numericExpression SUB(rhs numericExpression) numericExpression
MUL(expression numericExpression) numericExpression MUL(rhs numericExpression) numericExpression
DIV(expression numericExpression) numericExpression DIV(rhs numericExpression) numericExpression
} }
type numericInterfaceImpl struct { type numericInterfaceImpl struct {
parent numericExpression parent numericExpression
} }
func (n *numericInterfaceImpl) EQ(expression numericExpression) boolExpression { func (n *numericInterfaceImpl) EQ(rhs numericExpression) boolExpression {
return EQ(n.parent, expression) return EQ(n.parent, rhs)
} }
func (n *numericInterfaceImpl) NOT_EQ(expression numericExpression) boolExpression { func (n *numericInterfaceImpl) NOT_EQ(rhs numericExpression) boolExpression {
return NOT_EQ(n.parent, expression) return NOT_EQ(n.parent, rhs)
} }
func (n *numericInterfaceImpl) GT(expression numericExpression) boolExpression { func (n *numericInterfaceImpl) IS_DISTINCT_FROM(rhs numericExpression) boolExpression {
return GT(n.parent, expression) return IS_DISTINCT_FROM(n.parent, rhs)
} }
func (n *numericInterfaceImpl) GT_EQ(expression numericExpression) boolExpression { func (n *numericInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs numericExpression) boolExpression {
return GT_EQ(n.parent, expression) return IS_NOT_DISTINCT_FROM(n.parent, rhs)
}
func (n *numericInterfaceImpl) GT(rhs numericExpression) boolExpression {
return GT(n.parent, rhs)
}
func (n *numericInterfaceImpl) GT_EQ(rhs numericExpression) boolExpression {
return GT_EQ(n.parent, rhs)
} }
func (n *numericInterfaceImpl) LT(expression numericExpression) boolExpression { func (n *numericInterfaceImpl) LT(expression numericExpression) boolExpression {

View file

@ -19,6 +19,14 @@ func NOT_EQ(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "!=") return newBinaryBoolExpression(lhs, rhs, "!=")
} }
func IS_DISTINCT_FROM(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "IS DISTINCT FROM")
}
func IS_NOT_DISTINCT_FROM(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "IS NOT DISTINCT FROM")
}
// Returns a representation of "a<b" // Returns a representation of "a<b"
func LT(lhs expression, rhs expression) boolExpression { func LT(lhs expression, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "<") return newBinaryBoolExpression(lhs, rhs, "<")

View file

@ -5,6 +5,9 @@ type stringExpression interface {
EQ(rhs stringExpression) boolExpression EQ(rhs stringExpression) boolExpression
NOT_EQ(rhs stringExpression) boolExpression NOT_EQ(rhs stringExpression) boolExpression
IS_DISTINCT_FROM(rhs stringExpression) boolExpression
IS_NOT_DISTINCT_FROM(rhs stringExpression) boolExpression
LT(rhs stringExpression) boolExpression LT(rhs stringExpression) boolExpression
LT_EQ(rhs stringExpression) boolExpression LT_EQ(rhs stringExpression) boolExpression
GT(rhs stringExpression) boolExpression GT(rhs stringExpression) boolExpression
@ -23,6 +26,14 @@ func (s *stringInterfaceImpl) NOT_EQ(rhs stringExpression) boolExpression {
return NOT_EQ(s.parent, rhs) return NOT_EQ(s.parent, rhs)
} }
func (s *stringInterfaceImpl) IS_DISTINCT_FROM(rhs stringExpression) boolExpression {
return IS_DISTINCT_FROM(s.parent, rhs)
}
func (s *stringInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs stringExpression) boolExpression {
return IS_NOT_DISTINCT_FROM(s.parent, rhs)
}
func (s *stringInterfaceImpl) GT(rhs stringExpression) boolExpression { func (s *stringInterfaceImpl) GT(rhs stringExpression) boolExpression {
return GT(s.parent, rhs) return GT(s.parent, rhs)
} }

View file

@ -12,7 +12,7 @@ func TestStringEQColumn(t *testing.T) {
err := exp.serialize(select_statement, &out) err := exp.serialize(select_statement, &out)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "table3.col2 = table2.col4") assert.Equal(t, out.buff.String(), "table3.col2 = table2.colStr")
} }
func TestStringEQString(t *testing.T) { func TestStringEQString(t *testing.T) {
@ -32,7 +32,7 @@ func TestStringNOT_EQ(t *testing.T) {
err := exp.serialize(select_statement, &out) err := exp.serialize(select_statement, &out)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "table3.col2 != table2.col4") assert.Equal(t, out.buff.String(), "table3.col2 != table2.colStr")
} }
func TestStringGT(t *testing.T) { func TestStringGT(t *testing.T) {
@ -42,7 +42,7 @@ func TestStringGT(t *testing.T) {
err := exp.serialize(select_statement, &out) err := exp.serialize(select_statement, &out)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "table3.col2 > table2.col4") assert.Equal(t, out.buff.String(), "table3.col2 > table2.colStr")
} }
func TestStringGT_EQ(t *testing.T) { func TestStringGT_EQ(t *testing.T) {
@ -52,7 +52,7 @@ func TestStringGT_EQ(t *testing.T) {
err := exp.serialize(select_statement, &out) err := exp.serialize(select_statement, &out)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "table3.col2 >= table2.col4") assert.Equal(t, out.buff.String(), "table3.col2 >= table2.colStr")
} }
func TestStringLT(t *testing.T) { func TestStringLT(t *testing.T) {
@ -62,7 +62,7 @@ func TestStringLT(t *testing.T) {
err := exp.serialize(select_statement, &out) err := exp.serialize(select_statement, &out)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "table3.col2 < table2.col4") assert.Equal(t, out.buff.String(), "table3.col2 < table2.colStr")
} }
func TestStringLT_EQ(t *testing.T) { func TestStringLT_EQ(t *testing.T) {
@ -72,5 +72,5 @@ func TestStringLT_EQ(t *testing.T) {
err := exp.serialize(select_statement, &out) err := exp.serialize(select_statement, &out)
assert.NilError(t, err) assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "table3.col2 <= table2.col4") assert.Equal(t, out.buff.String(), "table3.col2 <= table2.colStr")
} }

View file

@ -22,7 +22,7 @@ var table1 = NewTable(
var table2Col3 = NewIntegerColumn("col3", Nullable) var table2Col3 = NewIntegerColumn("col3", Nullable)
var table2Col4 = NewIntegerColumn("col4", Nullable) var table2Col4 = NewIntegerColumn("col4", Nullable)
var table2StrCol = NewStringColumn("col4", Nullable) var table2StrCol = NewStringColumn("colStr", Nullable)
var table2ColBool = NewBoolColumn("colBool", Nullable) var table2ColBool = NewBoolColumn("colBool", Nullable)
var table2ColTime = NewTimeColumn("colTime", Nullable) var table2ColTime = NewTimeColumn("colTime", Nullable)

View file

@ -5,6 +5,9 @@ type timeExpression interface {
EQ(rhs timeExpression) boolExpression EQ(rhs timeExpression) boolExpression
NOT_EQ(rhs timeExpression) boolExpression NOT_EQ(rhs timeExpression) boolExpression
IS_DISTINCT_FROM(rhs timeExpression) boolExpression
IS_NOT_DISTINCT_FROM(rhs timeExpression) boolExpression
LT(rhs timeExpression) boolExpression LT(rhs timeExpression) boolExpression
LT_EQ(rhs timeExpression) boolExpression LT_EQ(rhs timeExpression) boolExpression
GT(rhs timeExpression) boolExpression GT(rhs timeExpression) boolExpression
@ -23,6 +26,14 @@ func (t *timeInterfaceImpl) NOT_EQ(rhs timeExpression) boolExpression {
return NOT_EQ(t.parent, rhs) return NOT_EQ(t.parent, rhs)
} }
func (t *timeInterfaceImpl) IS_DISTINCT_FROM(rhs timeExpression) boolExpression {
return IS_DISTINCT_FROM(t.parent, rhs)
}
func (t *timeInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs timeExpression) boolExpression {
return IS_NOT_DISTINCT_FROM(t.parent, rhs)
}
func (t *timeInterfaceImpl) LT(rhs timeExpression) boolExpression { func (t *timeInterfaceImpl) LT(rhs timeExpression) boolExpression {
return LT(t.parent, rhs) return LT(t.parent, rhs)
} }
@ -47,7 +58,7 @@ type prefixTimeExpression struct {
prefixOpExpression prefixOpExpression
} }
func newPrefixTimeExpression(expression expression, operator string) timeExpression { func newPrefixTimeExpression(operator string, expression expression) timeExpression {
timeExpr := prefixTimeExpression{} timeExpr := prefixTimeExpression{}
timeExpr.prefixOpExpression = newPrefixExpression(expression, operator) timeExpr.prefixOpExpression = newPrefixExpression(expression, operator)
@ -58,5 +69,5 @@ func newPrefixTimeExpression(expression expression, operator string) timeExpress
} }
func INTERVAL(interval string) expression { func INTERVAL(interval string) expression {
return newPrefixTimeExpression(Literal(interval), "INTERVAL") return newPrefixTimeExpression("INTERVAL", Literal(interval))
} }

View file

@ -3,35 +3,34 @@ package sqlbuilder
import ( import (
"gotest.tools/assert" "gotest.tools/assert"
"testing" "testing"
"time"
) )
func TestTimeExpressionEQ(t *testing.T) { func TestTimeExpressionEQ(t *testing.T) {
assert.Equal(t, getTestSerialize(t, table1ColTime.EQ(table2ColTime)), "table1.colTime = table2.colTime") assert.Equal(t, getTestSerialize(t, table1ColTime.EQ(table2ColTime)), "table1.colTime = table2.colTime")
assert.Equal(t, getTestSerialize(t, table1ColTime.EQ(Time(time.Now()))), "table1.colTime = $1") assert.Equal(t, getTestSerialize(t, table1ColTime.EQ(Time(10, 20, 0, 0))), "table1.colTime = $1")
} }
func TestTimeExpressionNOT_EQ(t *testing.T) { func TestTimeExpressionNOT_EQ(t *testing.T) {
assert.Equal(t, getTestSerialize(t, table1ColTime.NOT_EQ(table2ColTime)), "table1.colTime != table2.colTime") assert.Equal(t, getTestSerialize(t, table1ColTime.NOT_EQ(table2ColTime)), "table1.colTime != table2.colTime")
assert.Equal(t, getTestSerialize(t, table1ColTime.NOT_EQ(Time(time.Now()))), "table1.colTime != $1") assert.Equal(t, getTestSerialize(t, table1ColTime.NOT_EQ(Time(10, 20, 0, 0))), "table1.colTime != $1")
} }
func TestTimeExpressionLT(t *testing.T) { func TestTimeExpressionLT(t *testing.T) {
assert.Equal(t, getTestSerialize(t, table1ColTime.LT(table2ColTime)), "table1.colTime < table2.colTime") assert.Equal(t, getTestSerialize(t, table1ColTime.LT(table2ColTime)), "table1.colTime < table2.colTime")
assert.Equal(t, getTestSerialize(t, table1ColTime.LT(Time(time.Now()))), "table1.colTime < $1") assert.Equal(t, getTestSerialize(t, table1ColTime.LT(Time(10, 20, 0, 0))), "table1.colTime < $1")
} }
func TestTimeExpressionLT_EQ(t *testing.T) { func TestTimeExpressionLT_EQ(t *testing.T) {
assert.Equal(t, getTestSerialize(t, table1ColTime.LT_EQ(table2ColTime)), "table1.colTime <= table2.colTime") assert.Equal(t, getTestSerialize(t, table1ColTime.LT_EQ(table2ColTime)), "table1.colTime <= table2.colTime")
assert.Equal(t, getTestSerialize(t, table1ColTime.LT_EQ(Time(time.Now()))), "table1.colTime <= $1") assert.Equal(t, getTestSerialize(t, table1ColTime.LT_EQ(Time(10, 20, 0, 0))), "table1.colTime <= $1")
} }
func TestTimeExpressionGT(t *testing.T) { func TestTimeExpressionGT(t *testing.T) {
assert.Equal(t, getTestSerialize(t, table1ColTime.GT(table2ColTime)), "table1.colTime > table2.colTime") assert.Equal(t, getTestSerialize(t, table1ColTime.GT(table2ColTime)), "table1.colTime > table2.colTime")
assert.Equal(t, getTestSerialize(t, table1ColTime.GT(Time(time.Now()))), "table1.colTime > $1") assert.Equal(t, getTestSerialize(t, table1ColTime.GT(Time(10, 20, 0, 0))), "table1.colTime > $1")
} }
func TestTimeExpressionGT_EQ(t *testing.T) { func TestTimeExpressionGT_EQ(t *testing.T) {
assert.Equal(t, getTestSerialize(t, table1ColTime.GT_EQ(table2ColTime)), "table1.colTime >= table2.colTime") assert.Equal(t, getTestSerialize(t, table1ColTime.GT_EQ(table2ColTime)), "table1.colTime >= table2.colTime")
assert.Equal(t, getTestSerialize(t, table1ColTime.GT_EQ(Time(time.Now()))), "table1.colTime >= $1") assert.Equal(t, getTestSerialize(t, table1ColTime.GT_EQ(Time(10, 20, 0, 0))), "table1.colTime >= $1")
} }

View file

@ -0,0 +1,51 @@
package sqlbuilder
type TimestampExpression interface {
expression
EQ(rhs TimestampExpression) boolExpression
NOT_EQ(rhs TimestampExpression) boolExpression
IS_DISTINCT_FROM(rhs TimestampExpression) boolExpression
IS_NOT_DISTINCT_FROM(rhs TimestampExpression) boolExpression
LT(rhs TimestampExpression) boolExpression
LT_EQ(rhs TimestampExpression) boolExpression
GT(rhs TimestampExpression) boolExpression
GT_EQ(rhs TimestampExpression) boolExpression
}
type timestampInterfaceImpl struct {
parent TimestampExpression
}
func (t *timestampInterfaceImpl) EQ(rhs TimestampExpression) boolExpression {
return EQ(t.parent, rhs)
}
func (t *timestampInterfaceImpl) NOT_EQ(rhs TimestampExpression) boolExpression {
return NOT_EQ(t.parent, rhs)
}
func (t *timestampInterfaceImpl) IS_DISTINCT_FROM(rhs TimestampExpression) boolExpression {
return IS_DISTINCT_FROM(t.parent, rhs)
}
func (t *timestampInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimestampExpression) boolExpression {
return IS_NOT_DISTINCT_FROM(t.parent, rhs)
}
func (t *timestampInterfaceImpl) LT(rhs TimestampExpression) boolExpression {
return LT(t.parent, rhs)
}
func (t *timestampInterfaceImpl) LT_EQ(rhs TimestampExpression) boolExpression {
return LT_EQ(t.parent, rhs)
}
func (t *timestampInterfaceImpl) GT(rhs TimestampExpression) boolExpression {
return GT(t.parent, rhs)
}
func (t *timestampInterfaceImpl) GT_EQ(rhs TimestampExpression) boolExpression {
return GT_EQ(t.parent, rhs)
}

View file

@ -0,0 +1,51 @@
package sqlbuilder
type TimestampzExpression interface {
expression
EQ(rhs TimestampzExpression) boolExpression
NOT_EQ(rhs TimestampzExpression) boolExpression
IS_DISTINCT_FROM(rhs TimestampzExpression) boolExpression
IS_NOT_DISTINCT_FROM(rhs TimestampzExpression) boolExpression
LT(rhs TimestampzExpression) boolExpression
LT_EQ(rhs TimestampzExpression) boolExpression
GT(rhs TimestampzExpression) boolExpression
GT_EQ(rhs TimestampzExpression) boolExpression
}
type timestampzInterfaceImpl struct {
parent TimestampzExpression
}
func (t *timestampzInterfaceImpl) EQ(rhs TimestampzExpression) boolExpression {
return EQ(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) NOT_EQ(rhs TimestampzExpression) boolExpression {
return NOT_EQ(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) IS_DISTINCT_FROM(rhs TimestampzExpression) boolExpression {
return IS_DISTINCT_FROM(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimestampzExpression) boolExpression {
return IS_NOT_DISTINCT_FROM(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) LT(rhs TimestampzExpression) boolExpression {
return LT(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) LT_EQ(rhs TimestampzExpression) boolExpression {
return LT_EQ(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) GT(rhs TimestampzExpression) boolExpression {
return GT(t.parent, rhs)
}
func (t *timestampzInterfaceImpl) GT_EQ(rhs TimestampzExpression) boolExpression {
return GT_EQ(t.parent, rhs)
}

View file

@ -0,0 +1,69 @@
package sqlbuilder
type timezExpression interface {
expression
EQ(rhs timezExpression) boolExpression
NOT_EQ(rhs timezExpression) boolExpression
IS_DISTINCT_FROM(rhs timezExpression) boolExpression
IS_NOT_DISTINCT_FROM(rhs timezExpression) boolExpression
LT(rhs timezExpression) boolExpression
LT_EQ(rhs timezExpression) boolExpression
GT(rhs timezExpression) boolExpression
GT_EQ(rhs timezExpression) boolExpression
}
type timezInterfaceImpl struct {
parent timezExpression
}
func (t *timezInterfaceImpl) EQ(rhs timezExpression) boolExpression {
return EQ(t.parent, rhs)
}
func (t *timezInterfaceImpl) NOT_EQ(rhs timezExpression) boolExpression {
return NOT_EQ(t.parent, rhs)
}
func (t *timezInterfaceImpl) IS_DISTINCT_FROM(rhs timezExpression) boolExpression {
return IS_DISTINCT_FROM(t.parent, rhs)
}
func (t *timezInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs timezExpression) boolExpression {
return IS_NOT_DISTINCT_FROM(t.parent, rhs)
}
func (t *timezInterfaceImpl) LT(rhs timezExpression) boolExpression {
return LT(t.parent, rhs)
}
func (t *timezInterfaceImpl) LT_EQ(rhs timezExpression) boolExpression {
return LT_EQ(t.parent, rhs)
}
func (t *timezInterfaceImpl) GT(rhs timezExpression) boolExpression {
return GT(t.parent, rhs)
}
func (t *timezInterfaceImpl) GT_EQ(rhs timezExpression) boolExpression {
return GT_EQ(t.parent, rhs)
}
//---------------------------------------------------//
type prefixTimezExpression struct {
expressionInterfaceImpl
timezInterfaceImpl
prefixOpExpression
}
func newPrefixTimezExpression(operator string, expression expression) timezExpression {
timeExpr := prefixTimezExpression{}
timeExpr.prefixOpExpression = newPrefixExpression(expression, operator)
timeExpr.expressionInterfaceImpl.parent = &timeExpr
timeExpr.timezInterfaceImpl.parent = &timeExpr
return &timeExpr
}

View file

@ -971,15 +971,15 @@ SELECT payment.payment_id AS "payment.payment_id",
payment.amount AS "payment.amount", payment.amount AS "payment.amount",
payment.payment_date AS "payment.payment_date" payment.payment_date AS "payment.payment_date"
FROM dvds.payment FROM dvds.payment
WHERE payment.payment_date <= '2007-02-14 22:16:01' WHERE payment.payment_date < '2007-02-14 22:16:01.000'
ORDER BY payment.payment_date ASC; ORDER BY payment.payment_date ASC;
` `
query := Payment.SELECT(Payment.AllColumns). query := Payment.SELECT(Payment.AllColumns).
WHERE(Payment.PaymentDate.LtEqL("2007-02-14 22:16:01")). WHERE(Payment.PaymentDate.LT(Timestamp(2007, 02, 14, 22, 16, 01, 0))).
ORDER_BY(Payment.PaymentDate.ASC()) ORDER_BY(Payment.PaymentDate.ASC())
assertQuery(t, query, expectedSql, "2007-02-14 22:16:01") assertQuery(t, query, expectedSql, "2007-02-14 22:16:01.000")
payments := []model.Payment{} payments := []model.Payment{}

View file

@ -3,6 +3,7 @@ package tests
import ( import (
"fmt" "fmt"
"github.com/google/uuid" "github.com/google/uuid"
. "github.com/sub0zero/go-sqlbuilder/sqlbuilder"
"github.com/sub0zero/go-sqlbuilder/tests/.test_files/dvd_rental/test_sample/model" "github.com/sub0zero/go-sqlbuilder/tests/.test_files/dvd_rental/test_sample/model"
. "github.com/sub0zero/go-sqlbuilder/tests/.test_files/dvd_rental/test_sample/table" . "github.com/sub0zero/go-sqlbuilder/tests/.test_files/dvd_rental/test_sample/table"
"gotest.tools/assert" "gotest.tools/assert"
@ -20,11 +21,159 @@ func TestAllTypesSelect(t *testing.T) {
assert.Equal(t, len(dest), 2) assert.Equal(t, len(dest), 2)
assert.DeepEqual(t, dest[0], dest0) assert.DeepEqual(t, dest[0], allTypesRow0)
assert.DeepEqual(t, dest[1], dest1) assert.DeepEqual(t, dest[1], allTypesRow1)
} }
var dest0 = model.AllTypes{ func TestStringOperators(t *testing.T) {
query := AllTypes.SELECT(
AllTypes.Text.EQ(AllTypes.Character),
AllTypes.Text.EQ(String("Text")),
AllTypes.Text.NOT_EQ(AllTypes.CharacterVaryingPtr),
AllTypes.Text.NOT_EQ(String("Text")),
AllTypes.Text.GT(AllTypes.Text),
AllTypes.Text.GT(String("Text")),
AllTypes.Text.GT_EQ(AllTypes.TextPtr),
AllTypes.Text.GT_EQ(String("Text")),
AllTypes.Text.LT(AllTypes.Character),
AllTypes.Text.LT(String("Text")),
AllTypes.Text.LT_EQ(AllTypes.CharacterVaryingPtr),
AllTypes.Text.LT_EQ(String("Text")),
)
fmt.Println(query.DebugSql())
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
func TestExpressionOperators(t *testing.T) {
query := AllTypes.SELECT(
AllTypes.Integer.IS_NULL(),
AllTypes.Timestamp.IS_NOT_NULL(),
)
fmt.Println(query.DebugSql())
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
func TestBoolOperators(t *testing.T) {
query := AllTypes.SELECT(
AllTypes.Boolean.EQ(AllTypes.BooleanPtr),
AllTypes.Boolean.EQ(Bool(true)),
AllTypes.Boolean.NOT_EQ(AllTypes.BooleanPtr),
AllTypes.Boolean.NOT_EQ(Bool(false)),
AllTypes.Boolean.IS_DISTINCT_FROM(AllTypes.BooleanPtr),
AllTypes.Boolean.IS_DISTINCT_FROM(Bool(true)),
AllTypes.Boolean.IS_NOT_DISTINCT_FROM(AllTypes.BooleanPtr),
AllTypes.Boolean.IS_NOT_DISTINCT_FROM(Bool(true)),
AllTypes.Boolean.IS_TRUE(),
AllTypes.Boolean.IS_NOT_TRUE(),
AllTypes.Boolean.IS_NOT_FALSE(),
AllTypes.Boolean.IS_UNKNOWN(),
AllTypes.Boolean.IS_NOT_UNKNOWN(),
AllTypes.Boolean.AND(AllTypes.Boolean).EQ(AllTypes.Boolean.AND(AllTypes.Boolean)),
AllTypes.Boolean.OR(AllTypes.Boolean).EQ(AllTypes.Boolean.AND(AllTypes.Boolean)),
)
fmt.Println(query.DebugSql())
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
func TestNumericOperators(t *testing.T) {
query := AllTypes.SELECT(
AllTypes.Numeric.EQ(AllTypes.Numeric),
AllTypes.Decimal.EQ(Int(12)),
AllTypes.Real.EQ(Float(12.12)),
AllTypes.Smallint.NOT_EQ(AllTypes.Real),
AllTypes.Integer.NOT_EQ(Int(12)),
AllTypes.Bigint.NOT_EQ(Float(12)),
AllTypes.Numeric.IS_DISTINCT_FROM(AllTypes.Numeric),
AllTypes.Decimal.IS_DISTINCT_FROM(Int(12)),
AllTypes.Real.IS_DISTINCT_FROM(Float(12.12)),
AllTypes.Numeric.IS_NOT_DISTINCT_FROM(AllTypes.Numeric),
AllTypes.Decimal.IS_NOT_DISTINCT_FROM(Int(12)),
AllTypes.Real.IS_NOT_DISTINCT_FROM(Float(12.12)),
AllTypes.Numeric.LT(AllTypes.Integer),
AllTypes.Numeric.LT(Int(124)),
AllTypes.Numeric.LT(Float(34.56)),
AllTypes.Smallint.LT_EQ(AllTypes.Numeric),
AllTypes.Integer.LT_EQ(Int(45)),
AllTypes.Bigint.LT_EQ(Float(65)),
AllTypes.Numeric.GT(AllTypes.Smallint),
AllTypes.Numeric.GT(Int(124)),
AllTypes.Numeric.GT(Float(34.56)),
AllTypes.Smallint.GT_EQ(AllTypes.Numeric),
AllTypes.Integer.GT_EQ(Int(45)),
AllTypes.Bigint.GT_EQ(Float(65)),
)
fmt.Println(query.DebugSql())
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
func TestTimeOperators(t *testing.T) {
query := AllTypes.SELECT(
AllTypes.Time.EQ(AllTypes.Time),
AllTypes.Time.EQ(Time(23, 6, 6, 1)),
AllTypes.Timez.EQ(AllTypes.TimezPtr),
AllTypes.Timez.EQ(Timez(23, 6, 6, 222, +200)),
AllTypes.Timestamp.EQ(AllTypes.TimestampPtr),
AllTypes.Timestamp.EQ(Timestamp(2010, 10, 21, 15, 30, 12, 333)),
AllTypes.Timestampz.EQ(AllTypes.TimestampzPtr),
AllTypes.Timestampz.EQ(Timestampz(2010, 10, 21, 15, 30, 12, 444, 0)),
AllTypes.Date.EQ(AllTypes.DatePtr),
AllTypes.Date.EQ(Date(2010, 12, 3)),
AllTypes.Time.NOT_EQ(AllTypes.Time),
AllTypes.Time.NOT_EQ(Time(23, 6, 6, 10)),
AllTypes.Timez.NOT_EQ(AllTypes.TimezPtr),
AllTypes.Timez.NOT_EQ(Timez(23, 6, 6, 555, +200)),
AllTypes.Timestamp.NOT_EQ(AllTypes.TimestampPtr),
AllTypes.Timestamp.NOT_EQ(Timestamp(2010, 10, 21, 15, 30, 12, 666)),
AllTypes.Timestampz.NOT_EQ(AllTypes.TimestampzPtr),
AllTypes.Timestampz.NOT_EQ(Timestampz(2010, 10, 21, 15, 30, 12, 777, 0)),
AllTypes.Date.NOT_EQ(AllTypes.DatePtr),
AllTypes.Date.NOT_EQ(Date(2010, 12, 3)),
AllTypes.Time.IS_DISTINCT_FROM(AllTypes.Time),
AllTypes.Time.IS_DISTINCT_FROM(Time(23, 6, 6, 100)),
AllTypes.Time.IS_NOT_DISTINCT_FROM(AllTypes.Time),
AllTypes.Time.IS_NOT_DISTINCT_FROM(Time(23, 6, 6, 200)),
AllTypes.Time.LT(AllTypes.Time),
AllTypes.Time.LT(Time(23, 6, 6, 22)),
AllTypes.Time.LT_EQ(AllTypes.Time),
AllTypes.Time.LT_EQ(Time(23, 6, 6, 33)),
AllTypes.Time.GT(AllTypes.Time),
AllTypes.Time.GT(Time(23, 6, 6, 0)),
AllTypes.Time.GT_EQ(AllTypes.Time),
AllTypes.Time.GT_EQ(Time(23, 6, 6, 1)),
)
fmt.Println(query.DebugSql())
err := query.Query(db, &struct{}{})
assert.NilError(t, err)
}
var allTypesRow0 = model.AllTypes{
SmallintPtr: int16Ptr(1), SmallintPtr: int16Ptr(1),
Smallint: 1, Smallint: 1,
IntegerPtr: int32Ptr(300), IntegerPtr: int32Ptr(300),
@ -90,7 +239,7 @@ var dest0 = model.AllTypes{
TextMultiDimArray: "{{meeting,lunch},{training,presentation}}", TextMultiDimArray: "{{meeting,lunch},{training,presentation}}",
} }
var dest1 = model.AllTypes{ var allTypesRow1 = model.AllTypes{
SmallintPtr: nil, SmallintPtr: nil,
Smallint: 1, Smallint: 1,
IntegerPtr: nil, IntegerPtr: nil,