Add support for PostgreSQL interval column

This commit is contained in:
go-jet 2020-02-09 18:37:48 +01:00
parent 641c62098c
commit 3013dc3647
30 changed files with 1038 additions and 255 deletions

View file

@ -57,8 +57,10 @@ func (c ColumnMetaData) getSqlBuilderColumnType() string {
return "Time" return "Time"
case "time with time zone": case "time with time zone":
return "Timez" return "Timez"
case "interval":
return "Interval"
case "USER-DEFINED", "enum", "text", "character", "character varying", "bytea", "uuid", case "USER-DEFINED", "enum", "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", "line", "ARRAY",
"char", "varchar", "binary", "varbinary", "char", "varchar", "binary", "varbinary",
"tinyblob", "blob", "mediumblob", "longblob", "tinytext", "mediumtext", "longtext": // MySQL "tinyblob", "blob", "mediumblob", "longblob", "tinytext", "mediumtext", "longtext": // MySQL
return "String" return "String"

View file

@ -13,8 +13,7 @@ func newAlias(expression Expression, aliasName string) Projection {
} }
func (a *alias) fromImpl(subQuery SelectTable) Projection { func (a *alias) fromImpl(subQuery SelectTable) Projection {
column := newColumn(a.alias, "", nil) column := NewColumnImpl(a.alias, "", nil)
column.Parent = &column
column.subQuery = subQuery column.subQuery = subQuery
return &column return &column

View file

@ -37,19 +37,19 @@ type boolInterfaceImpl struct {
} }
func (b *boolInterfaceImpl) EQ(expression BoolExpression) BoolExpression { func (b *boolInterfaceImpl) EQ(expression BoolExpression) BoolExpression {
return eq(b.parent, expression) return Eq(b.parent, expression)
} }
func (b *boolInterfaceImpl) NOT_EQ(expression BoolExpression) BoolExpression { func (b *boolInterfaceImpl) NOT_EQ(expression BoolExpression) BoolExpression {
return notEq(b.parent, expression) return NotEq(b.parent, expression)
} }
func (b *boolInterfaceImpl) IS_DISTINCT_FROM(rhs BoolExpression) BoolExpression { func (b *boolInterfaceImpl) IS_DISTINCT_FROM(rhs BoolExpression) BoolExpression {
return isDistinctFrom(b.parent, rhs) return IsDistinctFrom(b.parent, rhs)
} }
func (b *boolInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs BoolExpression) BoolExpression { func (b *boolInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs BoolExpression) BoolExpression {
return isNotDistinctFrom(b.parent, rhs) return IsNotDistinctFrom(b.parent, rhs)
} }
func (b *boolInterfaceImpl) AND(expression BoolExpression) BoolExpression { func (b *boolInterfaceImpl) AND(expression BoolExpression) BoolExpression {
@ -86,7 +86,7 @@ func (b *boolInterfaceImpl) IS_NOT_UNKNOWN() BoolExpression {
//---------------------------------------------------// //---------------------------------------------------//
func newBinaryBoolOperatorExpression(lhs, rhs Expression, operator string, additionalParams ...Expression) BoolExpression { func newBinaryBoolOperatorExpression(lhs, rhs Expression, operator string, additionalParams ...Expression) BoolExpression {
return BoolExp(newBinaryOperatorExpression(lhs, rhs, operator, additionalParams...)) return BoolExp(NewBinaryOperatorExpression(lhs, rhs, operator, additionalParams...))
} }
//---------------------------------------------------// //---------------------------------------------------//

View file

@ -18,8 +18,8 @@ type ColumnExpression interface {
Expression Expression
} }
// The base type for real materialized columns. // ColumnExpressionImpl is base type for sql columns.
type columnImpl struct { type ColumnExpressionImpl struct {
ExpressionInterfaceImpl ExpressionInterfaceImpl
name string name string
@ -28,34 +28,41 @@ type columnImpl struct {
subQuery SelectTable subQuery SelectTable
} }
func newColumn(name string, tableName string, parent ColumnExpression) columnImpl { // NewColumnImpl creates new ColumnExpressionImpl
bc := columnImpl{ func NewColumnImpl(name string, tableName string, parent ColumnExpression) ColumnExpressionImpl {
bc := ColumnExpressionImpl{
name: name, name: name,
tableName: tableName, tableName: tableName,
} }
bc.ExpressionInterfaceImpl.Parent = parent if parent != nil {
bc.ExpressionInterfaceImpl.Parent = parent
} else {
bc.ExpressionInterfaceImpl.Parent = &bc
}
return bc return bc
} }
func (c *columnImpl) Name() string { // Name returns name of the column
func (c *ColumnExpressionImpl) Name() string {
return c.name return c.name
} }
func (c *columnImpl) TableName() string { // TableName returns column table name
func (c *ColumnExpressionImpl) TableName() string {
return c.tableName return c.tableName
} }
func (c *columnImpl) setTableName(table string) { func (c *ColumnExpressionImpl) setTableName(table string) {
c.tableName = table c.tableName = table
} }
func (c *columnImpl) setSubQuery(subQuery SelectTable) { func (c *ColumnExpressionImpl) setSubQuery(subQuery SelectTable) {
c.subQuery = subQuery c.subQuery = subQuery
} }
func (c *columnImpl) defaultAlias() string { func (c *ColumnExpressionImpl) defaultAlias() string {
if c.tableName != "" { if c.tableName != "" {
return c.tableName + "." + c.name return c.tableName + "." + c.name
} }
@ -63,25 +70,31 @@ func (c *columnImpl) defaultAlias() string {
return c.name return c.name
} }
func (c *columnImpl) serializeForOrderBy(statement StatementType, out *SQLBuilder) { func (c *ColumnExpressionImpl) fromImpl(subQuery SelectTable) Projection {
newColumn := NewColumnImpl(c.name, c.tableName, nil)
newColumn.setSubQuery(subQuery)
return &newColumn
}
func (c *ColumnExpressionImpl) serializeForOrderBy(statement StatementType, out *SQLBuilder) {
if statement == SetStatementType { if statement == SetStatementType {
// set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause // set Statement (UNION, EXCEPT ...) can reference only select projections in order by clause
out.WriteAlias(c.defaultAlias()) //always quote out.WriteAlias(c.defaultAlias()) //always quote
return return
} }
c.serialize(statement, out) c.serialize(statement, out)
} }
func (c columnImpl) serializeForProjection(statement StatementType, out *SQLBuilder) { func (c ColumnExpressionImpl) serializeForProjection(statement StatementType, out *SQLBuilder) {
c.serialize(statement, out) c.serialize(statement, out)
out.WriteString("AS") out.WriteString("AS")
out.WriteAlias(c.defaultAlias()) out.WriteAlias(c.defaultAlias())
} }
func (c columnImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) { func (c ColumnExpressionImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
if c.subQuery != nil { if c.subQuery != nil {
out.WriteIdentifier(c.subQuery.Alias()) out.WriteIdentifier(c.subQuery.Alias())
@ -128,3 +141,13 @@ func (cl ColumnList) TableName() string { return "" }
func (cl ColumnList) setTableName(name string) {} func (cl ColumnList) setTableName(name string) {}
func (cl ColumnList) setSubQuery(subQuery SelectTable) {} func (cl ColumnList) setSubQuery(subQuery SelectTable) {}
func (cl ColumnList) defaultAlias() string { return "" } func (cl ColumnList) defaultAlias() string { return "" }
// SetTableName is utility function to set table name from outside of jet package to avoid making public setTableName
func SetTableName(columnExpression ColumnExpression, tableName string) {
columnExpression.setTableName(tableName)
}
// SetSubQuery is utility function to set table name from outside of jet package to avoid making public setSubQuery
func SetSubQuery(columnExpression ColumnExpression, subQuery SelectTable) {
columnExpression.setSubQuery(subQuery)
}

View file

@ -3,7 +3,7 @@ package jet
import "testing" import "testing"
func TestColumn(t *testing.T) { func TestColumn(t *testing.T) {
column := newColumn("col", "", nil) column := NewColumnImpl("col", "", nil)
column.ExpressionInterfaceImpl.Parent = &column column.ExpressionInterfaceImpl.Parent = &column
assertClauseSerialize(t, column, "col") assertClauseSerialize(t, column, "col")

View file

@ -10,11 +10,10 @@ type ColumnBool interface {
type boolColumnImpl struct { type boolColumnImpl struct {
boolInterfaceImpl boolInterfaceImpl
ColumnExpressionImpl
columnImpl
} }
func (i *boolColumnImpl) fromImpl(subQuery SelectTable) Projection { func (i *boolColumnImpl) From(subQuery SelectTable) ColumnBool {
newBoolColumn := BoolColumn(i.name) newBoolColumn := BoolColumn(i.name)
newBoolColumn.setTableName(i.tableName) newBoolColumn.setTableName(i.tableName)
newBoolColumn.setSubQuery(subQuery) newBoolColumn.setSubQuery(subQuery)
@ -22,16 +21,10 @@ func (i *boolColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newBoolColumn return newBoolColumn
} }
func (i *boolColumnImpl) From(subQuery SelectTable) ColumnBool {
newBoolColumn := i.fromImpl(subQuery).(ColumnBool)
return newBoolColumn
}
// BoolColumn creates named bool column. // BoolColumn creates named bool column.
func BoolColumn(name string) ColumnBool { func BoolColumn(name string) ColumnBool {
boolColumn := &boolColumnImpl{} boolColumn := &boolColumnImpl{}
boolColumn.columnImpl = newColumn(name, "", boolColumn) boolColumn.ColumnExpressionImpl = NewColumnImpl(name, "", boolColumn)
boolColumn.boolInterfaceImpl.parent = boolColumn boolColumn.boolInterfaceImpl.parent = boolColumn
return boolColumn return boolColumn
@ -49,19 +42,13 @@ type ColumnFloat interface {
type floatColumnImpl struct { type floatColumnImpl struct {
floatInterfaceImpl floatInterfaceImpl
columnImpl ColumnExpressionImpl
}
func (i *floatColumnImpl) fromImpl(subQuery SelectTable) Projection {
newFloatColumn := FloatColumn(i.name)
newFloatColumn.setTableName(i.tableName)
newFloatColumn.setSubQuery(subQuery)
return newFloatColumn
} }
func (i *floatColumnImpl) From(subQuery SelectTable) ColumnFloat { func (i *floatColumnImpl) From(subQuery SelectTable) ColumnFloat {
newFloatColumn := i.fromImpl(subQuery).(ColumnFloat) newFloatColumn := FloatColumn(i.name)
newFloatColumn.setTableName(i.tableName)
newFloatColumn.setSubQuery(subQuery)
return newFloatColumn return newFloatColumn
} }
@ -70,7 +57,7 @@ func (i *floatColumnImpl) From(subQuery SelectTable) ColumnFloat {
func FloatColumn(name string) ColumnFloat { func FloatColumn(name string) ColumnFloat {
floatColumn := &floatColumnImpl{} floatColumn := &floatColumnImpl{}
floatColumn.floatInterfaceImpl.parent = floatColumn floatColumn.floatInterfaceImpl.parent = floatColumn
floatColumn.columnImpl = newColumn(name, "", floatColumn) floatColumn.ColumnExpressionImpl = NewColumnImpl(name, "", floatColumn)
return floatColumn return floatColumn
} }
@ -88,10 +75,10 @@ type ColumnInteger interface {
type integerColumnImpl struct { type integerColumnImpl struct {
integerInterfaceImpl integerInterfaceImpl
columnImpl ColumnExpressionImpl
} }
func (i *integerColumnImpl) fromImpl(subQuery SelectTable) Projection { func (i *integerColumnImpl) From(subQuery SelectTable) ColumnInteger {
newIntColumn := IntegerColumn(i.name) newIntColumn := IntegerColumn(i.name)
newIntColumn.setTableName(i.tableName) newIntColumn.setTableName(i.tableName)
newIntColumn.setSubQuery(subQuery) newIntColumn.setSubQuery(subQuery)
@ -99,15 +86,11 @@ func (i *integerColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newIntColumn return newIntColumn
} }
func (i *integerColumnImpl) From(subQuery SelectTable) ColumnInteger {
return i.fromImpl(subQuery).(ColumnInteger)
}
// IntegerColumn creates named integer column. // IntegerColumn creates named integer column.
func IntegerColumn(name string) ColumnInteger { func IntegerColumn(name string) ColumnInteger {
integerColumn := &integerColumnImpl{} integerColumn := &integerColumnImpl{}
integerColumn.integerInterfaceImpl.parent = integerColumn integerColumn.integerInterfaceImpl.parent = integerColumn
integerColumn.columnImpl = newColumn(name, "", integerColumn) integerColumn.ColumnExpressionImpl = NewColumnImpl(name, "", integerColumn)
return integerColumn return integerColumn
} }
@ -126,10 +109,10 @@ type ColumnString interface {
type stringColumnImpl struct { type stringColumnImpl struct {
stringInterfaceImpl stringInterfaceImpl
columnImpl ColumnExpressionImpl
} }
func (i *stringColumnImpl) fromImpl(subQuery SelectTable) Projection { func (i *stringColumnImpl) From(subQuery SelectTable) ColumnString {
newStrColumn := StringColumn(i.name) newStrColumn := StringColumn(i.name)
newStrColumn.setTableName(i.tableName) newStrColumn.setTableName(i.tableName)
newStrColumn.setSubQuery(subQuery) newStrColumn.setSubQuery(subQuery)
@ -137,15 +120,11 @@ func (i *stringColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newStrColumn return newStrColumn
} }
func (i *stringColumnImpl) From(subQuery SelectTable) ColumnString {
return i.fromImpl(subQuery).(ColumnString)
}
// StringColumn creates named string column. // StringColumn creates named string column.
func StringColumn(name string) ColumnString { func StringColumn(name string) ColumnString {
stringColumn := &stringColumnImpl{} stringColumn := &stringColumnImpl{}
stringColumn.stringInterfaceImpl.parent = stringColumn stringColumn.stringInterfaceImpl.parent = stringColumn
stringColumn.columnImpl = newColumn(name, "", stringColumn) stringColumn.ColumnExpressionImpl = NewColumnImpl(name, "", stringColumn)
return stringColumn return stringColumn
} }
@ -162,10 +141,10 @@ type ColumnTime interface {
type timeColumnImpl struct { type timeColumnImpl struct {
timeInterfaceImpl timeInterfaceImpl
columnImpl ColumnExpressionImpl
} }
func (i *timeColumnImpl) fromImpl(subQuery SelectTable) Projection { func (i *timeColumnImpl) From(subQuery SelectTable) ColumnTime {
newTimeColumn := TimeColumn(i.name) newTimeColumn := TimeColumn(i.name)
newTimeColumn.setTableName(i.tableName) newTimeColumn.setTableName(i.tableName)
newTimeColumn.setSubQuery(subQuery) newTimeColumn.setSubQuery(subQuery)
@ -173,15 +152,11 @@ func (i *timeColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newTimeColumn return newTimeColumn
} }
func (i *timeColumnImpl) From(subQuery SelectTable) ColumnTime {
return i.fromImpl(subQuery).(ColumnTime)
}
// TimeColumn creates named time column // TimeColumn creates named time column
func TimeColumn(name string) ColumnTime { func TimeColumn(name string) ColumnTime {
timeColumn := &timeColumnImpl{} timeColumn := &timeColumnImpl{}
timeColumn.timeInterfaceImpl.parent = timeColumn timeColumn.timeInterfaceImpl.parent = timeColumn
timeColumn.columnImpl = newColumn(name, "", timeColumn) timeColumn.ColumnExpressionImpl = NewColumnImpl(name, "", timeColumn)
return timeColumn return timeColumn
} }
@ -197,11 +172,10 @@ type ColumnTimez interface {
type timezColumnImpl struct { type timezColumnImpl struct {
timezInterfaceImpl timezInterfaceImpl
ColumnExpressionImpl
columnImpl
} }
func (i *timezColumnImpl) fromImpl(subQuery SelectTable) Projection { func (i *timezColumnImpl) From(subQuery SelectTable) ColumnTimez {
newTimezColumn := TimezColumn(i.name) newTimezColumn := TimezColumn(i.name)
newTimezColumn.setTableName(i.tableName) newTimezColumn.setTableName(i.tableName)
newTimezColumn.setSubQuery(subQuery) newTimezColumn.setSubQuery(subQuery)
@ -209,15 +183,11 @@ func (i *timezColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newTimezColumn return newTimezColumn
} }
func (i *timezColumnImpl) From(subQuery SelectTable) ColumnTimez {
return i.fromImpl(subQuery).(ColumnTimez)
}
// TimezColumn creates named time with time zone column. // TimezColumn creates named time with time zone column.
func TimezColumn(name string) ColumnTimez { func TimezColumn(name string) ColumnTimez {
timezColumn := &timezColumnImpl{} timezColumn := &timezColumnImpl{}
timezColumn.timezInterfaceImpl.parent = timezColumn timezColumn.timezInterfaceImpl.parent = timezColumn
timezColumn.columnImpl = newColumn(name, "", timezColumn) timezColumn.ColumnExpressionImpl = NewColumnImpl(name, "", timezColumn)
return timezColumn return timezColumn
} }
@ -234,11 +204,10 @@ type ColumnTimestamp interface {
type timestampColumnImpl struct { type timestampColumnImpl struct {
timestampInterfaceImpl timestampInterfaceImpl
ColumnExpressionImpl
columnImpl
} }
func (i *timestampColumnImpl) fromImpl(subQuery SelectTable) Projection { func (i *timestampColumnImpl) From(subQuery SelectTable) ColumnTimestamp {
newTimestampColumn := TimestampColumn(i.name) newTimestampColumn := TimestampColumn(i.name)
newTimestampColumn.setTableName(i.tableName) newTimestampColumn.setTableName(i.tableName)
newTimestampColumn.setSubQuery(subQuery) newTimestampColumn.setSubQuery(subQuery)
@ -246,15 +215,11 @@ func (i *timestampColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newTimestampColumn return newTimestampColumn
} }
func (i *timestampColumnImpl) From(subQuery SelectTable) ColumnTimestamp {
return i.fromImpl(subQuery).(ColumnTimestamp)
}
// TimestampColumn creates named timestamp column // TimestampColumn creates named timestamp column
func TimestampColumn(name string) ColumnTimestamp { func TimestampColumn(name string) ColumnTimestamp {
timestampColumn := &timestampColumnImpl{} timestampColumn := &timestampColumnImpl{}
timestampColumn.timestampInterfaceImpl.parent = timestampColumn timestampColumn.timestampInterfaceImpl.parent = timestampColumn
timestampColumn.columnImpl = newColumn(name, "", timestampColumn) timestampColumn.ColumnExpressionImpl = NewColumnImpl(name, "", timestampColumn)
return timestampColumn return timestampColumn
} }
@ -271,11 +236,10 @@ type ColumnTimestampz interface {
type timestampzColumnImpl struct { type timestampzColumnImpl struct {
timestampzInterfaceImpl timestampzInterfaceImpl
ColumnExpressionImpl
columnImpl
} }
func (i *timestampzColumnImpl) fromImpl(subQuery SelectTable) Projection { func (i *timestampzColumnImpl) From(subQuery SelectTable) ColumnTimestampz {
newTimestampzColumn := TimestampzColumn(i.name) newTimestampzColumn := TimestampzColumn(i.name)
newTimestampzColumn.setTableName(i.tableName) newTimestampzColumn.setTableName(i.tableName)
newTimestampzColumn.setSubQuery(subQuery) newTimestampzColumn.setSubQuery(subQuery)
@ -283,15 +247,11 @@ func (i *timestampzColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newTimestampzColumn return newTimestampzColumn
} }
func (i *timestampzColumnImpl) From(subQuery SelectTable) ColumnTimestampz {
return i.fromImpl(subQuery).(ColumnTimestampz)
}
// TimestampzColumn creates named timestamp with time zone column. // TimestampzColumn creates named timestamp with time zone column.
func TimestampzColumn(name string) ColumnTimestampz { func TimestampzColumn(name string) ColumnTimestampz {
timestampzColumn := &timestampzColumnImpl{} timestampzColumn := &timestampzColumnImpl{}
timestampzColumn.timestampzInterfaceImpl.parent = timestampzColumn timestampzColumn.timestampzInterfaceImpl.parent = timestampzColumn
timestampzColumn.columnImpl = newColumn(name, "", timestampzColumn) timestampzColumn.ColumnExpressionImpl = NewColumnImpl(name, "", timestampzColumn)
return timestampzColumn return timestampzColumn
} }
@ -308,11 +268,10 @@ type ColumnDate interface {
type dateColumnImpl struct { type dateColumnImpl struct {
dateInterfaceImpl dateInterfaceImpl
ColumnExpressionImpl
columnImpl
} }
func (i *dateColumnImpl) fromImpl(subQuery SelectTable) Projection { func (i *dateColumnImpl) From(subQuery SelectTable) ColumnDate {
newDateColumn := DateColumn(i.name) newDateColumn := DateColumn(i.name)
newDateColumn.setTableName(i.tableName) newDateColumn.setTableName(i.tableName)
newDateColumn.setSubQuery(subQuery) newDateColumn.setSubQuery(subQuery)
@ -320,14 +279,10 @@ func (i *dateColumnImpl) fromImpl(subQuery SelectTable) Projection {
return newDateColumn return newDateColumn
} }
func (i *dateColumnImpl) From(subQuery SelectTable) ColumnDate {
return i.fromImpl(subQuery).(ColumnDate)
}
// DateColumn creates named date column. // DateColumn creates named date column.
func DateColumn(name string) ColumnDate { func DateColumn(name string) ColumnDate {
dateColumn := &dateColumnImpl{} dateColumn := &dateColumnImpl{}
dateColumn.dateInterfaceImpl.parent = dateColumn dateColumn.dateInterfaceImpl.parent = dateColumn
dateColumn.columnImpl = newColumn(name, "", dateColumn) dateColumn.ColumnExpressionImpl = NewColumnImpl(name, "", dateColumn)
return dateColumn return dateColumn
} }

View file

@ -43,5 +43,74 @@ func TestNewFloatColumnColumn(t *testing.T) {
assertClauseSerialize(t, floatColumn2, `sub_query."table1.col_float"`) assertClauseSerialize(t, floatColumn2, `sub_query."table1.col_float"`)
assertClauseSerialize(t, floatColumn2.EQ(Float(2.22)), `(sub_query."table1.col_float" = $1)`, float64(2.22)) assertClauseSerialize(t, floatColumn2.EQ(Float(2.22)), `(sub_query."table1.col_float" = $1)`, float64(2.22))
assertProjectionSerialize(t, floatColumn2, `sub_query."table1.col_float" AS "table1.col_float"`) assertProjectionSerialize(t, floatColumn2, `sub_query."table1.col_float" AS "table1.col_float"`)
}
func TestNewDateColumnColumn(t *testing.T) {
dateColumn := DateColumn("col_date").From(subQuery)
assertClauseSerialize(t, dateColumn, `sub_query."col_date"`)
assertClauseSerialize(t, dateColumn.EQ(Date(2002, 2, 3)),
`(sub_query."col_date" = $1)`, "2002-02-03")
assertProjectionSerialize(t, dateColumn, `sub_query."col_date" AS "col_date"`)
dateColumn2 := table1ColDate.From(subQuery)
assertClauseSerialize(t, dateColumn2, `sub_query."table1.col_date"`)
assertClauseSerialize(t, dateColumn2.EQ(Date(2002, 2, 3)),
`(sub_query."table1.col_date" = $1)`, "2002-02-03")
assertProjectionSerialize(t, dateColumn2, `sub_query."table1.col_date" AS "table1.col_date"`)
}
func TestNewTimeColumnColumn(t *testing.T) {
timeColumn := TimeColumn("col_time").From(subQuery)
assertClauseSerialize(t, timeColumn, `sub_query."col_time"`)
assertClauseSerialize(t, timeColumn.EQ(Time(1, 1, 1, 1)),
`(sub_query."col_time" = $1)`, "01:01:01.000000001")
assertProjectionSerialize(t, timeColumn, `sub_query."col_time" AS "col_time"`)
timeColumn2 := table1ColTime.From(subQuery)
assertClauseSerialize(t, timeColumn2, `sub_query."table1.col_time"`)
assertClauseSerialize(t, timeColumn2.EQ(Time(2, 2, 2)),
`(sub_query."table1.col_time" = $1)`, "02:02:02")
assertProjectionSerialize(t, timeColumn2, `sub_query."table1.col_time" AS "table1.col_time"`)
}
func TestNewTimezColumnColumn(t *testing.T) {
timezColumn := TimezColumn("col_timez").From(subQuery)
assertClauseSerialize(t, timezColumn, `sub_query."col_timez"`)
assertClauseSerialize(t, timezColumn.EQ(Timez(1, 1, 1, 1, "UTC")),
`(sub_query."col_timez" = $1)`, "01:01:01.000000001 UTC")
assertProjectionSerialize(t, timezColumn, `sub_query."col_timez" AS "col_timez"`)
timezColumn2 := table1ColTimez.From(subQuery)
assertClauseSerialize(t, timezColumn2, `sub_query."table1.col_timez"`)
assertClauseSerialize(t, timezColumn2.EQ(Timez(2, 2, 2, 0, "UTC")),
`(sub_query."table1.col_timez" = $1)`, "02:02:02 UTC")
assertProjectionSerialize(t, timezColumn2, `sub_query."table1.col_timez" AS "table1.col_timez"`)
}
func TestNewTimestampColumnColumn(t *testing.T) {
timestampColumn := TimestampColumn("col_timestamp").From(subQuery)
assertClauseSerialize(t, timestampColumn, `sub_query."col_timestamp"`)
assertClauseSerialize(t, timestampColumn.EQ(Timestamp(1, 1, 1, 1, 1, 1)),
`(sub_query."col_timestamp" = $1)`, "0001-01-01 01:01:01")
assertProjectionSerialize(t, timestampColumn, `sub_query."col_timestamp" AS "col_timestamp"`)
timestampColumn2 := table1ColTimestamp.From(subQuery)
assertClauseSerialize(t, timestampColumn2, `sub_query."table1.col_timestamp"`)
assertClauseSerialize(t, timestampColumn2.EQ(Timestamp(2, 2, 2, 2, 2, 2)),
`(sub_query."table1.col_timestamp" = $1)`, "0002-02-02 02:02:02")
assertProjectionSerialize(t, timestampColumn2, `sub_query."table1.col_timestamp" AS "table1.col_timestamp"`)
}
func TestNewTimestampzColumnColumn(t *testing.T) {
timestampzColumn := TimestampzColumn("col_timestampz").From(subQuery)
assertClauseSerialize(t, timestampzColumn, `sub_query."col_timestampz"`)
assertClauseSerialize(t, timestampzColumn.EQ(Timestampz(1, 1, 1, 1, 1, 1, 0, "UTC")),
`(sub_query."col_timestampz" = $1)`, "0001-01-01 01:01:01 UTC")
assertProjectionSerialize(t, timestampzColumn, `sub_query."col_timestampz" AS "col_timestampz"`)
timestampzColumn2 := table1ColTimestampz.From(subQuery)
assertClauseSerialize(t, timestampzColumn2, `sub_query."table1.col_timestampz"`)
assertClauseSerialize(t, timestampzColumn2.EQ(Timestampz(2, 2, 2, 2, 2, 2, 0, "UTC")),
`(sub_query."table1.col_timestampz" = $1)`, "0002-02-02 02:02:02 UTC")
assertProjectionSerialize(t, timestampzColumn2, `sub_query."table1.col_timestampz" AS "table1.col_timestampz"`)
} }

View file

@ -23,43 +23,43 @@ type dateInterfaceImpl struct {
} }
func (d *dateInterfaceImpl) EQ(rhs DateExpression) BoolExpression { func (d *dateInterfaceImpl) EQ(rhs DateExpression) BoolExpression {
return eq(d.parent, rhs) return Eq(d.parent, rhs)
} }
func (d *dateInterfaceImpl) NOT_EQ(rhs DateExpression) BoolExpression { func (d *dateInterfaceImpl) NOT_EQ(rhs DateExpression) BoolExpression {
return notEq(d.parent, rhs) return NotEq(d.parent, rhs)
} }
func (d *dateInterfaceImpl) IS_DISTINCT_FROM(rhs DateExpression) BoolExpression { func (d *dateInterfaceImpl) IS_DISTINCT_FROM(rhs DateExpression) BoolExpression {
return isDistinctFrom(d.parent, rhs) return IsDistinctFrom(d.parent, rhs)
} }
func (d *dateInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs DateExpression) BoolExpression { func (d *dateInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs DateExpression) BoolExpression {
return isNotDistinctFrom(d.parent, rhs) return IsNotDistinctFrom(d.parent, rhs)
} }
func (d *dateInterfaceImpl) LT(rhs DateExpression) BoolExpression { func (d *dateInterfaceImpl) LT(rhs DateExpression) BoolExpression {
return lt(d.parent, rhs) return Lt(d.parent, rhs)
} }
func (d *dateInterfaceImpl) LT_EQ(rhs DateExpression) BoolExpression { func (d *dateInterfaceImpl) LT_EQ(rhs DateExpression) BoolExpression {
return ltEq(d.parent, rhs) return LtEq(d.parent, rhs)
} }
func (d *dateInterfaceImpl) GT(rhs DateExpression) BoolExpression { func (d *dateInterfaceImpl) GT(rhs DateExpression) BoolExpression {
return gt(d.parent, rhs) return Gt(d.parent, rhs)
} }
func (d *dateInterfaceImpl) GT_EQ(rhs DateExpression) BoolExpression { func (d *dateInterfaceImpl) GT_EQ(rhs DateExpression) BoolExpression {
return gtEq(d.parent, rhs) return GtEq(d.parent, rhs)
} }
func (d *dateInterfaceImpl) ADD(rhs Interval) TimestampExpression { func (d *dateInterfaceImpl) ADD(rhs Interval) TimestampExpression {
return TimestampExp(newBinaryOperatorExpression(d.parent, rhs, "+")) return TimestampExp(Add(d.parent, rhs))
} }
func (d *dateInterfaceImpl) SUB(rhs Interval) TimestampExpression { func (d *dateInterfaceImpl) SUB(rhs Interval) TimestampExpression {
return TimestampExp(newBinaryOperatorExpression(d.parent, rhs, "-")) return TimestampExp(Sub(d.parent, rhs))
} }
//---------------------------------------------------// //---------------------------------------------------//

View file

@ -92,7 +92,8 @@ type binaryOperatorExpression struct {
operator string operator string
} }
func newBinaryOperatorExpression(lhs, rhs Serializer, operator string, additionalParam ...Expression) *binaryOperatorExpression { // NewBinaryOperatorExpression creates new binaryOperatorExpression
func NewBinaryOperatorExpression(lhs, rhs Serializer, operator string, additionalParam ...Expression) *binaryOperatorExpression {
binaryExpression := &binaryOperatorExpression{ binaryExpression := &binaryOperatorExpression{
lhs: lhs, lhs: lhs,
rhs: rhs, rhs: rhs,

View file

@ -29,64 +29,59 @@ type floatInterfaceImpl struct {
} }
func (n *floatInterfaceImpl) EQ(rhs FloatExpression) BoolExpression { func (n *floatInterfaceImpl) EQ(rhs FloatExpression) BoolExpression {
return eq(n.parent, rhs) return Eq(n.parent, rhs)
} }
func (n *floatInterfaceImpl) NOT_EQ(rhs FloatExpression) BoolExpression { func (n *floatInterfaceImpl) NOT_EQ(rhs FloatExpression) BoolExpression {
return notEq(n.parent, rhs) return NotEq(n.parent, rhs)
} }
func (n *floatInterfaceImpl) IS_DISTINCT_FROM(rhs FloatExpression) BoolExpression { func (n *floatInterfaceImpl) IS_DISTINCT_FROM(rhs FloatExpression) BoolExpression {
return isDistinctFrom(n.parent, rhs) return IsDistinctFrom(n.parent, rhs)
} }
func (n *floatInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs FloatExpression) BoolExpression { func (n *floatInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs FloatExpression) BoolExpression {
return isNotDistinctFrom(n.parent, rhs) return IsNotDistinctFrom(n.parent, rhs)
} }
func (n *floatInterfaceImpl) GT(rhs FloatExpression) BoolExpression { func (n *floatInterfaceImpl) GT(rhs FloatExpression) BoolExpression {
return gt(n.parent, rhs) return Gt(n.parent, rhs)
} }
func (n *floatInterfaceImpl) GT_EQ(rhs FloatExpression) BoolExpression { func (n *floatInterfaceImpl) GT_EQ(rhs FloatExpression) BoolExpression {
return gtEq(n.parent, rhs) return GtEq(n.parent, rhs)
} }
func (n *floatInterfaceImpl) LT(expression FloatExpression) BoolExpression { func (n *floatInterfaceImpl) LT(rhs FloatExpression) BoolExpression {
return lt(n.parent, expression) return Lt(n.parent, rhs)
} }
func (n *floatInterfaceImpl) LT_EQ(expression FloatExpression) BoolExpression { func (n *floatInterfaceImpl) LT_EQ(rhs FloatExpression) BoolExpression {
return ltEq(n.parent, expression) return LtEq(n.parent, rhs)
} }
func (n *floatInterfaceImpl) ADD(expression NumericExpression) FloatExpression { func (n *floatInterfaceImpl) ADD(rhs NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "+") return FloatExp(Add(n.parent, rhs))
} }
func (n *floatInterfaceImpl) SUB(expression NumericExpression) FloatExpression { func (n *floatInterfaceImpl) SUB(rhs NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "-") return FloatExp(Sub(n.parent, rhs))
} }
func (n *floatInterfaceImpl) MUL(expression NumericExpression) FloatExpression { func (n *floatInterfaceImpl) MUL(rhs NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "*") return FloatExp(Mul(n.parent, rhs))
} }
func (n *floatInterfaceImpl) DIV(expression NumericExpression) FloatExpression { func (n *floatInterfaceImpl) DIV(rhs NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "/") return FloatExp(Div(n.parent, rhs))
} }
func (n *floatInterfaceImpl) MOD(expression NumericExpression) FloatExpression { func (n *floatInterfaceImpl) MOD(rhs NumericExpression) FloatExpression {
return newBinaryFloatExpression(n.parent, expression, "%") return FloatExp(Mod(n.parent, rhs))
} }
func (n *floatInterfaceImpl) POW(expression NumericExpression) FloatExpression { func (n *floatInterfaceImpl) POW(rhs NumericExpression) FloatExpression {
return POW(n.parent, expression) return POW(n.parent, rhs)
}
//---------------------------------------------------//
func newBinaryFloatExpression(lhs, rhs Expression, operator string) FloatExpression {
return FloatExp(newBinaryOperatorExpression(lhs, rhs, operator))
} }
//---------------------------------------------------// //---------------------------------------------------//

View file

@ -54,71 +54,71 @@ type integerInterfaceImpl struct {
} }
func (i *integerInterfaceImpl) EQ(rhs IntegerExpression) BoolExpression { func (i *integerInterfaceImpl) EQ(rhs IntegerExpression) BoolExpression {
return eq(i.parent, rhs) return Eq(i.parent, rhs)
} }
func (i *integerInterfaceImpl) NOT_EQ(rhs IntegerExpression) BoolExpression { func (i *integerInterfaceImpl) NOT_EQ(rhs IntegerExpression) BoolExpression {
return notEq(i.parent, rhs) return NotEq(i.parent, rhs)
} }
func (i *integerInterfaceImpl) IS_DISTINCT_FROM(rhs IntegerExpression) BoolExpression { func (i *integerInterfaceImpl) IS_DISTINCT_FROM(rhs IntegerExpression) BoolExpression {
return isDistinctFrom(i.parent, rhs) return IsDistinctFrom(i.parent, rhs)
} }
func (i *integerInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs IntegerExpression) BoolExpression { func (i *integerInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs IntegerExpression) BoolExpression {
return isNotDistinctFrom(i.parent, rhs) return IsNotDistinctFrom(i.parent, rhs)
} }
func (i *integerInterfaceImpl) GT(rhs IntegerExpression) BoolExpression { func (i *integerInterfaceImpl) GT(rhs IntegerExpression) BoolExpression {
return gt(i.parent, rhs) return Gt(i.parent, rhs)
} }
func (i *integerInterfaceImpl) GT_EQ(rhs IntegerExpression) BoolExpression { func (i *integerInterfaceImpl) GT_EQ(rhs IntegerExpression) BoolExpression {
return gtEq(i.parent, rhs) return GtEq(i.parent, rhs)
} }
func (i *integerInterfaceImpl) LT(expression IntegerExpression) BoolExpression { func (i *integerInterfaceImpl) LT(rhs IntegerExpression) BoolExpression {
return lt(i.parent, expression) return Lt(i.parent, rhs)
} }
func (i *integerInterfaceImpl) LT_EQ(expression IntegerExpression) BoolExpression { func (i *integerInterfaceImpl) LT_EQ(rhs IntegerExpression) BoolExpression {
return ltEq(i.parent, expression) return LtEq(i.parent, rhs)
} }
func (i *integerInterfaceImpl) ADD(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) ADD(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "+") return IntExp(Add(i.parent, rhs))
} }
func (i *integerInterfaceImpl) SUB(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) SUB(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "-") return IntExp(Sub(i.parent, rhs))
} }
func (i *integerInterfaceImpl) MUL(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) MUL(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "*") return IntExp(Mul(i.parent, rhs))
} }
func (i *integerInterfaceImpl) DIV(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) DIV(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "/") return IntExp(Div(i.parent, rhs))
} }
func (i *integerInterfaceImpl) MOD(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) MOD(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "%") return IntExp(Mod(i.parent, rhs))
} }
func (i *integerInterfaceImpl) POW(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) POW(rhs IntegerExpression) IntegerExpression {
return IntExp(POW(i.parent, expression)) return IntExp(POW(i.parent, rhs))
} }
func (i *integerInterfaceImpl) BIT_AND(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) BIT_AND(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "&") return newBinaryIntegerOperatorExpression(i.parent, rhs, "&")
} }
func (i *integerInterfaceImpl) BIT_OR(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) BIT_OR(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "|") return newBinaryIntegerOperatorExpression(i.parent, rhs, "|")
} }
func (i *integerInterfaceImpl) BIT_XOR(expression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) BIT_XOR(rhs IntegerExpression) IntegerExpression {
return newBinaryIntegerOperatorExpression(i.parent, expression, "#") return newBinaryIntegerOperatorExpression(i.parent, rhs, "#")
} }
func (i *integerInterfaceImpl) BIT_SHIFT_LEFT(intExpression IntegerExpression) IntegerExpression { func (i *integerInterfaceImpl) BIT_SHIFT_LEFT(intExpression IntegerExpression) IntegerExpression {
@ -131,7 +131,7 @@ func (i *integerInterfaceImpl) BIT_SHIFT_RIGHT(intExpression IntegerExpression)
//---------------------------------------------------// //---------------------------------------------------//
func newBinaryIntegerOperatorExpression(lhs, rhs IntegerExpression, operator string) IntegerExpression { func newBinaryIntegerOperatorExpression(lhs, rhs IntegerExpression, operator string) IntegerExpression {
return IntExp(newBinaryOperatorExpression(lhs, rhs, operator)) return IntExp(NewBinaryOperatorExpression(lhs, rhs, operator))
} }
//---------------------------------------------------// //---------------------------------------------------//

View file

@ -11,22 +11,27 @@ type IsInterval interface {
isInterval() isInterval()
} }
// IsIntervalImpl is implementation of IsInterval interface
type IsIntervalImpl struct{}
func (i *IsIntervalImpl) isInterval() {}
// NewInterval creates new interval from serializer // NewInterval creates new interval from serializer
func NewInterval(s Serializer) Interval { func NewInterval(s Serializer) *IntervalImpl {
newInterval := &intervalImpl{ newInterval := &IntervalImpl{
interval: s, interval: s,
} }
return newInterval return newInterval
} }
type intervalImpl struct { // IntervalImpl is implementation of Interval type
type IntervalImpl struct {
interval Serializer interval Serializer
IsIntervalImpl
} }
func (i intervalImpl) isInterval() {} func (i IntervalImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
func (i intervalImpl) serialize(statement StatementType, out *SQLBuilder, options ...SerializeOption) {
out.WriteString("INTERVAL") out.WriteString("INTERVAL")
i.interval.serialize(statement, out, options...) i.interval.serialize(statement, out, options...)
} }

View file

@ -346,9 +346,9 @@ func (n *rawExpression) serialize(statement StatementType, out *SQLBuilder, opti
// Raw can be used for any unsupported functions, operators or expressions. // Raw can be used for any unsupported functions, operators or expressions.
// For example: Raw("current_database()") // For example: Raw("current_database()")
func Raw(raw string) Expression { func Raw(raw string, parent ...Expression) Expression {
rawExp := &rawExpression{Raw: raw} rawExp := &rawExpression{Raw: raw}
rawExp.ExpressionInterfaceImpl.Parent = rawExp rawExp.ExpressionInterfaceImpl.Parent = OptionalOrDefaultExpression(rawExp, parent...)
return rawExp return rawExp
} }

View file

@ -29,44 +29,71 @@ func EXISTS(subQuery Expression) BoolExpression {
return newPrefixBoolOperatorExpression(subQuery, "EXISTS") return newPrefixBoolOperatorExpression(subQuery, "EXISTS")
} }
// Returns a representation of "a=b" // Eq returns a representation of "a=b"
func eq(lhs, rhs Expression) BoolExpression { func Eq(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "=") return newBinaryBoolOperatorExpression(lhs, rhs, "=")
} }
// Returns a representation of "a!=b" // NotEq returns a representation of "a!=b"
func notEq(lhs, rhs Expression) BoolExpression { func NotEq(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "!=") return newBinaryBoolOperatorExpression(lhs, rhs, "!=")
} }
func isDistinctFrom(lhs, rhs Expression) BoolExpression { // IsDistinctFrom returns a representation of "a IS DISTINCT FROM b"
func IsDistinctFrom(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "IS DISTINCT FROM") return newBinaryBoolOperatorExpression(lhs, rhs, "IS DISTINCT FROM")
} }
func isNotDistinctFrom(lhs, rhs Expression) BoolExpression { // IsNotDistinctFrom returns a representation of "a IS NOT DISTINCT FROM b"
func IsNotDistinctFrom(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "IS NOT DISTINCT FROM") return newBinaryBoolOperatorExpression(lhs, rhs, "IS NOT DISTINCT FROM")
} }
// Returns a representation of "a<b" // Lt returns a representation of "a<b"
func lt(lhs Expression, rhs Expression) BoolExpression { func Lt(lhs Expression, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "<") return newBinaryBoolOperatorExpression(lhs, rhs, "<")
} }
// Returns a representation of "a<=b" // LtEq returns a representation of "a<=b"
func ltEq(lhs, rhs Expression) BoolExpression { func LtEq(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, "<=") return newBinaryBoolOperatorExpression(lhs, rhs, "<=")
} }
// Returns a representation of "a>b" // Gt returns a representation of "a>b"
func gt(lhs, rhs Expression) BoolExpression { func Gt(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, ">") return newBinaryBoolOperatorExpression(lhs, rhs, ">")
} }
// Returns a representation of "a>=b" // GtEq returns a representation of "a>=b"
func gtEq(lhs, rhs Expression) BoolExpression { func GtEq(lhs, rhs Expression) BoolExpression {
return newBinaryBoolOperatorExpression(lhs, rhs, ">=") return newBinaryBoolOperatorExpression(lhs, rhs, ">=")
} }
// Add notEq returns a representation of "a + b"
func Add(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "+")
}
// Sub notEq returns a representation of "a - b"
func Sub(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "-")
}
// Mul returns a representation of "a * b"
func Mul(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "*")
}
// Div returns a representation of "a / b"
func Div(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "/")
}
// Mod returns a representation of "a % b"
func Mod(lhs, rhs Serializer) Expression {
return NewBinaryOperatorExpression(lhs, rhs, "%")
}
// --------------- CASE operator -------------------// // --------------- CASE operator -------------------//
// CaseOperator is interface for SQL case operator // CaseOperator is interface for SQL case operator

View file

@ -28,35 +28,35 @@ type stringInterfaceImpl struct {
} }
func (s *stringInterfaceImpl) EQ(rhs StringExpression) BoolExpression { func (s *stringInterfaceImpl) EQ(rhs StringExpression) BoolExpression {
return eq(s.parent, rhs) return Eq(s.parent, rhs)
} }
func (s *stringInterfaceImpl) NOT_EQ(rhs StringExpression) BoolExpression { func (s *stringInterfaceImpl) NOT_EQ(rhs StringExpression) BoolExpression {
return notEq(s.parent, rhs) return NotEq(s.parent, rhs)
} }
func (s *stringInterfaceImpl) IS_DISTINCT_FROM(rhs StringExpression) BoolExpression { func (s *stringInterfaceImpl) IS_DISTINCT_FROM(rhs StringExpression) BoolExpression {
return isDistinctFrom(s.parent, rhs) return IsDistinctFrom(s.parent, rhs)
} }
func (s *stringInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs StringExpression) BoolExpression { func (s *stringInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs StringExpression) BoolExpression {
return isNotDistinctFrom(s.parent, rhs) return IsNotDistinctFrom(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)
} }
func (s *stringInterfaceImpl) GT_EQ(rhs StringExpression) BoolExpression { func (s *stringInterfaceImpl) GT_EQ(rhs StringExpression) BoolExpression {
return gtEq(s.parent, rhs) return GtEq(s.parent, rhs)
} }
func (s *stringInterfaceImpl) LT(rhs StringExpression) BoolExpression { func (s *stringInterfaceImpl) LT(rhs StringExpression) BoolExpression {
return lt(s.parent, rhs) return Lt(s.parent, rhs)
} }
func (s *stringInterfaceImpl) LT_EQ(rhs StringExpression) BoolExpression { func (s *stringInterfaceImpl) LT_EQ(rhs StringExpression) BoolExpression {
return ltEq(s.parent, rhs) return LtEq(s.parent, rhs)
} }
func (s *stringInterfaceImpl) CONCAT(rhs Expression) StringExpression { func (s *stringInterfaceImpl) CONCAT(rhs Expression) StringExpression {
@ -81,7 +81,7 @@ func (s *stringInterfaceImpl) NOT_REGEXP_LIKE(pattern StringExpression, caseSens
//---------------------------------------------------// //---------------------------------------------------//
func newBinaryStringOperatorExpression(lhs, rhs Expression, operator string) StringExpression { func newBinaryStringOperatorExpression(lhs, rhs Expression, operator string) StringExpression {
return StringExp(newBinaryOperatorExpression(lhs, rhs, operator)) return StringExp(NewBinaryOperatorExpression(lhs, rhs, operator))
} }
//---------------------------------------------------// //---------------------------------------------------//

View file

@ -23,43 +23,43 @@ type timeInterfaceImpl struct {
} }
func (t *timeInterfaceImpl) EQ(rhs TimeExpression) BoolExpression { func (t *timeInterfaceImpl) EQ(rhs TimeExpression) BoolExpression {
return eq(t.parent, rhs) return Eq(t.parent, rhs)
} }
func (t *timeInterfaceImpl) NOT_EQ(rhs TimeExpression) BoolExpression { func (t *timeInterfaceImpl) NOT_EQ(rhs TimeExpression) BoolExpression {
return notEq(t.parent, rhs) return NotEq(t.parent, rhs)
} }
func (t *timeInterfaceImpl) IS_DISTINCT_FROM(rhs TimeExpression) BoolExpression { func (t *timeInterfaceImpl) IS_DISTINCT_FROM(rhs TimeExpression) BoolExpression {
return isDistinctFrom(t.parent, rhs) return IsDistinctFrom(t.parent, rhs)
} }
func (t *timeInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimeExpression) BoolExpression { func (t *timeInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimeExpression) BoolExpression {
return isNotDistinctFrom(t.parent, rhs) return IsNotDistinctFrom(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)
} }
func (t *timeInterfaceImpl) LT_EQ(rhs TimeExpression) BoolExpression { func (t *timeInterfaceImpl) LT_EQ(rhs TimeExpression) BoolExpression {
return ltEq(t.parent, rhs) return LtEq(t.parent, rhs)
} }
func (t *timeInterfaceImpl) GT(rhs TimeExpression) BoolExpression { func (t *timeInterfaceImpl) GT(rhs TimeExpression) BoolExpression {
return gt(t.parent, rhs) return Gt(t.parent, rhs)
} }
func (t *timeInterfaceImpl) GT_EQ(rhs TimeExpression) BoolExpression { func (t *timeInterfaceImpl) GT_EQ(rhs TimeExpression) BoolExpression {
return gtEq(t.parent, rhs) return GtEq(t.parent, rhs)
} }
func (t *timeInterfaceImpl) ADD(rhs Interval) TimeExpression { func (t *timeInterfaceImpl) ADD(rhs Interval) TimeExpression {
return TimeExp(newBinaryOperatorExpression(t.parent, rhs, "+")) return TimeExp(Add(t.parent, rhs))
} }
func (t *timeInterfaceImpl) SUB(rhs Interval) TimeExpression { func (t *timeInterfaceImpl) SUB(rhs Interval) TimeExpression {
return TimeExp(newBinaryOperatorExpression(t.parent, rhs, "-")) return TimeExp(Sub(t.parent, rhs))
} }
//---------------------------------------------------// //---------------------------------------------------//

View file

@ -23,43 +23,43 @@ type timestampInterfaceImpl struct {
} }
func (t *timestampInterfaceImpl) EQ(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) EQ(rhs TimestampExpression) BoolExpression {
return eq(t.parent, rhs) return Eq(t.parent, rhs)
} }
func (t *timestampInterfaceImpl) NOT_EQ(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) NOT_EQ(rhs TimestampExpression) BoolExpression {
return notEq(t.parent, rhs) return NotEq(t.parent, rhs)
} }
func (t *timestampInterfaceImpl) IS_DISTINCT_FROM(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) IS_DISTINCT_FROM(rhs TimestampExpression) BoolExpression {
return isDistinctFrom(t.parent, rhs) return IsDistinctFrom(t.parent, rhs)
} }
func (t *timestampInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimestampExpression) BoolExpression {
return isNotDistinctFrom(t.parent, rhs) return IsNotDistinctFrom(t.parent, rhs)
} }
func (t *timestampInterfaceImpl) LT(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) LT(rhs TimestampExpression) BoolExpression {
return lt(t.parent, rhs) return Lt(t.parent, rhs)
} }
func (t *timestampInterfaceImpl) LT_EQ(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) LT_EQ(rhs TimestampExpression) BoolExpression {
return ltEq(t.parent, rhs) return LtEq(t.parent, rhs)
} }
func (t *timestampInterfaceImpl) GT(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) GT(rhs TimestampExpression) BoolExpression {
return gt(t.parent, rhs) return Gt(t.parent, rhs)
} }
func (t *timestampInterfaceImpl) GT_EQ(rhs TimestampExpression) BoolExpression { func (t *timestampInterfaceImpl) GT_EQ(rhs TimestampExpression) BoolExpression {
return gtEq(t.parent, rhs) return GtEq(t.parent, rhs)
} }
func (t *timestampInterfaceImpl) ADD(rhs Interval) TimestampExpression { func (t *timestampInterfaceImpl) ADD(rhs Interval) TimestampExpression {
return TimestampExp(newBinaryOperatorExpression(t.parent, rhs, "+")) return TimestampExp(Add(t.parent, rhs))
} }
func (t *timestampInterfaceImpl) SUB(rhs Interval) TimestampExpression { func (t *timestampInterfaceImpl) SUB(rhs Interval) TimestampExpression {
return TimestampExp(newBinaryOperatorExpression(t.parent, rhs, "-")) return TimestampExp(Sub(t.parent, rhs))
} }
//------------------------------------------------- //-------------------------------------------------

View file

@ -23,43 +23,43 @@ type timestampzInterfaceImpl struct {
} }
func (t *timestampzInterfaceImpl) EQ(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) EQ(rhs TimestampzExpression) BoolExpression {
return eq(t.parent, rhs) return Eq(t.parent, rhs)
} }
func (t *timestampzInterfaceImpl) NOT_EQ(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) NOT_EQ(rhs TimestampzExpression) BoolExpression {
return notEq(t.parent, rhs) return NotEq(t.parent, rhs)
} }
func (t *timestampzInterfaceImpl) IS_DISTINCT_FROM(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) IS_DISTINCT_FROM(rhs TimestampzExpression) BoolExpression {
return isDistinctFrom(t.parent, rhs) return IsDistinctFrom(t.parent, rhs)
} }
func (t *timestampzInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimestampzExpression) BoolExpression {
return isNotDistinctFrom(t.parent, rhs) return IsNotDistinctFrom(t.parent, rhs)
} }
func (t *timestampzInterfaceImpl) LT(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) LT(rhs TimestampzExpression) BoolExpression {
return lt(t.parent, rhs) return Lt(t.parent, rhs)
} }
func (t *timestampzInterfaceImpl) LT_EQ(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) LT_EQ(rhs TimestampzExpression) BoolExpression {
return ltEq(t.parent, rhs) return LtEq(t.parent, rhs)
} }
func (t *timestampzInterfaceImpl) GT(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) GT(rhs TimestampzExpression) BoolExpression {
return gt(t.parent, rhs) return Gt(t.parent, rhs)
} }
func (t *timestampzInterfaceImpl) GT_EQ(rhs TimestampzExpression) BoolExpression { func (t *timestampzInterfaceImpl) GT_EQ(rhs TimestampzExpression) BoolExpression {
return gtEq(t.parent, rhs) return GtEq(t.parent, rhs)
} }
func (t *timestampzInterfaceImpl) ADD(rhs Interval) TimestampzExpression { func (t *timestampzInterfaceImpl) ADD(rhs Interval) TimestampzExpression {
return TimestampzExp(newBinaryOperatorExpression(t.parent, rhs, "+")) return TimestampzExp(Add(t.parent, rhs))
} }
func (t *timestampzInterfaceImpl) SUB(rhs Interval) TimestampzExpression { func (t *timestampzInterfaceImpl) SUB(rhs Interval) TimestampzExpression {
return TimestampzExp(newBinaryOperatorExpression(t.parent, rhs, "-")) return TimestampzExp(Sub(t.parent, rhs))
} }
//------------------------------------------------- //-------------------------------------------------

View file

@ -23,43 +23,43 @@ type timezInterfaceImpl struct {
} }
func (t *timezInterfaceImpl) EQ(rhs TimezExpression) BoolExpression { func (t *timezInterfaceImpl) EQ(rhs TimezExpression) BoolExpression {
return eq(t.parent, rhs) return Eq(t.parent, rhs)
} }
func (t *timezInterfaceImpl) NOT_EQ(rhs TimezExpression) BoolExpression { func (t *timezInterfaceImpl) NOT_EQ(rhs TimezExpression) BoolExpression {
return notEq(t.parent, rhs) return NotEq(t.parent, rhs)
} }
func (t *timezInterfaceImpl) IS_DISTINCT_FROM(rhs TimezExpression) BoolExpression { func (t *timezInterfaceImpl) IS_DISTINCT_FROM(rhs TimezExpression) BoolExpression {
return isDistinctFrom(t.parent, rhs) return IsDistinctFrom(t.parent, rhs)
} }
func (t *timezInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimezExpression) BoolExpression { func (t *timezInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs TimezExpression) BoolExpression {
return isNotDistinctFrom(t.parent, rhs) return IsNotDistinctFrom(t.parent, rhs)
} }
func (t *timezInterfaceImpl) LT(rhs TimezExpression) BoolExpression { func (t *timezInterfaceImpl) LT(rhs TimezExpression) BoolExpression {
return lt(t.parent, rhs) return Lt(t.parent, rhs)
} }
func (t *timezInterfaceImpl) LT_EQ(rhs TimezExpression) BoolExpression { func (t *timezInterfaceImpl) LT_EQ(rhs TimezExpression) BoolExpression {
return ltEq(t.parent, rhs) return LtEq(t.parent, rhs)
} }
func (t *timezInterfaceImpl) GT(rhs TimezExpression) BoolExpression { func (t *timezInterfaceImpl) GT(rhs TimezExpression) BoolExpression {
return gt(t.parent, rhs) return Gt(t.parent, rhs)
} }
func (t *timezInterfaceImpl) GT_EQ(rhs TimezExpression) BoolExpression { func (t *timezInterfaceImpl) GT_EQ(rhs TimezExpression) BoolExpression {
return gtEq(t.parent, rhs) return GtEq(t.parent, rhs)
} }
func (t *timezInterfaceImpl) ADD(rhs Interval) TimezExpression { func (t *timezInterfaceImpl) ADD(rhs Interval) TimezExpression {
return TimezExp(newBinaryOperatorExpression(t.parent, rhs, "+")) return TimezExp(Add(t.parent, rhs))
} }
func (t *timezInterfaceImpl) SUB(rhs Interval) TimezExpression { func (t *timezInterfaceImpl) SUB(rhs Interval) TimezExpression {
return TimezExp(newBinaryOperatorExpression(t.parent, rhs, "-")) return TimezExp(Sub(t.parent, rhs))
} }
//---------------------------------------------------// //---------------------------------------------------//

View file

@ -187,3 +187,23 @@ func UnwidColumnList(columns []Column) []Column {
return ret return ret
} }
// OptionalOrDefaultString will return first value from variable argument list str or
// defaultStr if variable argument list is empty
func OptionalOrDefaultString(defaultStr string, str ...string) string {
if len(str) > 0 {
return str[0]
}
return defaultStr
}
// OptionalOrDefaultExpression will return first value from variable argument list expression or
// defaultExpression if variable argument list is empty
func OptionalOrDefaultExpression(defaultExpression Expression, expression ...Expression) Expression {
if len(expression) > 0 {
return expression[0]
}
return defaultExpression
}

View file

@ -0,0 +1,19 @@
package jet
import (
"gotest.tools/assert"
"testing"
)
func TestOptionalOrDefaultString(t *testing.T) {
assert.Equal(t, OptionalOrDefaultString("default"), "default")
assert.Equal(t, OptionalOrDefaultString("default", "optional"), "optional")
}
func TestOptionalOrDefaultExpression(t *testing.T) {
defaultExpression := table2ColFloat
optionalExpression := table1Col1
assert.Equal(t, OptionalOrDefaultExpression(defaultExpression), defaultExpression)
assert.Equal(t, OptionalOrDefaultExpression(defaultExpression, optionalExpression), optionalExpression)
}

View file

@ -1,6 +1,8 @@
package postgres package postgres
import "github.com/go-jet/jet/internal/jet" import (
"github.com/go-jet/jet/internal/jet"
)
// Column is common column interface for all types of columns. // Column is common column interface for all types of columns.
type Column = jet.ColumnExpression type Column = jet.ColumnExpression
@ -62,3 +64,34 @@ type ColumnTimestampz = jet.ColumnTimestampz
// TimestampzColumn creates named timestamp with time zone column. // TimestampzColumn creates named timestamp with time zone column.
var TimestampzColumn = jet.TimestampzColumn var TimestampzColumn = jet.TimestampzColumn
//------------------------------------------------------//
// ColumnInterval is interface of PostgreSQL interval columns.
type ColumnInterval interface {
IntervalExpression
jet.Column
From(subQuery SelectTable) ColumnInterval
}
type intervalColumnImpl struct {
jet.ColumnExpressionImpl
intervalInterfaceImpl
}
func (i *intervalColumnImpl) From(subQuery SelectTable) ColumnInterval {
newIntervalColumn := IntervalColumn(i.Name())
jet.SetTableName(newIntervalColumn, i.TableName())
jet.SetSubQuery(newIntervalColumn, subQuery)
return newIntervalColumn
}
// IntervalColumn creates named interval column.
func IntervalColumn(name string) ColumnInterval {
intervalColumn := &intervalColumnImpl{}
intervalColumn.ColumnExpressionImpl = jet.NewColumnImpl(name, "", intervalColumn)
intervalColumn.intervalInterfaceImpl.parent = intervalColumn
return intervalColumn
}

20
postgres/columns_test.go Normal file
View file

@ -0,0 +1,20 @@
package postgres
import (
"testing"
)
func TestNewIntervalColumn(t *testing.T) {
subQuery := SELECT(Int(1)).AsTable("sub_query")
subQueryIntervalColumn := IntervalColumn("col_interval").From(subQuery)
assertSerialize(t, subQueryIntervalColumn, `sub_query."col_interval"`)
assertSerialize(t, subQueryIntervalColumn.EQ(INTERVAL(2, HOUR, 10, MINUTE)),
`(sub_query."col_interval" = INTERVAL '2 HOUR 10 MINUTE')`)
assertProjectionSerialize(t, subQueryIntervalColumn, `sub_query."col_interval" AS "col_interval"`)
subQueryIntervalColumn2 := table1ColInterval.From(subQuery)
assertSerialize(t, subQueryIntervalColumn2, `sub_query."table1.col_interval"`)
assertSerialize(t, subQueryIntervalColumn2.EQ(INTERVAL(1, DAY)), `(sub_query."table1.col_interval" = INTERVAL '1 DAY')`)
assertProjectionSerialize(t, subQueryIntervalColumn2, `sub_query."table1.col_interval" AS "table1.col_interval"`)
}

View file

@ -12,6 +12,9 @@ type BoolExpression = jet.BoolExpression
// StringExpression interface // StringExpression interface
type StringExpression = jet.StringExpression type StringExpression = jet.StringExpression
// NumericExpression interface
type NumericExpression = jet.NumericExpression
// IntegerExpression interface // IntegerExpression interface
type IntegerExpression = jet.IntegerExpression type IntegerExpression = jet.IntegerExpression

View file

@ -27,39 +27,109 @@ const (
MILLENNIUM MILLENNIUM
) )
type intervalExpressionImpl struct {
jet.Interval
jet.ExpressionInterfaceImpl
}
// IntervalExpression is representation of postgres INTERVAL // IntervalExpression is representation of postgres INTERVAL
type IntervalExpression interface { type IntervalExpression interface {
jet.IsInterval jet.IsInterval
jet.Expression jet.Expression
EQ(rhs IntervalExpression) BoolExpression
NOT_EQ(rhs IntervalExpression) BoolExpression
IS_DISTINCT_FROM(rhs IntervalExpression) BoolExpression
IS_NOT_DISTINCT_FROM(rhs IntervalExpression) BoolExpression
LT(rhs IntervalExpression) BoolExpression
LT_EQ(rhs IntervalExpression) BoolExpression
GT(rhs IntervalExpression) BoolExpression
GT_EQ(rhs IntervalExpression) BoolExpression
ADD(rhs IntervalExpression) IntervalExpression
SUB(rhs IntervalExpression) IntervalExpression
MUL(rhs NumericExpression) IntervalExpression
DIV(rhs NumericExpression) IntervalExpression
}
type intervalInterfaceImpl struct {
jet.IsIntervalImpl
parent IntervalExpression
}
func (i *intervalInterfaceImpl) EQ(rhs IntervalExpression) BoolExpression {
return jet.Eq(i.parent, rhs)
}
func (i *intervalInterfaceImpl) NOT_EQ(rhs IntervalExpression) BoolExpression {
return jet.NotEq(i.parent, rhs)
}
func (i *intervalInterfaceImpl) IS_DISTINCT_FROM(rhs IntervalExpression) BoolExpression {
return jet.IsDistinctFrom(i.parent, rhs)
}
func (i *intervalInterfaceImpl) IS_NOT_DISTINCT_FROM(rhs IntervalExpression) BoolExpression {
return jet.IsNotDistinctFrom(i.parent, rhs)
}
func (i *intervalInterfaceImpl) LT(rhs IntervalExpression) BoolExpression {
return jet.Lt(i.parent, rhs)
}
func (i *intervalInterfaceImpl) LT_EQ(rhs IntervalExpression) BoolExpression {
return jet.LtEq(i.parent, rhs)
}
func (i *intervalInterfaceImpl) GT(rhs IntervalExpression) BoolExpression {
return jet.Gt(i.parent, rhs)
}
func (i *intervalInterfaceImpl) GT_EQ(rhs IntervalExpression) BoolExpression {
return jet.GtEq(i.parent, rhs)
}
func (i *intervalInterfaceImpl) ADD(rhs IntervalExpression) IntervalExpression {
return IntervalExp(jet.Add(i.parent, rhs))
}
func (i *intervalInterfaceImpl) SUB(rhs IntervalExpression) IntervalExpression {
return IntervalExp(jet.Sub(i.parent, rhs))
}
func (i *intervalInterfaceImpl) MUL(rhs NumericExpression) IntervalExpression {
return IntervalExp(jet.Mul(i.parent, rhs))
}
func (i *intervalInterfaceImpl) DIV(rhs NumericExpression) IntervalExpression {
return IntervalExp(jet.Div(i.parent, rhs))
}
type intervalExpression struct {
jet.Expression
intervalInterfaceImpl
} }
// INTERVAL creates new interval expression from the list of quantity-unit pairs. // INTERVAL creates new interval expression from the list of quantity-unit pairs.
// For example: INTERVAL(1, DAY, 3, MINUTE) // For example: INTERVAL(1, DAY, 3, MINUTE)
func INTERVAL(quantityAndUnit ...quantityAndUnit) IntervalExpression { func INTERVAL(quantityAndUnit ...quantityAndUnit) IntervalExpression {
if len(quantityAndUnit)%2 != 0 { quantityAndUnitLen := len(quantityAndUnit)
if quantityAndUnitLen == 0 || quantityAndUnitLen%2 != 0 {
panic("jet: invalid number of quantity and unit fields") panic("jet: invalid number of quantity and unit fields")
} }
fields := []string{} fields := []string{}
for i := 0; i < len(quantityAndUnit); i += 2 { for i := 0; i < len(quantityAndUnit); i += 2 {
quantity := strconv.FormatFloat(float64(quantityAndUnit[i]), 'f', -1, 64) quantity := strconv.FormatFloat(quantityAndUnit[i], 'f', -1, 64)
unitString := unitToString(quantityAndUnit[i+1]) unitString := unitToString(quantityAndUnit[i+1])
fields = append(fields, quantity+" "+unitString) fields = append(fields, quantity+" "+unitString)
} }
intervalStr := fmt.Sprintf("'%s'", strings.Join(fields, " ")) intervalStr := fmt.Sprintf("INTERVAL '%s'", strings.Join(fields, " "))
newInterval := &intervalExpressionImpl{ newInterval := &intervalExpression{}
Interval: jet.NewInterval(jet.Raw(intervalStr)),
}
newInterval.ExpressionInterfaceImpl.Parent = newInterval newInterval.Expression = jet.Raw(intervalStr, newInterval)
newInterval.intervalInterfaceImpl.parent = newInterval
return newInterval return newInterval
} }
@ -136,13 +206,14 @@ func unitToString(unit quantityAndUnit) string {
//---------------------------------------------------// //---------------------------------------------------//
type intervalWrapper struct { type intervalWrapper struct {
jet.IsInterval intervalInterfaceImpl
Expression Expression
} }
func newIntervalExpressionWrap(expression Expression) IntervalExpression { func newIntervalExpressionWrap(expression Expression) IntervalExpression {
intervalWrap := intervalWrapper{Expression: expression} intervalWrap := &intervalWrapper{Expression: expression}
return &intervalWrap intervalWrap.intervalInterfaceImpl.parent = intervalWrap
return intervalWrap
} }
// IntervalExp is interval expression wrapper around arbitrary expression. // IntervalExp is interval expression wrapper around arbitrary expression.

View file

@ -44,11 +44,12 @@ func TestINTERVALd(t *testing.T) {
} }
func TestINTERVAL_InvalidParams(t *testing.T) { func TestINTERVAL_InvalidParams(t *testing.T) {
assertPanicErr(t, func() { INTERVAL() }, "jet: invalid number of quantity and unit fields")
assertPanicErr(t, func() { INTERVAL(1) }, "jet: invalid number of quantity and unit fields") assertPanicErr(t, func() { INTERVAL(1) }, "jet: invalid number of quantity and unit fields")
assertPanicErr(t, func() { INTERVAL(1, 2) }, "jet: invalid INTERVAL unit type") assertPanicErr(t, func() { INTERVAL(1, 2) }, "jet: invalid INTERVAL unit type")
} }
func TestIntervalArithmetic(t *testing.T) { func TestDateTimeIntervalArithmetic(t *testing.T) {
assertSerialize(t, table2ColDate.ADD(INTERVAL(1, HOUR)), "(table2.col_date + INTERVAL '1 HOUR')") assertSerialize(t, table2ColDate.ADD(INTERVAL(1, HOUR)), "(table2.col_date + INTERVAL '1 HOUR')")
assertSerialize(t, table2ColDate.SUB(INTERVAL(1, HOUR)), "(table2.col_date - INTERVAL '1 HOUR')") assertSerialize(t, table2ColDate.SUB(INTERVAL(1, HOUR)), "(table2.col_date - INTERVAL '1 HOUR')")
assertSerialize(t, table2ColTime.ADD(INTERVAL(1, HOUR)), "(table2.col_time + INTERVAL '1 HOUR')") assertSerialize(t, table2ColTime.ADD(INTERVAL(1, HOUR)), "(table2.col_time + INTERVAL '1 HOUR')")
@ -60,3 +61,24 @@ func TestIntervalArithmetic(t *testing.T) {
assertSerialize(t, table2ColTimestampz.ADD(INTERVAL(1, HOUR)), "(table2.col_timestampz + INTERVAL '1 HOUR')") assertSerialize(t, table2ColTimestampz.ADD(INTERVAL(1, HOUR)), "(table2.col_timestampz + INTERVAL '1 HOUR')")
assertSerialize(t, table2ColTimestampz.SUB(INTERVAL(1, HOUR)), "(table2.col_timestampz - INTERVAL '1 HOUR')") assertSerialize(t, table2ColTimestampz.SUB(INTERVAL(1, HOUR)), "(table2.col_timestampz - INTERVAL '1 HOUR')")
} }
func TestIntervalExpressionMethods(t *testing.T) {
assertSerialize(t, table1ColInterval.EQ(table2ColInterval), "(table1.col_interval = table2.col_interval)")
assertSerialize(t, table1ColInterval.EQ(INTERVAL(10, SECOND)), "(table1.col_interval = INTERVAL '10 SECOND')")
assertSerialize(t, table1ColInterval.EQ(INTERVALd(11*time.Minute)), "(table1.col_interval = INTERVAL '11 MINUTE')")
assertSerialize(t, table1ColInterval.EQ(INTERVALd(11*time.Minute)).EQ(Bool(false)),
"((table1.col_interval = INTERVAL '11 MINUTE') = $1)", false)
assertSerialize(t, table1ColInterval.NOT_EQ(table2ColInterval), "(table1.col_interval != table2.col_interval)")
assertSerialize(t, table1ColInterval.IS_DISTINCT_FROM(table2ColInterval), "(table1.col_interval IS DISTINCT FROM table2.col_interval)")
assertSerialize(t, table1ColInterval.IS_NOT_DISTINCT_FROM(table2ColInterval), "(table1.col_interval IS NOT DISTINCT FROM table2.col_interval)")
assertSerialize(t, table1ColInterval.LT(table2ColInterval), "(table1.col_interval < table2.col_interval)")
assertSerialize(t, table1ColInterval.LT_EQ(table2ColInterval), "(table1.col_interval <= table2.col_interval)")
assertSerialize(t, table1ColInterval.GT(table2ColInterval), "(table1.col_interval > table2.col_interval)")
assertSerialize(t, table1ColInterval.GT_EQ(table2ColInterval), "(table1.col_interval >= table2.col_interval)")
assertSerialize(t, table1ColInterval.ADD(table2ColInterval), "(table1.col_interval + table2.col_interval)")
assertSerialize(t, table1ColInterval.SUB(table2ColInterval), "(table1.col_interval - table2.col_interval)")
assertSerialize(t, table1ColInterval.MUL(table2ColInt), "(table1.col_interval * table2.col_int)")
assertSerialize(t, table1ColInterval.MUL(table2ColFloat), "(table1.col_interval * table2.col_float)")
assertSerialize(t, table1ColInterval.DIV(table2ColInt), "(table1.col_interval / table2.col_int)")
assertSerialize(t, table1ColInterval.DIV(table2ColFloat), "(table1.col_interval / table2.col_float)")
}

View file

@ -17,6 +17,7 @@ var table1ColTimestamp = TimestampColumn("col_timestamp")
var table1ColTimestampz = TimestampzColumn("col_timestampz") var table1ColTimestampz = TimestampzColumn("col_timestampz")
var table1ColBool = BoolColumn("col_bool") var table1ColBool = BoolColumn("col_bool")
var table1ColDate = DateColumn("col_date") var table1ColDate = DateColumn("col_date")
var table1ColInterval = IntervalColumn("col_interval")
var table1 = NewTable( var table1 = NewTable(
"db", "db",
@ -31,6 +32,7 @@ var table1 = NewTable(
table1ColDate, table1ColDate,
table1ColTimestamp, table1ColTimestamp,
table1ColTimestampz, table1ColTimestampz,
table1ColInterval,
) )
var table2Col3 = IntegerColumn("col3") var table2Col3 = IntegerColumn("col3")
@ -44,6 +46,7 @@ var table2ColTimez = TimezColumn("col_timez")
var table2ColTimestamp = TimestampColumn("col_timestamp") var table2ColTimestamp = TimestampColumn("col_timestamp")
var table2ColTimestampz = TimestampzColumn("col_timestampz") var table2ColTimestampz = TimestampzColumn("col_timestampz")
var table2ColDate = DateColumn("col_date") var table2ColDate = DateColumn("col_date")
var table2ColInterval = IntervalColumn("col_interval")
var table2 = NewTable( var table2 = NewTable(
"db", "db",
@ -59,6 +62,7 @@ var table2 = NewTable(
table2ColDate, table2ColDate,
table2ColTimestamp, table2ColTimestamp,
table2ColTimestampz, table2ColTimestampz,
table2ColInterval,
) )
var table3Col1 = IntegerColumn("col1") var table3Col1 = IntegerColumn("col1")

View file

@ -71,6 +71,152 @@ func TestAllTypesInsertQuery(t *testing.T) {
assert.DeepEqual(t, dest[1], allTypesRow1) assert.DeepEqual(t, dest[1], allTypesRow1)
} }
func TestAllTypesFromSubQuery(t *testing.T) {
subQuery := SELECT(AllTypes.AllColumns).
FROM(AllTypes).
AsTable("allTypesSubQuery")
mainQuery := SELECT(subQuery.AllColumns()).
FROM(subQuery).
LIMIT(2)
assert.Equal(t, mainQuery.DebugSql(), `
SELECT "allTypesSubQuery"."all_types.small_int_ptr" AS "all_types.small_int_ptr",
"allTypesSubQuery"."all_types.small_int" AS "all_types.small_int",
"allTypesSubQuery"."all_types.integer_ptr" AS "all_types.integer_ptr",
"allTypesSubQuery"."all_types.integer" AS "all_types.integer",
"allTypesSubQuery"."all_types.big_int_ptr" AS "all_types.big_int_ptr",
"allTypesSubQuery"."all_types.big_int" AS "all_types.big_int",
"allTypesSubQuery"."all_types.decimal_ptr" AS "all_types.decimal_ptr",
"allTypesSubQuery"."all_types.decimal" AS "all_types.decimal",
"allTypesSubQuery"."all_types.numeric_ptr" AS "all_types.numeric_ptr",
"allTypesSubQuery"."all_types.numeric" AS "all_types.numeric",
"allTypesSubQuery"."all_types.real_ptr" AS "all_types.real_ptr",
"allTypesSubQuery"."all_types.real" AS "all_types.real",
"allTypesSubQuery"."all_types.double_precision_ptr" AS "all_types.double_precision_ptr",
"allTypesSubQuery"."all_types.double_precision" AS "all_types.double_precision",
"allTypesSubQuery"."all_types.smallserial" AS "all_types.smallserial",
"allTypesSubQuery"."all_types.serial" AS "all_types.serial",
"allTypesSubQuery"."all_types.bigserial" AS "all_types.bigserial",
"allTypesSubQuery"."all_types.var_char_ptr" AS "all_types.var_char_ptr",
"allTypesSubQuery"."all_types.var_char" AS "all_types.var_char",
"allTypesSubQuery"."all_types.char_ptr" AS "all_types.char_ptr",
"allTypesSubQuery"."all_types.char" AS "all_types.char",
"allTypesSubQuery"."all_types.text_ptr" AS "all_types.text_ptr",
"allTypesSubQuery"."all_types.text" AS "all_types.text",
"allTypesSubQuery"."all_types.bytea_ptr" AS "all_types.bytea_ptr",
"allTypesSubQuery"."all_types.bytea" AS "all_types.bytea",
"allTypesSubQuery"."all_types.timestampz_ptr" AS "all_types.timestampz_ptr",
"allTypesSubQuery"."all_types.timestampz" AS "all_types.timestampz",
"allTypesSubQuery"."all_types.timestamp_ptr" AS "all_types.timestamp_ptr",
"allTypesSubQuery"."all_types.timestamp" AS "all_types.timestamp",
"allTypesSubQuery"."all_types.date_ptr" AS "all_types.date_ptr",
"allTypesSubQuery"."all_types.date" AS "all_types.date",
"allTypesSubQuery"."all_types.timez_ptr" AS "all_types.timez_ptr",
"allTypesSubQuery"."all_types.timez" AS "all_types.timez",
"allTypesSubQuery"."all_types.time_ptr" AS "all_types.time_ptr",
"allTypesSubQuery"."all_types.time" AS "all_types.time",
"allTypesSubQuery"."all_types.interval_ptr" AS "all_types.interval_ptr",
"allTypesSubQuery"."all_types.interval" AS "all_types.interval",
"allTypesSubQuery"."all_types.boolean_ptr" AS "all_types.boolean_ptr",
"allTypesSubQuery"."all_types.boolean" AS "all_types.boolean",
"allTypesSubQuery"."all_types.point_ptr" AS "all_types.point_ptr",
"allTypesSubQuery"."all_types.bit_ptr" AS "all_types.bit_ptr",
"allTypesSubQuery"."all_types.bit" AS "all_types.bit",
"allTypesSubQuery"."all_types.bit_varying_ptr" AS "all_types.bit_varying_ptr",
"allTypesSubQuery"."all_types.bit_varying" AS "all_types.bit_varying",
"allTypesSubQuery"."all_types.tsvector_ptr" AS "all_types.tsvector_ptr",
"allTypesSubQuery"."all_types.tsvector" AS "all_types.tsvector",
"allTypesSubQuery"."all_types.uuid_ptr" AS "all_types.uuid_ptr",
"allTypesSubQuery"."all_types.uuid" AS "all_types.uuid",
"allTypesSubQuery"."all_types.xml_ptr" AS "all_types.xml_ptr",
"allTypesSubQuery"."all_types.xml" AS "all_types.xml",
"allTypesSubQuery"."all_types.json_ptr" AS "all_types.json_ptr",
"allTypesSubQuery"."all_types.json" AS "all_types.json",
"allTypesSubQuery"."all_types.jsonb_ptr" AS "all_types.jsonb_ptr",
"allTypesSubQuery"."all_types.jsonb" AS "all_types.jsonb",
"allTypesSubQuery"."all_types.integer_array_ptr" AS "all_types.integer_array_ptr",
"allTypesSubQuery"."all_types.integer_array" AS "all_types.integer_array",
"allTypesSubQuery"."all_types.text_array_ptr" AS "all_types.text_array_ptr",
"allTypesSubQuery"."all_types.text_array" AS "all_types.text_array",
"allTypesSubQuery"."all_types.jsonb_array" AS "all_types.jsonb_array",
"allTypesSubQuery"."all_types.text_multi_dim_array_ptr" AS "all_types.text_multi_dim_array_ptr",
"allTypesSubQuery"."all_types.text_multi_dim_array" AS "all_types.text_multi_dim_array"
FROM (
SELECT all_types.small_int_ptr AS "all_types.small_int_ptr",
all_types.small_int AS "all_types.small_int",
all_types.integer_ptr AS "all_types.integer_ptr",
all_types.integer AS "all_types.integer",
all_types.big_int_ptr AS "all_types.big_int_ptr",
all_types.big_int AS "all_types.big_int",
all_types.decimal_ptr AS "all_types.decimal_ptr",
all_types.decimal AS "all_types.decimal",
all_types.numeric_ptr AS "all_types.numeric_ptr",
all_types.numeric AS "all_types.numeric",
all_types.real_ptr AS "all_types.real_ptr",
all_types.real AS "all_types.real",
all_types.double_precision_ptr AS "all_types.double_precision_ptr",
all_types.double_precision AS "all_types.double_precision",
all_types.smallserial AS "all_types.smallserial",
all_types.serial AS "all_types.serial",
all_types.bigserial AS "all_types.bigserial",
all_types.var_char_ptr AS "all_types.var_char_ptr",
all_types.var_char AS "all_types.var_char",
all_types.char_ptr AS "all_types.char_ptr",
all_types.char AS "all_types.char",
all_types.text_ptr AS "all_types.text_ptr",
all_types.text AS "all_types.text",
all_types.bytea_ptr AS "all_types.bytea_ptr",
all_types.bytea AS "all_types.bytea",
all_types.timestampz_ptr AS "all_types.timestampz_ptr",
all_types.timestampz AS "all_types.timestampz",
all_types.timestamp_ptr AS "all_types.timestamp_ptr",
all_types.timestamp AS "all_types.timestamp",
all_types.date_ptr AS "all_types.date_ptr",
all_types.date AS "all_types.date",
all_types.timez_ptr AS "all_types.timez_ptr",
all_types.timez AS "all_types.timez",
all_types.time_ptr AS "all_types.time_ptr",
all_types.time AS "all_types.time",
all_types.interval_ptr AS "all_types.interval_ptr",
all_types.interval AS "all_types.interval",
all_types.boolean_ptr AS "all_types.boolean_ptr",
all_types.boolean AS "all_types.boolean",
all_types.point_ptr AS "all_types.point_ptr",
all_types.bit_ptr AS "all_types.bit_ptr",
all_types.bit AS "all_types.bit",
all_types.bit_varying_ptr AS "all_types.bit_varying_ptr",
all_types.bit_varying AS "all_types.bit_varying",
all_types.tsvector_ptr AS "all_types.tsvector_ptr",
all_types.tsvector AS "all_types.tsvector",
all_types.uuid_ptr AS "all_types.uuid_ptr",
all_types.uuid AS "all_types.uuid",
all_types.xml_ptr AS "all_types.xml_ptr",
all_types.xml AS "all_types.xml",
all_types.json_ptr AS "all_types.json_ptr",
all_types.json AS "all_types.json",
all_types.jsonb_ptr AS "all_types.jsonb_ptr",
all_types.jsonb AS "all_types.jsonb",
all_types.integer_array_ptr AS "all_types.integer_array_ptr",
all_types.integer_array AS "all_types.integer_array",
all_types.text_array_ptr AS "all_types.text_array_ptr",
all_types.text_array AS "all_types.text_array",
all_types.jsonb_array AS "all_types.jsonb_array",
all_types.text_multi_dim_array_ptr AS "all_types.text_multi_dim_array_ptr",
all_types.text_multi_dim_array AS "all_types.text_multi_dim_array"
FROM test_sample.all_types
) AS "allTypesSubQuery"
LIMIT 2;
`)
dest := []model.AllTypes{}
err := mainQuery.Query(db, &dest)
assert.NilError(t, err)
assert.Equal(t, len(dest), 2)
}
func TestExpressionOperators(t *testing.T) { func TestExpressionOperators(t *testing.T) {
query := AllTypes.SELECT( query := AllTypes.SELECT(
AllTypes.Integer.IS_NULL().AS("result.is_null"), AllTypes.Integer.IS_NULL().AS("result.is_null"),
@ -671,7 +817,20 @@ func TestInterval(t *testing.T) {
INTERVALd(1*time.Hour), INTERVALd(1*time.Hour),
INTERVALd(24*time.Hour), INTERVALd(24*time.Hour),
INTERVALd(24*time.Hour+2*time.Hour+3*time.Minute+4*time.Second+5*time.Microsecond), INTERVALd(24*time.Hour+2*time.Hour+3*time.Minute+4*time.Second+5*time.Microsecond),
)
AllTypes.Interval.EQ(INTERVAL(2, HOUR, 20, MINUTE)).EQ(Bool(true)),
AllTypes.IntervalPtr.NOT_EQ(INTERVAL(2, HOUR, 20, MINUTE)).EQ(Bool(false)),
AllTypes.Interval.IS_DISTINCT_FROM(INTERVAL(2, HOUR, 20, MINUTE)).EQ(AllTypes.Boolean),
AllTypes.IntervalPtr.IS_NOT_DISTINCT_FROM(INTERVALd(10*time.Microsecond)).EQ(AllTypes.Boolean),
AllTypes.Interval.LT(AllTypes.IntervalPtr).EQ(AllTypes.BooleanPtr),
AllTypes.Interval.LT_EQ(AllTypes.IntervalPtr).EQ(AllTypes.BooleanPtr),
AllTypes.Interval.GT(AllTypes.IntervalPtr).EQ(AllTypes.BooleanPtr),
AllTypes.Interval.GT_EQ(AllTypes.IntervalPtr).EQ(AllTypes.BooleanPtr),
AllTypes.Interval.ADD(AllTypes.IntervalPtr).EQ(INTERVALd(17*time.Second)),
AllTypes.Interval.SUB(AllTypes.IntervalPtr).EQ(INTERVAL(100, MICROSECOND)),
AllTypes.IntervalPtr.MUL(Int(11)).EQ(AllTypes.Interval),
AllTypes.IntervalPtr.DIV(Float(22.222)).EQ(AllTypes.IntervalPtr),
).FROM(AllTypes)
//fmt.Println(stmt.DebugSql()) //fmt.Println(stmt.DebugSql())

View file

@ -15,7 +15,6 @@ import (
) )
func TestGeneratedModel(t *testing.T) { func TestGeneratedModel(t *testing.T) {
actor := model.Actor{} actor := model.Actor{}
assert.Equal(t, reflect.TypeOf(actor.ActorID).String(), "int32") assert.Equal(t, reflect.TypeOf(actor.ActorID).String(), "int32")
@ -275,3 +274,345 @@ func newActorInfoTable() *ActorInfoTable {
} }
} }
` `
func TestGeneratedAllTypesSQLBuilderFiles(t *testing.T) {
enumDir := testRoot + ".gentestdata/jetdb/test_sample/enum/"
modelDir := testRoot + ".gentestdata/jetdb/test_sample/model/"
tableDir := testRoot + ".gentestdata/jetdb/test_sample/table/"
enumFiles, err := ioutil.ReadDir(enumDir)
assert.NilError(t, err)
testutils.AssertFileNamesEqual(t, enumFiles, "mood.go")
testutils.AssertFileContent(t, enumDir+"mood.go", "\npackage enum", moodEnumContent)
modelFiles, err := ioutil.ReadDir(modelDir)
assert.NilError(t, err)
testutils.AssertFileNamesEqual(t, modelFiles, "all_types.go", "all_types_view.go", "employee.go", "link.go",
"mood.go", "person.go", "person_phone.go", "weird_names_table.go")
testutils.AssertFileContent(t, modelDir+"all_types.go", "\npackage model", allTypesModelContent)
tableFiles, err := ioutil.ReadDir(tableDir)
assert.NilError(t, err)
testutils.AssertFileNamesEqual(t, tableFiles, "all_types.go", "employee.go", "link.go",
"person.go", "person_phone.go", "weird_names_table.go")
testutils.AssertFileContent(t, tableDir+"all_types.go", "\npackage table", allTypesTableContent)
}
var moodEnumContent = `
package enum
import "github.com/go-jet/jet/postgres"
var Mood = &struct {
Sad postgres.StringExpression
Ok postgres.StringExpression
Happy postgres.StringExpression
}{
Sad: postgres.NewEnumValue("sad"),
Ok: postgres.NewEnumValue("ok"),
Happy: postgres.NewEnumValue("happy"),
}
`
var allTypesModelContent = `
package model
import (
"github.com/google/uuid"
"time"
)
type AllTypes struct {
SmallIntPtr *int16
SmallInt int16
IntegerPtr *int32
Integer int32
BigIntPtr *int64
BigInt int64
DecimalPtr *float64
Decimal float64
NumericPtr *float64
Numeric float64
RealPtr *float32
Real float32
DoublePrecisionPtr *float64
DoublePrecision float64
Smallserial int16
Serial int32
Bigserial int64
VarCharPtr *string
VarChar string
CharPtr *string
Char string
TextPtr *string
Text string
ByteaPtr *[]byte
Bytea []byte
TimestampzPtr *time.Time
Timestampz time.Time
TimestampPtr *time.Time
Timestamp time.Time
DatePtr *time.Time
Date time.Time
TimezPtr *time.Time
Timez time.Time
TimePtr *time.Time
Time time.Time
IntervalPtr *string
Interval string
BooleanPtr *bool
Boolean bool
PointPtr *string
BitPtr *string
Bit string
BitVaryingPtr *string
BitVarying string
TsvectorPtr *string
Tsvector string
UUIDPtr *uuid.UUID
UUID uuid.UUID
XMLPtr *string
XML string
JSONPtr *string
JSON string
JsonbPtr *string
Jsonb string
IntegerArrayPtr *string
IntegerArray string
TextArrayPtr *string
TextArray string
JsonbArray string
TextMultiDimArrayPtr *string
TextMultiDimArray string
}
`
var allTypesTableContent = `
package table
import (
"github.com/go-jet/jet/postgres"
)
var AllTypes = newAllTypesTable()
type AllTypesTable struct {
postgres.Table
//Columns
SmallIntPtr postgres.ColumnInteger
SmallInt postgres.ColumnInteger
IntegerPtr postgres.ColumnInteger
Integer postgres.ColumnInteger
BigIntPtr postgres.ColumnInteger
BigInt postgres.ColumnInteger
DecimalPtr postgres.ColumnFloat
Decimal postgres.ColumnFloat
NumericPtr postgres.ColumnFloat
Numeric postgres.ColumnFloat
RealPtr postgres.ColumnFloat
Real postgres.ColumnFloat
DoublePrecisionPtr postgres.ColumnFloat
DoublePrecision postgres.ColumnFloat
Smallserial postgres.ColumnInteger
Serial postgres.ColumnInteger
Bigserial postgres.ColumnInteger
VarCharPtr postgres.ColumnString
VarChar postgres.ColumnString
CharPtr postgres.ColumnString
Char postgres.ColumnString
TextPtr postgres.ColumnString
Text postgres.ColumnString
ByteaPtr postgres.ColumnString
Bytea postgres.ColumnString
TimestampzPtr postgres.ColumnTimestampz
Timestampz postgres.ColumnTimestampz
TimestampPtr postgres.ColumnTimestamp
Timestamp postgres.ColumnTimestamp
DatePtr postgres.ColumnDate
Date postgres.ColumnDate
TimezPtr postgres.ColumnTimez
Timez postgres.ColumnTimez
TimePtr postgres.ColumnTime
Time postgres.ColumnTime
IntervalPtr postgres.ColumnInterval
Interval postgres.ColumnInterval
BooleanPtr postgres.ColumnBool
Boolean postgres.ColumnBool
PointPtr postgres.ColumnString
BitPtr postgres.ColumnString
Bit postgres.ColumnString
BitVaryingPtr postgres.ColumnString
BitVarying postgres.ColumnString
TsvectorPtr postgres.ColumnString
Tsvector postgres.ColumnString
UUIDPtr postgres.ColumnString
UUID postgres.ColumnString
XMLPtr postgres.ColumnString
XML postgres.ColumnString
JSONPtr postgres.ColumnString
JSON postgres.ColumnString
JsonbPtr postgres.ColumnString
Jsonb postgres.ColumnString
IntegerArrayPtr postgres.ColumnString
IntegerArray postgres.ColumnString
TextArrayPtr postgres.ColumnString
TextArray postgres.ColumnString
JsonbArray postgres.ColumnString
TextMultiDimArrayPtr postgres.ColumnString
TextMultiDimArray postgres.ColumnString
AllColumns postgres.ColumnList
MutableColumns postgres.ColumnList
}
// creates new AllTypesTable with assigned alias
func (a *AllTypesTable) AS(alias string) *AllTypesTable {
aliasTable := newAllTypesTable()
aliasTable.Table.AS(alias)
return aliasTable
}
func newAllTypesTable() *AllTypesTable {
var (
SmallIntPtrColumn = postgres.IntegerColumn("small_int_ptr")
SmallIntColumn = postgres.IntegerColumn("small_int")
IntegerPtrColumn = postgres.IntegerColumn("integer_ptr")
IntegerColumn = postgres.IntegerColumn("integer")
BigIntPtrColumn = postgres.IntegerColumn("big_int_ptr")
BigIntColumn = postgres.IntegerColumn("big_int")
DecimalPtrColumn = postgres.FloatColumn("decimal_ptr")
DecimalColumn = postgres.FloatColumn("decimal")
NumericPtrColumn = postgres.FloatColumn("numeric_ptr")
NumericColumn = postgres.FloatColumn("numeric")
RealPtrColumn = postgres.FloatColumn("real_ptr")
RealColumn = postgres.FloatColumn("real")
DoublePrecisionPtrColumn = postgres.FloatColumn("double_precision_ptr")
DoublePrecisionColumn = postgres.FloatColumn("double_precision")
SmallserialColumn = postgres.IntegerColumn("smallserial")
SerialColumn = postgres.IntegerColumn("serial")
BigserialColumn = postgres.IntegerColumn("bigserial")
VarCharPtrColumn = postgres.StringColumn("var_char_ptr")
VarCharColumn = postgres.StringColumn("var_char")
CharPtrColumn = postgres.StringColumn("char_ptr")
CharColumn = postgres.StringColumn("char")
TextPtrColumn = postgres.StringColumn("text_ptr")
TextColumn = postgres.StringColumn("text")
ByteaPtrColumn = postgres.StringColumn("bytea_ptr")
ByteaColumn = postgres.StringColumn("bytea")
TimestampzPtrColumn = postgres.TimestampzColumn("timestampz_ptr")
TimestampzColumn = postgres.TimestampzColumn("timestampz")
TimestampPtrColumn = postgres.TimestampColumn("timestamp_ptr")
TimestampColumn = postgres.TimestampColumn("timestamp")
DatePtrColumn = postgres.DateColumn("date_ptr")
DateColumn = postgres.DateColumn("date")
TimezPtrColumn = postgres.TimezColumn("timez_ptr")
TimezColumn = postgres.TimezColumn("timez")
TimePtrColumn = postgres.TimeColumn("time_ptr")
TimeColumn = postgres.TimeColumn("time")
IntervalPtrColumn = postgres.IntervalColumn("interval_ptr")
IntervalColumn = postgres.IntervalColumn("interval")
BooleanPtrColumn = postgres.BoolColumn("boolean_ptr")
BooleanColumn = postgres.BoolColumn("boolean")
PointPtrColumn = postgres.StringColumn("point_ptr")
BitPtrColumn = postgres.StringColumn("bit_ptr")
BitColumn = postgres.StringColumn("bit")
BitVaryingPtrColumn = postgres.StringColumn("bit_varying_ptr")
BitVaryingColumn = postgres.StringColumn("bit_varying")
TsvectorPtrColumn = postgres.StringColumn("tsvector_ptr")
TsvectorColumn = postgres.StringColumn("tsvector")
UUIDPtrColumn = postgres.StringColumn("uuid_ptr")
UUIDColumn = postgres.StringColumn("uuid")
XMLPtrColumn = postgres.StringColumn("xml_ptr")
XMLColumn = postgres.StringColumn("xml")
JSONPtrColumn = postgres.StringColumn("json_ptr")
JSONColumn = postgres.StringColumn("json")
JsonbPtrColumn = postgres.StringColumn("jsonb_ptr")
JsonbColumn = postgres.StringColumn("jsonb")
IntegerArrayPtrColumn = postgres.StringColumn("integer_array_ptr")
IntegerArrayColumn = postgres.StringColumn("integer_array")
TextArrayPtrColumn = postgres.StringColumn("text_array_ptr")
TextArrayColumn = postgres.StringColumn("text_array")
JsonbArrayColumn = postgres.StringColumn("jsonb_array")
TextMultiDimArrayPtrColumn = postgres.StringColumn("text_multi_dim_array_ptr")
TextMultiDimArrayColumn = postgres.StringColumn("text_multi_dim_array")
)
return &AllTypesTable{
Table: postgres.NewTable("test_sample", "all_types", SmallIntPtrColumn, SmallIntColumn, IntegerPtrColumn, IntegerColumn, BigIntPtrColumn, BigIntColumn, DecimalPtrColumn, DecimalColumn, NumericPtrColumn, NumericColumn, RealPtrColumn, RealColumn, DoublePrecisionPtrColumn, DoublePrecisionColumn, SmallserialColumn, SerialColumn, BigserialColumn, VarCharPtrColumn, VarCharColumn, CharPtrColumn, CharColumn, TextPtrColumn, TextColumn, ByteaPtrColumn, ByteaColumn, TimestampzPtrColumn, TimestampzColumn, TimestampPtrColumn, TimestampColumn, DatePtrColumn, DateColumn, TimezPtrColumn, TimezColumn, TimePtrColumn, TimeColumn, IntervalPtrColumn, IntervalColumn, BooleanPtrColumn, BooleanColumn, PointPtrColumn, BitPtrColumn, BitColumn, BitVaryingPtrColumn, BitVaryingColumn, TsvectorPtrColumn, TsvectorColumn, UUIDPtrColumn, UUIDColumn, XMLPtrColumn, XMLColumn, JSONPtrColumn, JSONColumn, JsonbPtrColumn, JsonbColumn, IntegerArrayPtrColumn, IntegerArrayColumn, TextArrayPtrColumn, TextArrayColumn, JsonbArrayColumn, TextMultiDimArrayPtrColumn, TextMultiDimArrayColumn),
//Columns
SmallIntPtr: SmallIntPtrColumn,
SmallInt: SmallIntColumn,
IntegerPtr: IntegerPtrColumn,
Integer: IntegerColumn,
BigIntPtr: BigIntPtrColumn,
BigInt: BigIntColumn,
DecimalPtr: DecimalPtrColumn,
Decimal: DecimalColumn,
NumericPtr: NumericPtrColumn,
Numeric: NumericColumn,
RealPtr: RealPtrColumn,
Real: RealColumn,
DoublePrecisionPtr: DoublePrecisionPtrColumn,
DoublePrecision: DoublePrecisionColumn,
Smallserial: SmallserialColumn,
Serial: SerialColumn,
Bigserial: BigserialColumn,
VarCharPtr: VarCharPtrColumn,
VarChar: VarCharColumn,
CharPtr: CharPtrColumn,
Char: CharColumn,
TextPtr: TextPtrColumn,
Text: TextColumn,
ByteaPtr: ByteaPtrColumn,
Bytea: ByteaColumn,
TimestampzPtr: TimestampzPtrColumn,
Timestampz: TimestampzColumn,
TimestampPtr: TimestampPtrColumn,
Timestamp: TimestampColumn,
DatePtr: DatePtrColumn,
Date: DateColumn,
TimezPtr: TimezPtrColumn,
Timez: TimezColumn,
TimePtr: TimePtrColumn,
Time: TimeColumn,
IntervalPtr: IntervalPtrColumn,
Interval: IntervalColumn,
BooleanPtr: BooleanPtrColumn,
Boolean: BooleanColumn,
PointPtr: PointPtrColumn,
BitPtr: BitPtrColumn,
Bit: BitColumn,
BitVaryingPtr: BitVaryingPtrColumn,
BitVarying: BitVaryingColumn,
TsvectorPtr: TsvectorPtrColumn,
Tsvector: TsvectorColumn,
UUIDPtr: UUIDPtrColumn,
UUID: UUIDColumn,
XMLPtr: XMLPtrColumn,
XML: XMLColumn,
JSONPtr: JSONPtrColumn,
JSON: JSONColumn,
JsonbPtr: JsonbPtrColumn,
Jsonb: JsonbColumn,
IntegerArrayPtr: IntegerArrayPtrColumn,
IntegerArray: IntegerArrayColumn,
TextArrayPtr: TextArrayPtrColumn,
TextArray: TextArrayColumn,
JsonbArray: JsonbArrayColumn,
TextMultiDimArrayPtr: TextMultiDimArrayPtrColumn,
TextMultiDimArray: TextMultiDimArrayColumn,
AllColumns: postgres.ColumnList{SmallIntPtrColumn, SmallIntColumn, IntegerPtrColumn, IntegerColumn, BigIntPtrColumn, BigIntColumn, DecimalPtrColumn, DecimalColumn, NumericPtrColumn, NumericColumn, RealPtrColumn, RealColumn, DoublePrecisionPtrColumn, DoublePrecisionColumn, SmallserialColumn, SerialColumn, BigserialColumn, VarCharPtrColumn, VarCharColumn, CharPtrColumn, CharColumn, TextPtrColumn, TextColumn, ByteaPtrColumn, ByteaColumn, TimestampzPtrColumn, TimestampzColumn, TimestampPtrColumn, TimestampColumn, DatePtrColumn, DateColumn, TimezPtrColumn, TimezColumn, TimePtrColumn, TimeColumn, IntervalPtrColumn, IntervalColumn, BooleanPtrColumn, BooleanColumn, PointPtrColumn, BitPtrColumn, BitColumn, BitVaryingPtrColumn, BitVaryingColumn, TsvectorPtrColumn, TsvectorColumn, UUIDPtrColumn, UUIDColumn, XMLPtrColumn, XMLColumn, JSONPtrColumn, JSONColumn, JsonbPtrColumn, JsonbColumn, IntegerArrayPtrColumn, IntegerArrayColumn, TextArrayPtrColumn, TextArrayColumn, JsonbArrayColumn, TextMultiDimArrayPtrColumn, TextMultiDimArrayColumn},
MutableColumns: postgres.ColumnList{SmallIntPtrColumn, SmallIntColumn, IntegerPtrColumn, IntegerColumn, BigIntPtrColumn, BigIntColumn, DecimalPtrColumn, DecimalColumn, NumericPtrColumn, NumericColumn, RealPtrColumn, RealColumn, DoublePrecisionPtrColumn, DoublePrecisionColumn, SmallserialColumn, SerialColumn, BigserialColumn, VarCharPtrColumn, VarCharColumn, CharPtrColumn, CharColumn, TextPtrColumn, TextColumn, ByteaPtrColumn, ByteaColumn, TimestampzPtrColumn, TimestampzColumn, TimestampPtrColumn, TimestampColumn, DatePtrColumn, DateColumn, TimezPtrColumn, TimezColumn, TimePtrColumn, TimeColumn, IntervalPtrColumn, IntervalColumn, BooleanPtrColumn, BooleanColumn, PointPtrColumn, BitPtrColumn, BitColumn, BitVaryingPtrColumn, BitVaryingColumn, TsvectorPtrColumn, TsvectorColumn, UUIDPtrColumn, UUIDColumn, XMLPtrColumn, XMLColumn, JSONPtrColumn, JSONColumn, JsonbPtrColumn, JsonbColumn, IntegerArrayPtrColumn, IntegerArrayColumn, TextArrayPtrColumn, TextArrayColumn, JsonbArrayColumn, TextMultiDimArrayPtrColumn, TextMultiDimArrayColumn},
}
}
`

View file

@ -6,14 +6,19 @@ import (
_ "github.com/lib/pq" _ "github.com/lib/pq"
"github.com/pkg/profile" "github.com/pkg/profile"
"os" "os"
"os/exec"
"strings"
"testing" "testing"
) )
var db *sql.DB var db *sql.DB
var testRoot string
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
defer profile.Start().Stop() defer profile.Start().Stop()
setTestRoot()
var err error var err error
db, err = sql.Open("postgres", dbconfig.PostgresConnectString) db, err = sql.Open("postgres", dbconfig.PostgresConnectString)
if err != nil { if err != nil {
@ -25,3 +30,13 @@ func TestMain(m *testing.M) {
os.Exit(ret) os.Exit(ret)
} }
func setTestRoot() {
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
byteArr, err := cmd.Output()
if err != nil {
panic(err)
}
testRoot = strings.TrimSpace(string(byteArr)) + "/tests/"
}