jet/internal/jet/literal_expression.go

488 lines
13 KiB
Go
Raw Normal View History

2019-06-21 13:56:57 +02:00
package jet
import (
"fmt"
"time"
)
2019-05-29 14:03:38 +02:00
2019-08-13 10:16:26 +02:00
// LiteralExpression is representation of an escaped literal
type LiteralExpression interface {
Expression
Value() interface{}
SetConstant(constant bool)
}
type literalExpressionImpl struct {
ExpressionInterfaceImpl
2019-06-03 14:41:39 +02:00
value interface{}
constant bool
}
func literal(value interface{}, optionalConstant ...bool) *literalExpressionImpl {
exp := literalExpressionImpl{value: value}
2019-08-01 11:33:38 +02:00
if len(optionalConstant) > 0 {
exp.constant = optionalConstant[0]
}
exp.ExpressionInterfaceImpl.Parent = &exp
return &exp
}
// Literal is injected directly to SQL query, and does not appear in parametrized argument list.
func Literal(value interface{}) *literalExpressionImpl {
exp := literal(value)
return exp
}
// FixedLiteral is injected directly to SQL query, and does not appear in parametrized argument list.
func FixedLiteral(value interface{}) *literalExpressionImpl {
exp := literal(value)
2019-06-03 14:41:39 +02:00
exp.constant = true
return exp
}
2019-08-17 18:32:01 +02:00
func (l *literalExpressionImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
2019-06-03 14:41:39 +02:00
if l.constant {
out.insertConstantArgument(l.value)
} else {
2019-07-18 17:43:11 +02:00
out.insertParametrizedArgument(l.value)
2019-06-03 14:41:39 +02:00
}
}
2019-05-06 12:42:15 +02:00
func (l *literalExpressionImpl) Value() interface{} {
return l.value
}
func (l *literalExpressionImpl) SetConstant(constant bool) {
l.constant = constant
}
type integerLiteralExpression struct {
literalExpressionImpl
integerInterfaceImpl
}
2021-02-22 13:58:28 -05:00
func intLiteral(value interface{}) IntegerExpression {
numLiteral := &integerLiteralExpression{}
numLiteral.literalExpressionImpl = *literal(value)
2019-08-11 09:52:02 +02:00
numLiteral.literalExpressionImpl.Parent = numLiteral
numLiteral.integerInterfaceImpl.parent = numLiteral
return numLiteral
}
2021-02-22 13:58:28 -05:00
// Int creates a new 64 bit signed integer literal
func Int(value int64) IntegerExpression {
return intLiteral(value)
}
// Int8 creates a new 8 bit signed integer literal
func Int8(value int8) IntegerExpression {
return intLiteral(value)
}
// Int16 creates a new 16 bit signed integer literal
func Int16(value int16) IntegerExpression {
return intLiteral(value)
}
// Int32 creates a new 32 bit signed integer literal
func Int32(value int32) IntegerExpression {
return intLiteral(value)
}
// Uint8 creates a new 8 bit unsigned integer literal
func Uint8(value uint8) IntegerExpression {
return intLiteral(value)
}
// Uint16 creates a new 16 bit unsigned integer literal
func Uint16(value uint16) IntegerExpression {
return intLiteral(value)
}
// Uint32 creates a new 32 bit unsigned integer literal
func Uint32(value uint32) IntegerExpression {
return intLiteral(value)
}
// Uint64 creates a new 64 bit unsigned integer literal
func Uint64(value uint64) IntegerExpression {
return intLiteral(value)
}
//---------------------------------------------------//
type boolLiteralExpression struct {
boolInterfaceImpl
literalExpressionImpl
2019-05-29 14:03:38 +02:00
}
2019-07-18 17:43:11 +02:00
// Bool creates new bool literal expression
func Bool(value bool) BoolExpression {
boolLiteralExpression := boolLiteralExpression{}
boolLiteralExpression.literalExpressionImpl = *literal(value)
boolLiteralExpression.boolInterfaceImpl.parent = &boolLiteralExpression
return &boolLiteralExpression
}
//---------------------------------------------------//
type floatLiteral struct {
floatInterfaceImpl
literalExpressionImpl
2019-05-29 14:03:38 +02:00
}
// Float creates new float literal from float64 value
func Float(value float64) FloatExpression {
floatLiteral := floatLiteral{}
floatLiteral.literalExpressionImpl = *literal(value)
floatLiteral.floatInterfaceImpl.parent = &floatLiteral
return &floatLiteral
}
// Decimal creates new float literal from string value
func Decimal(value string) FloatExpression {
floatLiteral := floatLiteral{}
floatLiteral.literalExpressionImpl = *literal(value)
floatLiteral.floatInterfaceImpl.parent = &floatLiteral
return &floatLiteral
}
//---------------------------------------------------//
type stringLiteral struct {
stringInterfaceImpl
literalExpressionImpl
2019-05-29 14:03:38 +02:00
}
2019-07-18 17:43:11 +02:00
// String creates new string literal expression
2019-08-16 11:19:06 +02:00
func String(value string) StringExpression {
stringLiteral := stringLiteral{}
stringLiteral.literalExpressionImpl = *literal(value)
stringLiteral.stringInterfaceImpl.parent = &stringLiteral
return &stringLiteral
}
2019-08-13 10:16:26 +02:00
//---------------------------------------------------//
2019-08-13 10:16:26 +02:00
type timeLiteral struct {
timeInterfaceImpl
literalExpressionImpl
2019-05-29 14:03:38 +02:00
}
2019-07-18 17:43:11 +02:00
// Time creates new time literal expression
2019-08-13 10:16:26 +02:00
func Time(hour, minute, second int, nanoseconds ...time.Duration) TimeExpression {
timeLiteral := &timeLiteral{}
timeStr := fmt.Sprintf("%02d:%02d:%02d", hour, minute, second)
2019-08-13 10:16:26 +02:00
timeStr += formatNanoseconds(nanoseconds...)
timeLiteral.literalExpressionImpl = *literal(timeStr)
2019-08-13 10:16:26 +02:00
timeLiteral.timeInterfaceImpl.parent = timeLiteral
2019-05-29 14:03:38 +02:00
2019-08-13 10:16:26 +02:00
return timeLiteral
}
2019-08-17 14:49:35 +02:00
// TimeT creates new time literal expression from time.Time object
func TimeT(t time.Time) TimeExpression {
2019-08-13 10:16:26 +02:00
timeLiteral := &timeLiteral{}
timeLiteral.literalExpressionImpl = *literal(t)
timeLiteral.timeInterfaceImpl.parent = timeLiteral
return timeLiteral
}
//---------------------------------------------------//
type timezLiteral struct {
timezInterfaceImpl
literalExpressionImpl
}
2019-07-18 17:43:11 +02:00
// Timez creates new time with time zone literal expression
2019-08-13 10:16:26 +02:00
func Timez(hour, minute, second int, nanoseconds time.Duration, timezone string) TimezExpression {
timezLiteral := timezLiteral{}
timeStr := fmt.Sprintf("%02d:%02d:%02d", hour, minute, second)
timeStr += formatNanoseconds(nanoseconds)
timeStr += " " + timezone
timezLiteral.literalExpressionImpl = *literal(timeStr)
2019-08-01 11:33:38 +02:00
return TimezExp(literal(timeStr))
}
2019-08-17 14:49:35 +02:00
// TimezT creates new time with time zone literal expression from time.Time object
func TimezT(t time.Time) TimezExpression {
2019-08-13 10:16:26 +02:00
timeLiteral := &timezLiteral{}
timeLiteral.literalExpressionImpl = *literal(t)
timeLiteral.timezInterfaceImpl.parent = timeLiteral
return timeLiteral
}
2019-08-13 10:16:26 +02:00
//---------------------------------------------------//
2019-08-13 10:16:26 +02:00
type timestampLiteral struct {
timestampInterfaceImpl
literalExpressionImpl
}
2019-08-13 10:16:26 +02:00
// Timestamp creates new timestamp literal expression
func Timestamp(year int, month time.Month, day, hour, minute, second int, nanoseconds ...time.Duration) TimestampExpression {
timestamp := &timestampLiteral{}
timeStr := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
timeStr += formatNanoseconds(nanoseconds...)
timestamp.literalExpressionImpl = *literal(timeStr)
timestamp.timestampInterfaceImpl.parent = timestamp
return timestamp
}
2019-08-17 14:49:35 +02:00
// TimestampT creates new timestamp literal expression from time.Time object
func TimestampT(t time.Time) TimestampExpression {
2019-08-13 10:16:26 +02:00
timestamp := &timestampLiteral{}
timestamp.literalExpressionImpl = *literal(t)
timestamp.timestampInterfaceImpl.parent = timestamp
return timestamp
}
2019-08-13 10:16:26 +02:00
//---------------------------------------------------//
2019-08-13 10:16:26 +02:00
type timestampzLiteral struct {
timestampzInterfaceImpl
literalExpressionImpl
}
2019-08-17 14:49:35 +02:00
// Timestampz creates new timestamp with time zone literal expression
2019-08-13 10:16:26 +02:00
func Timestampz(year int, month time.Month, day, hour, minute, second int, nanoseconds time.Duration, timezone string) TimestampzExpression {
timestamp := &timestampzLiteral{}
timeStr := fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", year, month, day, hour, minute, second)
timeStr += formatNanoseconds(nanoseconds)
timeStr += " " + timezone
timestamp.literalExpressionImpl = *literal(timeStr)
timestamp.timestampzInterfaceImpl.parent = timestamp
return timestamp
}
2019-08-17 14:49:35 +02:00
// TimestampzT creates new timestamp literal expression from time.Time object
func TimestampzT(t time.Time) TimestampzExpression {
2019-08-13 10:16:26 +02:00
timestamp := &timestampzLiteral{}
timestamp.literalExpressionImpl = *literal(t)
timestamp.timestampzInterfaceImpl.parent = timestamp
return timestamp
}
//---------------------------------------------------//
type dateLiteral struct {
dateInterfaceImpl
literalExpressionImpl
}
2019-08-17 14:49:35 +02:00
// Date creates new date literal expression
func Date(year int, month time.Month, day int) DateExpression {
2019-08-13 10:16:26 +02:00
dateLiteral := &dateLiteral{}
timeStr := fmt.Sprintf("%04d-%02d-%02d", year, month, day)
2019-08-13 10:16:26 +02:00
dateLiteral.literalExpressionImpl = *literal(timeStr)
dateLiteral.dateInterfaceImpl.parent = dateLiteral
2019-08-13 10:16:26 +02:00
return dateLiteral
}
2019-06-03 17:38:47 +02:00
2019-08-17 14:49:35 +02:00
// DateT creates new date literal expression from time.Time object
func DateT(t time.Time) DateExpression {
2019-08-13 10:16:26 +02:00
dateLiteral := &dateLiteral{}
dateLiteral.literalExpressionImpl = *literal(t)
dateLiteral.dateInterfaceImpl.parent = dateLiteral
return dateLiteral
}
func formatNanoseconds(nanoseconds ...time.Duration) string {
if len(nanoseconds) > 0 && nanoseconds[0] != 0 {
duration := fmt.Sprintf("%09d", nanoseconds[0])
i := len(duration) - 1
for ; i >= 3; i-- {
if duration[i] != '0' {
break
}
}
return "." + duration[0:i+1]
}
return ""
}
2019-06-03 17:38:47 +02:00
//--------------------------------------------------//
var (
// NULL is jet equivalent of SQL NULL
NULL = newNullLiteral()
// STAR is jet equivalent of SQL *
STAR = newStarLiteral()
)
2019-06-03 18:28:16 +02:00
type nullLiteral struct {
ExpressionInterfaceImpl
2019-06-03 17:38:47 +02:00
}
2019-06-04 12:10:23 +02:00
func newNullLiteral() Expression {
2019-06-03 18:28:16 +02:00
nullExpression := &nullLiteral{}
2019-06-03 17:38:47 +02:00
nullExpression.ExpressionInterfaceImpl.Parent = nullExpression
2019-06-03 17:38:47 +02:00
return nullExpression
}
2019-08-17 18:32:01 +02:00
func (n *nullLiteral) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
2019-08-03 14:10:47 +02:00
out.WriteString("NULL")
2019-06-03 17:38:47 +02:00
}
2019-06-03 18:28:16 +02:00
//--------------------------------------------------//
type starLiteral struct {
ExpressionInterfaceImpl
2019-06-03 18:28:16 +02:00
}
2019-06-04 12:10:23 +02:00
func newStarLiteral() Expression {
2019-06-03 18:28:16 +02:00
starExpression := &starLiteral{}
starExpression.ExpressionInterfaceImpl.Parent = starExpression
2019-06-03 18:28:16 +02:00
return starExpression
}
2019-08-17 18:32:01 +02:00
func (n *starLiteral) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
2019-08-03 14:10:47 +02:00
out.WriteString("*")
2019-06-03 18:28:16 +02:00
}
//---------------------------------------------------//
type wrap struct {
ExpressionInterfaceImpl
2019-06-04 12:10:23 +02:00
expressions []Expression
}
2019-08-17 18:32:01 +02:00
func (n *wrap) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
2019-08-03 14:10:47 +02:00
out.WriteString("(")
serializeExpressionList(statement, n.expressions, ", ", out)
2019-08-03 14:10:47 +02:00
out.WriteString(")")
}
2019-07-18 17:43:11 +02:00
// WRAP wraps list of expressions with brackets '(' and ')'
2019-06-04 12:10:23 +02:00
func WRAP(expression ...Expression) Expression {
wrap := &wrap{expressions: expression}
wrap.ExpressionInterfaceImpl.Parent = wrap
return wrap
}
2019-06-04 12:10:23 +02:00
//---------------------------------------------------//
2019-12-08 11:07:49 +01:00
type rawExpression struct {
ExpressionInterfaceImpl
Raw string
NamedArgument map[string]interface{}
noWrap bool
2019-06-04 12:10:23 +02:00
}
2019-12-08 11:07:49 +01:00
func (n *rawExpression) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
if !n.noWrap && !contains(options, NoWrap) {
out.WriteByte('(')
}
out.insertRawQuery(n.Raw, n.NamedArgument)
if !n.noWrap && !contains(options, NoWrap) {
out.WriteByte(')')
}
2019-06-04 12:10:23 +02:00
}
2019-08-06 13:29:26 +02:00
// Raw can be used for any unsupported functions, operators or expressions.
// For example: Raw("current_database()")
func Raw(raw string, namedArgs ...map[string]interface{}) Expression {
var namedArguments map[string]interface{}
if len(namedArgs) > 0 {
namedArguments = namedArgs[0]
}
rawExp := &rawExpression{
Raw: raw,
NamedArgument: namedArguments,
}
rawExp.ExpressionInterfaceImpl.Parent = rawExp
return rawExp
}
// RawWithParent is a Raw constructor used for construction dialect specific expression
func RawWithParent(raw string, parent ...Expression) Expression {
rawExp := &rawExpression{
Raw: raw,
noWrap: true,
}
rawExp.ExpressionInterfaceImpl.Parent = OptionalOrDefaultExpression(rawExp, parent...)
2019-06-04 12:10:23 +02:00
return rawExp
}
2021-05-16 19:10:43 +02:00
// RawInt helper that for integer expressions
func RawInt(raw string, namedArgs ...map[string]interface{}) IntegerExpression {
return IntExp(Raw(raw, namedArgs...))
}
2021-05-16 19:10:43 +02:00
// RawFloat helper that for float expressions
func RawFloat(raw string, namedArgs ...map[string]interface{}) FloatExpression {
return FloatExp(Raw(raw, namedArgs...))
}
2021-05-16 19:10:43 +02:00
// RawString helper that for string expressions
func RawString(raw string, namedArgs ...map[string]interface{}) StringExpression {
return StringExp(Raw(raw, namedArgs...))
}
2021-05-16 19:10:43 +02:00
// RawTime helper that for time expressions
func RawTime(raw string, namedArgs ...map[string]interface{}) TimeExpression {
return TimeExp(Raw(raw, namedArgs...))
}
2021-05-16 19:10:43 +02:00
// RawTimez helper that for time with time zone expressions
func RawTimez(raw string, namedArgs ...map[string]interface{}) TimezExpression {
return TimezExp(Raw(raw, namedArgs...))
}
2021-05-16 19:10:43 +02:00
// RawTimestamp helper that for timestamp expressions
func RawTimestamp(raw string, namedArgs ...map[string]interface{}) TimestampExpression {
return TimestampExp(Raw(raw, namedArgs...))
}
2021-05-16 19:10:43 +02:00
// RawTimestampz helper that for timestamp with time zone expressions
func RawTimestampz(raw string, namedArgs ...map[string]interface{}) TimestampzExpression {
return TimestampzExp(Raw(raw, namedArgs...))
}
2021-05-16 19:10:43 +02:00
// RawDate helper that for date expressions
func RawDate(raw string, namedArgs ...map[string]interface{}) DateExpression {
return DateExp(Raw(raw, namedArgs...))
}
// UUID is a helper function to create string literal expression from uuid object
// value can be any uuid type with a String method
func UUID(value fmt.Stringer) StringExpression {
return String(value.String())
}