Current date/time functions.
This commit is contained in:
parent
37a55e6ee3
commit
7c98fb508c
8 changed files with 177 additions and 26 deletions
|
|
@ -158,7 +158,11 @@ func (q *queryData) finalize() (string, []interface{}) {
|
||||||
return q.buff.String() + ";\n", q.args
|
return q.buff.String() + ";\n", q.args
|
||||||
}
|
}
|
||||||
|
|
||||||
func (q *queryData) insertArgument(arg interface{}) {
|
func (q *queryData) insertConstantArgument(arg interface{}) {
|
||||||
|
q.writeString(ArgToString(arg))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *queryData) insertPreparedArgument(arg interface{}) {
|
||||||
q.args = append(q.args, arg)
|
q.args = append(q.args, arg)
|
||||||
argPlaceholder := "$" + strconv.Itoa(len(q.args))
|
argPlaceholder := "$" + strconv.Itoa(len(q.args))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ type funcExpressionImpl struct {
|
||||||
|
|
||||||
name string
|
name string
|
||||||
expressions []expression
|
expressions []expression
|
||||||
|
noBrackets bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func ROW(expressions ...expression) expression {
|
func ROW(expressions ...expression) expression {
|
||||||
|
|
@ -33,17 +34,40 @@ func (f *funcExpressionImpl) serialize(statement statementType, out *queryData,
|
||||||
return errors.New("Function expressions is nil. ")
|
return errors.New("Function expressions is nil. ")
|
||||||
}
|
}
|
||||||
|
|
||||||
out.writeString(f.name + "(")
|
addBrackets := !f.noBrackets || len(f.expressions) > 0
|
||||||
|
|
||||||
|
if addBrackets {
|
||||||
|
out.writeString(f.name + "(")
|
||||||
|
} else {
|
||||||
|
out.writeString(f.name)
|
||||||
|
}
|
||||||
|
|
||||||
err := serializeExpressionList(statement, f.expressions, ", ", out)
|
err := serializeExpressionList(statement, f.expressions, ", ", out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
out.writeString(")")
|
|
||||||
|
if addBrackets {
|
||||||
|
out.writeString(")")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type boolFunc struct {
|
||||||
|
funcExpressionImpl
|
||||||
|
boolInterfaceImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func newBoolFunc(name string, expressions ...expression) BoolExpression {
|
||||||
|
boolFunc := &boolFunc{}
|
||||||
|
|
||||||
|
boolFunc.funcExpressionImpl = *newFunc(name, expressions, boolFunc)
|
||||||
|
boolFunc.boolInterfaceImpl.parent = boolFunc
|
||||||
|
|
||||||
|
return boolFunc
|
||||||
|
}
|
||||||
|
|
||||||
type floatFunc struct {
|
type floatFunc struct {
|
||||||
funcExpressionImpl
|
funcExpressionImpl
|
||||||
floatInterfaceImpl
|
floatInterfaceImpl
|
||||||
|
|
@ -91,7 +115,7 @@ type dateFunc struct {
|
||||||
dateInterfaceImpl
|
dateInterfaceImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDateFunc(name string, expressions ...expression) DateExpression {
|
func newDateFunc(name string, expressions ...expression) *dateFunc {
|
||||||
dateFunc := &dateFunc{}
|
dateFunc := &dateFunc{}
|
||||||
|
|
||||||
dateFunc.funcExpressionImpl = *newFunc(name, expressions, dateFunc)
|
dateFunc.funcExpressionImpl = *newFunc(name, expressions, dateFunc)
|
||||||
|
|
@ -100,18 +124,46 @@ func newDateFunc(name string, expressions ...expression) DateExpression {
|
||||||
return dateFunc
|
return dateFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
type boolFunc struct {
|
type timeFunc struct {
|
||||||
funcExpressionImpl
|
funcExpressionImpl
|
||||||
boolInterfaceImpl
|
timeInterfaceImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
func newBoolFunc(name string, expressions ...expression) BoolExpression {
|
func newTimeFunc(name string, expressions ...expression) *timeFunc {
|
||||||
boolFunc := &boolFunc{}
|
timeFun := &timeFunc{}
|
||||||
|
|
||||||
boolFunc.funcExpressionImpl = *newFunc(name, expressions, boolFunc)
|
timeFun.funcExpressionImpl = *newFunc(name, expressions, timeFun)
|
||||||
boolFunc.boolInterfaceImpl.parent = boolFunc
|
timeFun.timeInterfaceImpl.parent = timeFun
|
||||||
|
|
||||||
return boolFunc
|
return timeFun
|
||||||
|
}
|
||||||
|
|
||||||
|
type timezFunc struct {
|
||||||
|
funcExpressionImpl
|
||||||
|
timezInterfaceImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTimezFunc(name string, expressions ...expression) *timezFunc {
|
||||||
|
timezFun := &timezFunc{}
|
||||||
|
|
||||||
|
timezFun.funcExpressionImpl = *newFunc(name, expressions, timezFun)
|
||||||
|
timezFun.timezInterfaceImpl.parent = timezFun
|
||||||
|
|
||||||
|
return timezFun
|
||||||
|
}
|
||||||
|
|
||||||
|
type timestampFunc struct {
|
||||||
|
funcExpressionImpl
|
||||||
|
timestampInterfaceImpl
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTimestampFunc(name string, expressions ...expression) *timestampFunc {
|
||||||
|
timestampFunc := ×tampFunc{}
|
||||||
|
|
||||||
|
timestampFunc.funcExpressionImpl = *newFunc(name, expressions, timestampFunc)
|
||||||
|
timestampFunc.timestampInterfaceImpl.parent = timestampFunc
|
||||||
|
|
||||||
|
return timestampFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
type timestampzFunc struct {
|
type timestampzFunc struct {
|
||||||
|
|
@ -119,7 +171,7 @@ type timestampzFunc struct {
|
||||||
timestampzInterfaceImpl
|
timestampzInterfaceImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTimestampzFunc(name string, expressions ...expression) TimestampzExpression {
|
func newTimestampzFunc(name string, expressions ...expression) *timestampzFunc {
|
||||||
timestampzFunc := ×tampzFunc{}
|
timestampzFunc := ×tampzFunc{}
|
||||||
|
|
||||||
timestampzFunc.funcExpressionImpl = *newFunc(name, expressions, timestampzFunc)
|
timestampzFunc.funcExpressionImpl = *newFunc(name, expressions, timestampzFunc)
|
||||||
|
|
@ -258,6 +310,7 @@ func CHR(integerExpression IntegerExpression) StringExpression {
|
||||||
return newStringFunc("CHR", integerExpression)
|
return newStringFunc("CHR", integerExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
//func CONCAT(expressions ...expression) StringExpression {
|
//func CONCAT(expressions ...expression) StringExpression {
|
||||||
// return newStringFunc("CONCAT", expressions...)
|
// return newStringFunc("CONCAT", expressions...)
|
||||||
//}
|
//}
|
||||||
|
|
@ -382,3 +435,71 @@ func TO_NUMBER(floatStr, format StringExpression) FloatExpression {
|
||||||
func TO_TIMESTAMP(timestampzStr, format StringExpression) TimestampzExpression {
|
func TO_TIMESTAMP(timestampzStr, format StringExpression) TimestampzExpression {
|
||||||
return newTimestampzFunc("TO_TIMESTAMP", timestampzStr, format)
|
return newTimestampzFunc("TO_TIMESTAMP", timestampzStr, format)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------- Date/Time Functions and Operators ---------------//
|
||||||
|
|
||||||
|
func CURRENT_DATE() DateExpression {
|
||||||
|
dateFunc := newDateFunc("CURRENT_DATE")
|
||||||
|
dateFunc.noBrackets = true
|
||||||
|
return dateFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func CURRENT_TIME(precision ...int) TimezExpression {
|
||||||
|
var timezFunc *timezFunc
|
||||||
|
|
||||||
|
if len(precision) > 0 {
|
||||||
|
timezFunc = newTimezFunc("CURRENT_TIME", ConstantLiteral(precision[0]))
|
||||||
|
} else {
|
||||||
|
timezFunc = newTimezFunc("CURRENT_TIME")
|
||||||
|
}
|
||||||
|
|
||||||
|
timezFunc.noBrackets = true
|
||||||
|
|
||||||
|
return timezFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func CURRENT_TIMESTAMP(precision ...int) TimestampzExpression {
|
||||||
|
var timestampzFunc *timestampzFunc
|
||||||
|
|
||||||
|
if len(precision) > 0 {
|
||||||
|
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP", ConstantLiteral(precision[0]))
|
||||||
|
} else {
|
||||||
|
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP")
|
||||||
|
}
|
||||||
|
|
||||||
|
timestampzFunc.noBrackets = true
|
||||||
|
|
||||||
|
return timestampzFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func LOCALTIME(precision ...int) TimeExpression {
|
||||||
|
var timeFunc *timeFunc
|
||||||
|
|
||||||
|
if len(precision) > 0 {
|
||||||
|
timeFunc = newTimeFunc("LOCALTIME", ConstantLiteral(precision[0]))
|
||||||
|
} else {
|
||||||
|
timeFunc = newTimeFunc("LOCALTIME")
|
||||||
|
}
|
||||||
|
|
||||||
|
timeFunc.noBrackets = true
|
||||||
|
|
||||||
|
return timeFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func LOCALTIMESTAMP(precision ...int) TimestampExpression {
|
||||||
|
var timestampFunc *timestampFunc
|
||||||
|
|
||||||
|
if len(precision) > 0 {
|
||||||
|
timestampFunc = newTimestampFunc("LOCALTIMESTAMP", ConstantLiteral(precision[0]))
|
||||||
|
} else {
|
||||||
|
timestampFunc = newTimestampFunc("LOCALTIMESTAMP")
|
||||||
|
}
|
||||||
|
|
||||||
|
timestampFunc.noBrackets = true
|
||||||
|
|
||||||
|
return timestampFunc
|
||||||
|
}
|
||||||
|
|
||||||
|
func NOW() TimestampzExpression {
|
||||||
|
return newTimestampzFunc("NOW")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ import "fmt"
|
||||||
// Representation of an escaped literal
|
// Representation of an escaped literal
|
||||||
type literalExpression struct {
|
type literalExpression struct {
|
||||||
expressionInterfaceImpl
|
expressionInterfaceImpl
|
||||||
value interface{}
|
value interface{}
|
||||||
|
constant bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func Literal(value interface{}) *literalExpression {
|
func Literal(value interface{}) *literalExpression {
|
||||||
|
|
@ -15,8 +16,19 @@ func Literal(value interface{}) *literalExpression {
|
||||||
return &exp
|
return &exp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ConstantLiteral(value interface{}) *literalExpression {
|
||||||
|
exp := Literal(value)
|
||||||
|
exp.constant = true
|
||||||
|
|
||||||
|
return exp
|
||||||
|
}
|
||||||
|
|
||||||
func (l literalExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
func (l literalExpression) serialize(statement statementType, out *queryData, options ...serializeOption) error {
|
||||||
out.insertArgument(l.value)
|
if l.constant {
|
||||||
|
out.insertConstantArgument(l.value)
|
||||||
|
} else {
|
||||||
|
out.insertPreparedArgument(l.value)
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -174,13 +174,13 @@ func (s *selectStatementImpl) serializeImpl(out *queryData) error {
|
||||||
if s.limit >= 0 {
|
if s.limit >= 0 {
|
||||||
out.nextLine()
|
out.nextLine()
|
||||||
out.writeString("LIMIT")
|
out.writeString("LIMIT")
|
||||||
out.insertArgument(s.limit)
|
out.insertPreparedArgument(s.limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.offset >= 0 {
|
if s.offset >= 0 {
|
||||||
out.nextLine()
|
out.nextLine()
|
||||||
out.writeString("OFFSET")
|
out.writeString("OFFSET")
|
||||||
out.insertArgument(s.offset)
|
out.insertPreparedArgument(s.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.forUpdate {
|
if s.forUpdate {
|
||||||
|
|
|
||||||
|
|
@ -168,13 +168,13 @@ func (s *setStatementImpl) serializeImpl(out *queryData) error {
|
||||||
if s.limit >= 0 {
|
if s.limit >= 0 {
|
||||||
out.nextLine()
|
out.nextLine()
|
||||||
out.writeString("LIMIT")
|
out.writeString("LIMIT")
|
||||||
out.insertArgument(s.limit)
|
out.insertPreparedArgument(s.limit)
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.offset >= 0 {
|
if s.offset >= 0 {
|
||||||
out.nextLine()
|
out.nextLine()
|
||||||
out.writeString("OFFSET")
|
out.writeString("OFFSET")
|
||||||
out.insertArgument(s.offset)
|
out.insertPreparedArgument(s.offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -6,30 +6,30 @@ import (
|
||||||
|
|
||||||
func TestTimeExpressionEQ(t *testing.T) {
|
func TestTimeExpressionEQ(t *testing.T) {
|
||||||
assertExpressionSerialize(t, table1ColTime.EQ(table2ColTime), "(table1.colTime = table2.colTime)")
|
assertExpressionSerialize(t, table1ColTime.EQ(table2ColTime), "(table1.colTime = table2.colTime)")
|
||||||
assertExpressionSerialize(t, table1ColTime.EQ(Time(10, 20, 0, 0)), "(table1.colTime = $1)", "10:20:00.000")
|
assertExpressionSerialize(t, table1ColTime.EQ(Time(10, 20, 0, 0)), "(table1.colTime = $1::time without time zone)", "10:20:00.000")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionNOT_EQ(t *testing.T) {
|
func TestTimeExpressionNOT_EQ(t *testing.T) {
|
||||||
assertExpressionSerialize(t, table1ColTime.NOT_EQ(table2ColTime), "(table1.colTime != table2.colTime)")
|
assertExpressionSerialize(t, table1ColTime.NOT_EQ(table2ColTime), "(table1.colTime != table2.colTime)")
|
||||||
assertExpressionSerialize(t, table1ColTime.NOT_EQ(Time(10, 20, 0, 0)), "(table1.colTime != $1)", "10:20:00.000")
|
assertExpressionSerialize(t, table1ColTime.NOT_EQ(Time(10, 20, 0, 0)), "(table1.colTime != $1::time without time zone)", "10:20:00.000")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionLT(t *testing.T) {
|
func TestTimeExpressionLT(t *testing.T) {
|
||||||
assertExpressionSerialize(t, table1ColTime.LT(table2ColTime), "(table1.colTime < table2.colTime)")
|
assertExpressionSerialize(t, table1ColTime.LT(table2ColTime), "(table1.colTime < table2.colTime)")
|
||||||
assertExpressionSerialize(t, table1ColTime.LT(Time(10, 20, 0, 0)), "(table1.colTime < $1)", "10:20:00.000")
|
assertExpressionSerialize(t, table1ColTime.LT(Time(10, 20, 0, 0)), "(table1.colTime < $1::time without time zone)", "10:20:00.000")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionLT_EQ(t *testing.T) {
|
func TestTimeExpressionLT_EQ(t *testing.T) {
|
||||||
assertExpressionSerialize(t, table1ColTime.LT_EQ(table2ColTime), "(table1.colTime <= table2.colTime)")
|
assertExpressionSerialize(t, table1ColTime.LT_EQ(table2ColTime), "(table1.colTime <= table2.colTime)")
|
||||||
assertExpressionSerialize(t, table1ColTime.LT_EQ(Time(10, 20, 0, 0)), "(table1.colTime <= $1)", "10:20:00.000")
|
assertExpressionSerialize(t, table1ColTime.LT_EQ(Time(10, 20, 0, 0)), "(table1.colTime <= $1::time without time zone)", "10:20:00.000")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionGT(t *testing.T) {
|
func TestTimeExpressionGT(t *testing.T) {
|
||||||
assertExpressionSerialize(t, table1ColTime.GT(table2ColTime), "(table1.colTime > table2.colTime)")
|
assertExpressionSerialize(t, table1ColTime.GT(table2ColTime), "(table1.colTime > table2.colTime)")
|
||||||
assertExpressionSerialize(t, table1ColTime.GT(Time(10, 20, 0, 0)), "(table1.colTime > $1)", "10:20:00.000")
|
assertExpressionSerialize(t, table1ColTime.GT(Time(10, 20, 0, 0)), "(table1.colTime > $1::time without time zone)", "10:20:00.000")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTimeExpressionGT_EQ(t *testing.T) {
|
func TestTimeExpressionGT_EQ(t *testing.T) {
|
||||||
assertExpressionSerialize(t, table1ColTime.GT_EQ(table2ColTime), "(table1.colTime >= table2.colTime)")
|
assertExpressionSerialize(t, table1ColTime.GT_EQ(table2ColTime), "(table1.colTime >= table2.colTime)")
|
||||||
assertExpressionSerialize(t, table1ColTime.GT_EQ(Time(10, 20, 0, 0)), "(table1.colTime >= $1)", "10:20:00.000")
|
assertExpressionSerialize(t, table1ColTime.GT_EQ(Time(10, 20, 0, 0)), "(table1.colTime >= $1::time without time zone)", "10:20:00.000")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -973,7 +973,7 @@ 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.000'
|
WHERE payment.payment_date < '2007-02-14 22:16:01.000'::timestamp without time zone
|
||||||
ORDER BY payment.payment_date ASC;
|
ORDER BY payment.payment_date ASC;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -111,7 +111,10 @@ func TestStringOperators(t *testing.T) {
|
||||||
TO_HEX(AllTypes.IntegerPtr),
|
TO_HEX(AllTypes.IntegerPtr),
|
||||||
)
|
)
|
||||||
|
|
||||||
//fmt.Println(query.Sql())
|
_, args, _ := query.Sql()
|
||||||
|
|
||||||
|
fmt.Println(query.Sql())
|
||||||
|
fmt.Println(args[15])
|
||||||
fmt.Println(query.DebugSql())
|
fmt.Println(query.DebugSql())
|
||||||
|
|
||||||
err := query.Query(db, &struct{}{})
|
err := query.Query(db, &struct{}{})
|
||||||
|
|
@ -284,6 +287,17 @@ func TestTimeOperators(t *testing.T) {
|
||||||
|
|
||||||
AllTypes.Time.GT_EQ(AllTypes.Time),
|
AllTypes.Time.GT_EQ(AllTypes.Time),
|
||||||
AllTypes.Time.GT_EQ(Time(23, 6, 6, 1)),
|
AllTypes.Time.GT_EQ(Time(23, 6, 6, 1)),
|
||||||
|
|
||||||
|
CURRENT_DATE(),
|
||||||
|
CURRENT_TIME(),
|
||||||
|
CURRENT_TIME(2),
|
||||||
|
CURRENT_TIMESTAMP(),
|
||||||
|
CURRENT_TIMESTAMP(1),
|
||||||
|
LOCALTIME(),
|
||||||
|
LOCALTIME(11),
|
||||||
|
LOCALTIMESTAMP(),
|
||||||
|
LOCALTIMESTAMP(4),
|
||||||
|
NOW(),
|
||||||
)
|
)
|
||||||
|
|
||||||
fmt.Println(query.DebugSql())
|
fmt.Println(query.DebugSql())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue