Add support for INTERVAL operator.
This commit is contained in:
parent
4f9323ddca
commit
dd9b815dbb
4 changed files with 57 additions and 27 deletions
|
|
@ -10,20 +10,25 @@ import (
|
||||||
type intervalExpression struct {
|
type intervalExpression struct {
|
||||||
expressionInterfaceImpl
|
expressionInterfaceImpl
|
||||||
duration time.Duration
|
duration time.Duration
|
||||||
negative bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var intervalSep = ":"
|
const intervalSep = ":"
|
||||||
|
|
||||||
func (c *intervalExpression) Serialize(out *queryData, options ...serializeOption) error {
|
func (c *intervalExpression) Serialize(out *queryData, options ...serializeOption) error {
|
||||||
hours := c.duration / time.Hour
|
|
||||||
minutes := (c.duration % time.Hour) / time.Minute
|
|
||||||
sec := (c.duration % time.Minute) / time.Second
|
|
||||||
msec := (c.duration % time.Second) / time.Microsecond
|
|
||||||
out.WriteString("INTERVAL '")
|
out.WriteString("INTERVAL '")
|
||||||
if c.negative {
|
|
||||||
|
duration := c.duration
|
||||||
|
|
||||||
|
if duration < 0 {
|
||||||
|
duration = -duration
|
||||||
out.WriteString("-")
|
out.WriteString("-")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hours := duration / time.Hour
|
||||||
|
minutes := (duration % time.Hour) / time.Minute
|
||||||
|
sec := (duration % time.Minute) / time.Second
|
||||||
|
msec := (duration % time.Second) / time.Microsecond
|
||||||
|
|
||||||
out.WriteString(strconv.FormatInt(int64(hours), 10))
|
out.WriteString(strconv.FormatInt(int64(hours), 10))
|
||||||
out.WriteString(intervalSep)
|
out.WriteString(intervalSep)
|
||||||
out.WriteString(strconv.FormatInt(int64(minutes), 10))
|
out.WriteString(strconv.FormatInt(int64(minutes), 10))
|
||||||
|
|
@ -36,19 +41,16 @@ func (c *intervalExpression) Serialize(out *queryData, options ...serializeOptio
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interval returns a representation of duration
|
//// Interval returns a representation of duration
|
||||||
// in a form "INTERVAL `hour:min:sec:microsec` HOUR_MICROSECOND"
|
//func Interval(duration time.Duration) Expression {
|
||||||
func Interval(duration time.Duration) Expression {
|
// intervalExp := &intervalExpression{
|
||||||
negative := false
|
// duration: duration,
|
||||||
if duration < 0 {
|
// }
|
||||||
negative = true
|
//
|
||||||
duration = -duration
|
// intervalExp.expressionInterfaceImpl.parent = intervalExp
|
||||||
}
|
//
|
||||||
return &intervalExpression{
|
// return intervalExp
|
||||||
duration: duration,
|
//}
|
||||||
negative: negative,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var likeEscaper = strings.NewReplacer("_", "\\_", "%", "\\%")
|
var likeEscaper = strings.NewReplacer("_", "\\_", "%", "\\%")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,3 +31,14 @@ func TestCase2(t *testing.T) {
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
assert.Equal(t, queryData.buff.String(), `(CASE table3.col1 WHEN $1 THEN table3.col1 + $2 WHEN $3 THEN table3.col1 + $4 ELSE $5 END)`)
|
assert.Equal(t, queryData.buff.String(), `(CASE table3.col1 WHEN $1 THEN table3.col1 + $2 WHEN $3 THEN table3.col1 + $4 ELSE $5 END)`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInterval(t *testing.T) {
|
||||||
|
query := INTERVAL(`6 years 5 months 4 days 3 hours 2 minutes 1 second`)
|
||||||
|
|
||||||
|
queryData := &queryData{}
|
||||||
|
|
||||||
|
err := query.Serialize(queryData)
|
||||||
|
|
||||||
|
assert.NilError(t, err)
|
||||||
|
assert.Equal(t, queryData.buff.String(), `INTERVAL $1`)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,3 +48,25 @@ func (t *timeInterfaceImpl) LtEq(expression TimeExpression) BoolExpression {
|
||||||
func (t *timeInterfaceImpl) LtEqL(literal string) BoolExpression {
|
func (t *timeInterfaceImpl) LtEqL(literal string) BoolExpression {
|
||||||
return LtEq(t.parent, Literal(literal))
|
return LtEq(t.parent, Literal(literal))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------//
|
||||||
|
type prefixTimeExpression struct {
|
||||||
|
expressionInterfaceImpl
|
||||||
|
timeInterfaceImpl
|
||||||
|
|
||||||
|
prefixExpression
|
||||||
|
}
|
||||||
|
|
||||||
|
func newPrefixTimeExpression(expression Expression, operator string) TimeExpression {
|
||||||
|
timeExpr := prefixTimeExpression{}
|
||||||
|
timeExpr.prefixExpression = newPrefixExpression(expression, operator)
|
||||||
|
|
||||||
|
timeExpr.expressionInterfaceImpl.parent = &timeExpr
|
||||||
|
timeExpr.timeInterfaceImpl.parent = &timeExpr
|
||||||
|
|
||||||
|
return &timeExpr
|
||||||
|
}
|
||||||
|
|
||||||
|
func INTERVAL(interval string) Expression {
|
||||||
|
return newPrefixTimeExpression(Literal(interval), "INTERVAL")
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package tests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
"github.com/sub0zero/go-sqlbuilder/sqlbuilder"
|
"github.com/sub0zero/go-sqlbuilder/sqlbuilder"
|
||||||
"github.com/sub0zero/go-sqlbuilder/tests/.test_files/dvd_rental/dvds/model"
|
"github.com/sub0zero/go-sqlbuilder/tests/.test_files/dvd_rental/dvds/model"
|
||||||
. "github.com/sub0zero/go-sqlbuilder/tests/.test_files/dvd_rental/dvds/table"
|
. "github.com/sub0zero/go-sqlbuilder/tests/.test_files/dvd_rental/dvds/table"
|
||||||
|
|
@ -678,11 +677,10 @@ func TestSelectWithCase(t *testing.T) {
|
||||||
ORDER_BY(Payment.PaymentID.ASC()).
|
ORDER_BY(Payment.PaymentID.ASC()).
|
||||||
LIMIT(20)
|
LIMIT(20)
|
||||||
|
|
||||||
queryStr, args, err := query.Sql()
|
queryStr, _, err := query.Sql()
|
||||||
|
|
||||||
assert.NilError(t, err)
|
assert.NilError(t, err)
|
||||||
fmt.Println(queryStr)
|
assert.Equal(t, queryStr, `SELECT (CASE payment.staff_id WHEN $1 THEN $2 WHEN $3 THEN $4 WHEN $5 THEN $6 ELSE $7 END) AS "staff_id_num" FROM dvds.payment ORDER BY payment.payment_id ASC LIMIT $8`)
|
||||||
fmt.Println(args)
|
|
||||||
|
|
||||||
dest := []struct {
|
dest := []struct {
|
||||||
StaffIdNum string
|
StaffIdNum string
|
||||||
|
|
@ -694,9 +692,6 @@ func TestSelectWithCase(t *testing.T) {
|
||||||
assert.Equal(t, len(dest), 20)
|
assert.Equal(t, len(dest), 20)
|
||||||
assert.Equal(t, dest[0].StaffIdNum, "TWO")
|
assert.Equal(t, dest[0].StaffIdNum, "TWO")
|
||||||
assert.Equal(t, dest[1].StaffIdNum, "ONE")
|
assert.Equal(t, dest[1].StaffIdNum, "ONE")
|
||||||
|
|
||||||
spew.Dump(dest)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func int16Ptr(i int16) *int16 {
|
func int16Ptr(i int16) *int16 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue