Literal expressions clean up.
This commit is contained in:
parent
bcdab0f111
commit
ba5ee27990
14 changed files with 78 additions and 36 deletions
|
|
@ -349,7 +349,7 @@ func TO_HEX(number IntegerExpression) StringExpression {
|
||||||
// REGEXP_LIKE Returns 1 if the string expr matches the regular expression specified by the pattern pat, 0 otherwise.
|
// REGEXP_LIKE Returns 1 if the string expr matches the regular expression specified by the pattern pat, 0 otherwise.
|
||||||
func REGEXP_LIKE(stringExp StringExpression, pattern StringExpression, matchType ...string) BoolExpression {
|
func REGEXP_LIKE(stringExp StringExpression, pattern StringExpression, matchType ...string) BoolExpression {
|
||||||
if len(matchType) > 0 {
|
if len(matchType) > 0 {
|
||||||
return newBoolFunc("REGEXP_LIKE", stringExp, pattern, String(matchType[0], true))
|
return newBoolFunc("REGEXP_LIKE", stringExp, pattern, ConstLiteral(matchType[0]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return newBoolFunc("REGEXP_LIKE", stringExp, pattern)
|
return newBoolFunc("REGEXP_LIKE", stringExp, pattern)
|
||||||
|
|
@ -391,7 +391,7 @@ func CURRENT_TIME(precision ...int) TimezExpression {
|
||||||
var timezFunc *timezFunc
|
var timezFunc *timezFunc
|
||||||
|
|
||||||
if len(precision) > 0 {
|
if len(precision) > 0 {
|
||||||
timezFunc = newTimezFunc("CURRENT_TIME", constLiteral(precision[0]))
|
timezFunc = newTimezFunc("CURRENT_TIME", ConstLiteral(precision[0]))
|
||||||
} else {
|
} else {
|
||||||
timezFunc = newTimezFunc("CURRENT_TIME")
|
timezFunc = newTimezFunc("CURRENT_TIME")
|
||||||
}
|
}
|
||||||
|
|
@ -406,7 +406,7 @@ func CURRENT_TIMESTAMP(precision ...int) TimestampzExpression {
|
||||||
var timestampzFunc *timestampzFunc
|
var timestampzFunc *timestampzFunc
|
||||||
|
|
||||||
if len(precision) > 0 {
|
if len(precision) > 0 {
|
||||||
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP", constLiteral(precision[0]))
|
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP", ConstLiteral(precision[0]))
|
||||||
} else {
|
} else {
|
||||||
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP")
|
timestampzFunc = newTimestampzFunc("CURRENT_TIMESTAMP")
|
||||||
}
|
}
|
||||||
|
|
@ -421,7 +421,7 @@ func LOCALTIME(precision ...int) TimeExpression {
|
||||||
var timeFunc *timeFunc
|
var timeFunc *timeFunc
|
||||||
|
|
||||||
if len(precision) > 0 {
|
if len(precision) > 0 {
|
||||||
timeFunc = newTimeFunc("LOCALTIME", constLiteral(precision[0]))
|
timeFunc = newTimeFunc("LOCALTIME", ConstLiteral(precision[0]))
|
||||||
} else {
|
} else {
|
||||||
timeFunc = newTimeFunc("LOCALTIME")
|
timeFunc = newTimeFunc("LOCALTIME")
|
||||||
}
|
}
|
||||||
|
|
@ -436,7 +436,7 @@ func LOCALTIMESTAMP(precision ...int) TimestampExpression {
|
||||||
var timestampFunc *timestampFunc
|
var timestampFunc *timestampFunc
|
||||||
|
|
||||||
if len(precision) > 0 {
|
if len(precision) > 0 {
|
||||||
timestampFunc = NewTimestampFunc("LOCALTIMESTAMP", constLiteral(precision[0]))
|
timestampFunc = NewTimestampFunc("LOCALTIMESTAMP", ConstLiteral(precision[0]))
|
||||||
} else {
|
} else {
|
||||||
timestampFunc = NewTimestampFunc("LOCALTIMESTAMP")
|
timestampFunc = NewTimestampFunc("LOCALTIMESTAMP")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ func TestIntExpressionPOW(t *testing.T) {
|
||||||
|
|
||||||
func TestIntExpressionBIT_NOT(t *testing.T) {
|
func TestIntExpressionBIT_NOT(t *testing.T) {
|
||||||
assertClauseSerialize(t, BIT_NOT(table2ColInt), "(~ table2.col_int)")
|
assertClauseSerialize(t, BIT_NOT(table2ColInt), "(~ table2.col_int)")
|
||||||
assertClauseSerialize(t, BIT_NOT(Int(11)), "(~ $1)", int64(11))
|
assertClauseSerialize(t, BIT_NOT(Int(11)), "(~ 11)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIntExpressionBIT_AND(t *testing.T) {
|
func TestIntExpressionBIT_AND(t *testing.T) {
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ func literal(value interface{}, optionalConstant ...bool) *literalExpressionImpl
|
||||||
return &exp
|
return &exp
|
||||||
}
|
}
|
||||||
|
|
||||||
func constLiteral(value interface{}) *literalExpressionImpl {
|
func ConstLiteral(value interface{}) *literalExpressionImpl {
|
||||||
exp := literal(value)
|
exp := literal(value)
|
||||||
exp.constant = true
|
exp.constant = true
|
||||||
|
|
||||||
|
|
@ -61,13 +61,10 @@ type integerLiteralExpression struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Int is constructor for integer expressions literals.
|
// Int is constructor for integer expressions literals.
|
||||||
func Int(value int64, constant ...bool) IntegerExpression {
|
func Int(value int64) IntegerExpression {
|
||||||
numLiteral := &integerLiteralExpression{}
|
numLiteral := &integerLiteralExpression{}
|
||||||
|
|
||||||
numLiteral.literalExpressionImpl = *literal(value)
|
numLiteral.literalExpressionImpl = *literal(value)
|
||||||
if len(constant) > 0 && constant[0] == true {
|
|
||||||
numLiteral.constant = true
|
|
||||||
}
|
|
||||||
|
|
||||||
numLiteral.literalExpressionImpl.Parent = numLiteral
|
numLiteral.literalExpressionImpl.Parent = numLiteral
|
||||||
numLiteral.integerInterfaceImpl.parent = numLiteral
|
numLiteral.integerInterfaceImpl.parent = numLiteral
|
||||||
|
|
@ -114,12 +111,9 @@ type stringLiteral struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// String creates new string literal expression
|
// String creates new string literal expression
|
||||||
func String(value string, constant ...bool) StringExpression {
|
func String(value string) StringExpression {
|
||||||
stringLiteral := stringLiteral{}
|
stringLiteral := stringLiteral{}
|
||||||
stringLiteral.literalExpressionImpl = *literal(value)
|
stringLiteral.literalExpressionImpl = *literal(value)
|
||||||
if len(constant) > 0 && constant[0] == true {
|
|
||||||
stringLiteral.constant = true
|
|
||||||
}
|
|
||||||
|
|
||||||
stringLiteral.stringInterfaceImpl.parent = &stringLiteral
|
stringLiteral.stringInterfaceImpl.parent = &stringLiteral
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ func NOT(exp BoolExpression) BoolExpression {
|
||||||
|
|
||||||
// BIT_NOT inverts every bit in integer expression result
|
// BIT_NOT inverts every bit in integer expression result
|
||||||
func BIT_NOT(expr IntegerExpression) IntegerExpression {
|
func BIT_NOT(expr IntegerExpression) IntegerExpression {
|
||||||
|
if literalExp, ok := expr.(LiteralExpression); ok {
|
||||||
|
literalExp.SetConstant(true)
|
||||||
|
}
|
||||||
return newPrefixIntegerOperator(expr, "~")
|
return newPrefixIntegerOperator(expr, "~")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ type castImpl struct {
|
||||||
jet.Cast
|
jet.Cast
|
||||||
}
|
}
|
||||||
|
|
||||||
func CAST(expr jet.Expression) cast {
|
func CAST(expr Expression) cast {
|
||||||
castImpl := &castImpl{}
|
castImpl := &castImpl{}
|
||||||
|
|
||||||
castImpl.Cast = jet.NewCastImpl(expr)
|
castImpl.Cast = jet.NewCastImpl(expr)
|
||||||
|
|
|
||||||
|
|
@ -30,3 +30,5 @@ var DateTimeExp = jet.TimestampExp
|
||||||
var TimestampExp = jet.TimestampExp
|
var TimestampExp = jet.TimestampExp
|
||||||
|
|
||||||
var Raw = jet.Raw
|
var Raw = jet.Raw
|
||||||
|
|
||||||
|
var NewEnumValue = jet.NewEnumValue
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ func CURRENT_TIMESTAMP(precision ...int) TimestampExpression {
|
||||||
// NOW returns current datetime
|
// NOW returns current datetime
|
||||||
func NOW(fsp ...int) DateTimeExpression {
|
func NOW(fsp ...int) DateTimeExpression {
|
||||||
if len(fsp) > 0 {
|
if len(fsp) > 0 {
|
||||||
return jet.NewTimestampFunc("NOW", Int(int64(fsp[0]), true))
|
return jet.NewTimestampFunc("NOW", jet.ConstLiteral(int64(fsp[0])))
|
||||||
}
|
}
|
||||||
return jet.NewTimestampFunc("NOW")
|
return jet.NewTimestampFunc("NOW")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,16 +36,6 @@ func SELECT(projection Projection, projections ...Projection) SelectStatement {
|
||||||
return newSelectStatement(nil, append([]Projection{projection}, projections...))
|
return newSelectStatement(nil, append([]Projection{projection}, projections...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func toJetProjectionList(projections []Projection) []jet.Projection {
|
|
||||||
ret := []jet.Projection{}
|
|
||||||
|
|
||||||
for _, projection := range projections {
|
|
||||||
ret = append(ret, projection)
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement {
|
func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement {
|
||||||
newSelect := &selectStatementImpl{}
|
newSelect := &selectStatementImpl{}
|
||||||
newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,12 @@ import "github.com/go-jet/jet/internal/jet"
|
||||||
type Statement jet.Statement
|
type Statement jet.Statement
|
||||||
type Projection jet.Projection
|
type Projection jet.Projection
|
||||||
|
|
||||||
var NewEnumValue = jet.NewEnumValue
|
func toJetProjectionList(projections []Projection) []jet.Projection {
|
||||||
|
ret := []jet.Projection{}
|
||||||
|
|
||||||
|
for _, projection := range projections {
|
||||||
|
ret = append(ret, projection)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,11 +37,11 @@ type SelectStatement interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
//SELECT creates new SelectStatement with list of projections
|
//SELECT creates new SelectStatement with list of projections
|
||||||
func SELECT(projection jet.Projection, projections ...jet.Projection) SelectStatement {
|
func SELECT(projection Projection, projections ...Projection) SelectStatement {
|
||||||
return newSelectStatement(nil, append([]jet.Projection{projection}, projections...))
|
return newSelectStatement(nil, append([]Projection{projection}, projections...))
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSelectStatement(table ReadableTable, projections []jet.Projection) SelectStatement {
|
func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement {
|
||||||
newSelect := &selectStatementImpl{}
|
newSelect := &selectStatementImpl{}
|
||||||
newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
newSelect.ExpressionStatementImpl.StatementImpl = jet.NewStatementImpl(Dialect, jet.SelectStatementType, newSelect, &newSelect.Select,
|
||||||
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy,
|
&newSelect.From, &newSelect.Where, &newSelect.GroupBy, &newSelect.Having, &newSelect.OrderBy,
|
||||||
|
|
@ -49,7 +49,7 @@ func newSelectStatement(table ReadableTable, projections []jet.Projection) Selec
|
||||||
|
|
||||||
newSelect.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSelect
|
newSelect.ExpressionStatementImpl.ExpressionInterfaceImpl.Parent = newSelect
|
||||||
|
|
||||||
newSelect.Select.Projections = projections
|
newSelect.Select.Projections = toJetProjectionList(projections)
|
||||||
newSelect.From.Table = table
|
newSelect.From.Table = table
|
||||||
newSelect.Limit.Count = -1
|
newSelect.Limit.Count = -1
|
||||||
newSelect.Offset.Count = -1
|
newSelect.Offset.Count = -1
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
type readableTable interface {
|
type readableTable interface {
|
||||||
// Generates a select query on the current tableName.
|
// Generates a select query on the current tableName.
|
||||||
SELECT(projection jet.Projection, projections ...jet.Projection) SelectStatement
|
SELECT(projection Projection, projections ...Projection) SelectStatement
|
||||||
|
|
||||||
// Creates a inner join tableName Expression using onCondition.
|
// Creates a inner join tableName Expression using onCondition.
|
||||||
INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
|
INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
|
||||||
|
|
@ -52,8 +52,8 @@ type readableTableInterfaceImpl struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generates a select query on the current tableName.
|
// Generates a select query on the current tableName.
|
||||||
func (r *readableTableInterfaceImpl) SELECT(projection1 jet.Projection, projections ...jet.Projection) SelectStatement {
|
func (r *readableTableInterfaceImpl) SELECT(projection1 Projection, projections ...Projection) SelectStatement {
|
||||||
return newSelectStatement(r.parent, append([]jet.Projection{projection1}, projections...))
|
return newSelectStatement(r.parent, append([]Projection{projection1}, projections...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates a inner join tableName Expression using onCondition.
|
// Creates a inner join tableName Expression using onCondition.
|
||||||
|
|
|
||||||
16
postgres/types.go
Normal file
16
postgres/types.go
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
package postgres
|
||||||
|
|
||||||
|
import "github.com/go-jet/jet/internal/jet"
|
||||||
|
|
||||||
|
type Statement jet.Statement
|
||||||
|
type Projection jet.Projection
|
||||||
|
|
||||||
|
func toJetProjectionList(projections []Projection) []jet.Projection {
|
||||||
|
ret := []jet.Projection{}
|
||||||
|
|
||||||
|
for _, projection := range projections {
|
||||||
|
ret = append(ret, projection)
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
@ -139,6 +139,35 @@ WHERE link.id = 201;
|
||||||
testutils.AssertExec(t, stmt, db)
|
testutils.AssertExec(t, stmt, db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUpdateWithModelDataAndMutableColumns(t *testing.T) {
|
||||||
|
|
||||||
|
setupLinkTableForUpdateTest(t)
|
||||||
|
|
||||||
|
link := model.Link{
|
||||||
|
ID: 201,
|
||||||
|
URL: "http://www.duckduckgo.com",
|
||||||
|
Name: "DuckDuckGo",
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt := Link.
|
||||||
|
UPDATE(Link.MutableColumns).
|
||||||
|
MODEL(link).
|
||||||
|
WHERE(Link.ID.EQ(Int(int64(link.ID))))
|
||||||
|
|
||||||
|
var expectedSQL = `
|
||||||
|
UPDATE test_sample.link
|
||||||
|
SET url = 'http://www.duckduckgo.com',
|
||||||
|
name = 'DuckDuckGo',
|
||||||
|
description = NULL
|
||||||
|
WHERE link.id = 201;
|
||||||
|
`
|
||||||
|
fmt.Println(stmt.DebugSql())
|
||||||
|
|
||||||
|
testutils.AssertDebugStatementSql(t, stmt, expectedSQL, "http://www.duckduckgo.com", "DuckDuckGo", nil, int64(201))
|
||||||
|
|
||||||
|
testutils.AssertExec(t, stmt, db)
|
||||||
|
}
|
||||||
|
|
||||||
func TestUpdateWithInvalidModelData(t *testing.T) {
|
func TestUpdateWithInvalidModelData(t *testing.T) {
|
||||||
defer func() {
|
defer func() {
|
||||||
r := recover()
|
r := recover()
|
||||||
|
|
|
||||||
|
|
@ -468,7 +468,7 @@ func TestIntegerOperators(t *testing.T) {
|
||||||
AllTypes.SmallInt.BIT_XOR(Int(11)).AS("bit xor 2"),
|
AllTypes.SmallInt.BIT_XOR(Int(11)).AS("bit xor 2"),
|
||||||
|
|
||||||
BIT_NOT(Int(-1).MUL(AllTypes.SmallInt)).AS("bit_not_1"),
|
BIT_NOT(Int(-1).MUL(AllTypes.SmallInt)).AS("bit_not_1"),
|
||||||
BIT_NOT(Int(-11, true)).AS("bit_not_2"),
|
BIT_NOT(Int(-11)).AS("bit_not_2"),
|
||||||
|
|
||||||
AllTypes.SmallInt.BIT_SHIFT_LEFT(AllTypes.SmallInt.DIV(Int(2))).AS("bit shift left 1"),
|
AllTypes.SmallInt.BIT_SHIFT_LEFT(AllTypes.SmallInt.DIV(Int(2))).AS("bit shift left 1"),
|
||||||
AllTypes.SmallInt.BIT_SHIFT_LEFT(Int(4)).AS("bit shift left 2"),
|
AllTypes.SmallInt.BIT_SHIFT_LEFT(Int(4)).AS("bit shift left 2"),
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue