Model refactor cleanup.

This commit is contained in:
zer0sub 2019-05-07 19:06:21 +02:00
parent c9561ecc37
commit f016a93d78
33 changed files with 536 additions and 618 deletions

View file

@ -1,20 +1,20 @@
package sqlbuilder
type Alias struct {
expression Expression
expression expression
alias string
}
func NewAlias(expression Expression, alias string) *Alias {
func NewAlias(expression expression, alias string) *Alias {
return &Alias{
expression: expression,
alias: alias,
}
}
func (a *Alias) SerializeForProjection(out *queryData) error {
func (a *Alias) serializeForProjection(out *queryData) error {
err := a.expression.Serialize(out)
err := a.expression.serialize(out)
if err != nil {
return err

View file

@ -1,51 +1,51 @@
package sqlbuilder
type BoolExpression interface {
Expression
type boolExpression interface {
expression
Eq(expression BoolExpression) BoolExpression
NotEq(expression BoolExpression) BoolExpression
GtEq(rhs Expression) BoolExpression
LtEq(rhs Expression) BoolExpression
Eq(expression boolExpression) boolExpression
NotEq(expression boolExpression) boolExpression
GtEq(rhs expression) boolExpression
LtEq(rhs expression) boolExpression
AND(expression BoolExpression) BoolExpression
OR(expression BoolExpression) BoolExpression
IS_TRUE() BoolExpression
IS_FALSE() BoolExpression
AND(expression boolExpression) boolExpression
OR(expression boolExpression) boolExpression
IS_TRUE() boolExpression
IS_FALSE() boolExpression
}
type boolInterfaceImpl struct {
parent BoolExpression
parent boolExpression
}
func (b *boolInterfaceImpl) Eq(expression BoolExpression) BoolExpression {
func (b *boolInterfaceImpl) Eq(expression boolExpression) boolExpression {
return Eq(b.parent, expression)
}
func (b *boolInterfaceImpl) NotEq(expression BoolExpression) BoolExpression {
func (b *boolInterfaceImpl) NotEq(expression boolExpression) boolExpression {
return NotEq(b.parent, expression)
}
func (b *boolInterfaceImpl) GtEq(rhs Expression) BoolExpression {
func (b *boolInterfaceImpl) GtEq(rhs expression) boolExpression {
return GtEq(b.parent, rhs)
}
func (b *boolInterfaceImpl) LtEq(rhs Expression) BoolExpression {
func (b *boolInterfaceImpl) LtEq(rhs expression) boolExpression {
return LtEq(b.parent, rhs)
}
func (b *boolInterfaceImpl) AND(expression BoolExpression) BoolExpression {
func (b *boolInterfaceImpl) AND(expression boolExpression) boolExpression {
return And(b.parent, expression)
}
func (b *boolInterfaceImpl) OR(expression BoolExpression) BoolExpression {
func (b *boolInterfaceImpl) OR(expression boolExpression) boolExpression {
return Or(b.parent, expression)
}
func (b *boolInterfaceImpl) IS_TRUE() BoolExpression {
func (b *boolInterfaceImpl) IS_TRUE() boolExpression {
return IsTrue(b.parent)
}
func (b *boolInterfaceImpl) IS_FALSE() BoolExpression {
func (b *boolInterfaceImpl) IS_FALSE() boolExpression {
return nil
}
@ -55,7 +55,7 @@ type boolLiteralExpression struct {
literalExpression
}
func newBoolLiteralExpression(value bool) BoolExpression {
func newBoolLiteralExpression(value bool) boolExpression {
boolLiteralExpression := boolLiteralExpression{}
boolLiteralExpression.literalExpression = *Literal(value)
@ -72,7 +72,7 @@ type binaryBoolExpression struct {
binaryExpression
}
func newBinaryBoolExpression(lhs, rhs Expression, operator string) BoolExpression {
func newBinaryBoolExpression(lhs, rhs expression, operator string) boolExpression {
boolExpression := binaryBoolExpression{}
boolExpression.binaryExpression = newBinaryExpression(lhs, rhs, operator)
@ -90,7 +90,7 @@ type prefixBoolExpression struct {
prefixExpression
}
func newPrefixBoolExpression(expression Expression, operator string) BoolExpression {
func newPrefixBoolExpression(expression expression, operator string) boolExpression {
boolExpression := prefixBoolExpression{}
boolExpression.prefixExpression = newPrefixExpression(expression, operator)
@ -100,100 +100,100 @@ func newPrefixBoolExpression(expression Expression, operator string) BoolExpress
return &boolExpression
}
func EXISTS(subQuery SelectStatement) BoolExpression {
func EXISTS(subQuery selectStatement) boolExpression {
return newPrefixBoolExpression(subQuery, "EXISTS")
}
// Returns a representation of "a=b"
func Eq(lhs, rhs Expression) BoolExpression {
func Eq(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "=")
}
// Returns a representation of "a=b", where b is a literal
func EqL(lhs Expression, val interface{}) BoolExpression {
func EqL(lhs expression, val interface{}) boolExpression {
return Eq(lhs, Literal(val))
}
// Returns a representation of "a!=b"
func NotEq(lhs, rhs Expression) BoolExpression {
func NotEq(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "!=")
}
// Returns a representation of "a!=b", where b is a literal
func NeqL(lhs Expression, val interface{}) BoolExpression {
func NeqL(lhs expression, val interface{}) boolExpression {
return NotEq(lhs, Literal(val))
}
// Returns a representation of "a<b"
func Lt(lhs Expression, rhs Expression) BoolExpression {
func Lt(lhs expression, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "<")
}
// Returns a representation of "a<b", where b is a literal
func LtL(lhs Expression, val interface{}) BoolExpression {
func LtL(lhs expression, val interface{}) boolExpression {
return Lt(lhs, Literal(val))
}
// Returns a representation of "a<=b"
func LtEq(lhs, rhs Expression) BoolExpression {
func LtEq(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "<=")
}
// Returns a representation of "a<=b", where b is a literal
func LteL(lhs Expression, val interface{}) BoolExpression {
func LteL(lhs expression, val interface{}) boolExpression {
return LtEq(lhs, Literal(val))
}
// Returns a representation of "a>b"
func Gt(lhs, rhs Expression) BoolExpression {
func Gt(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, ">")
}
// Returns a representation of "a>b", where b is a literal
func GtL(lhs Expression, val interface{}) BoolExpression {
func GtL(lhs expression, val interface{}) boolExpression {
return Gt(lhs, Literal(val))
}
// Returns a representation of "a>=b"
func GtEq(lhs, rhs Expression) BoolExpression {
func GtEq(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, ">=")
}
// Returns a representation of "a>=b", where b is a literal
func GteL(lhs Expression, val interface{}) BoolExpression {
func GteL(lhs expression, val interface{}) boolExpression {
return GtEq(lhs, Literal(val))
}
// Returns a representation of "not expr"
func Not(expr BoolExpression) BoolExpression {
func Not(expr boolExpression) boolExpression {
return newPrefixBoolExpression(expr, "NOT")
}
func IsTrue(expr BoolExpression) BoolExpression {
func IsTrue(expr boolExpression) boolExpression {
return newPrefixBoolExpression(expr, "IS TRUE")
}
func And(lhs, rhs Expression) BoolExpression {
func And(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "AND")
}
// Returns a representation of "c[0] OR ... OR c[n-1]" for c in clauses
func Or(lhs, rhs Expression) BoolExpression {
func Or(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "OR")
}
func Like(lhs, rhs Expression) BoolExpression {
func Like(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "LIKE")
}
func LikeL(lhs Expression, val string) BoolExpression {
func LikeL(lhs expression, val string) boolExpression {
return Like(lhs, Literal(val))
}
func Regexp(lhs, rhs Expression) BoolExpression {
func Regexp(lhs, rhs expression) boolExpression {
return newBinaryBoolExpression(lhs, rhs, "REGEXP")
}
func RegexpL(lhs Expression, val string) BoolExpression {
func RegexpL(lhs expression, val string) boolExpression {
return Regexp(lhs, Literal(val))
}

View file

@ -9,7 +9,7 @@ func TestBinaryExpression(t *testing.T) {
boolExpression := Eq(Literal(2), Literal(3))
out := queryData{}
err := boolExpression.Serialize(&out)
err := boolExpression.serialize(&out)
assert.NilError(t, err)
@ -20,7 +20,7 @@ func TestBinaryExpression(t *testing.T) {
alias := boolExpression.AS("alias_eq_expression")
out := queryData{}
err := alias.SerializeForProjection(&out)
err := alias.serializeForProjection(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `$1 = $2 AS "alias_eq_expression"`)
@ -30,7 +30,7 @@ func TestBinaryExpression(t *testing.T) {
exp := boolExpression.AND(Eq(Literal(4), Literal(5)))
out := queryData{}
err := exp.Serialize(&out)
err := exp.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `($1 = $2 AND $3 = $4)`)
@ -40,7 +40,7 @@ func TestBinaryExpression(t *testing.T) {
exp := boolExpression.OR(Eq(Literal(4), Literal(5)))
out := queryData{}
err := exp.Serialize(&out)
err := exp.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `($1 = $2 OR $3 = $4)`)
@ -51,7 +51,7 @@ func TestUnaryExpression(t *testing.T) {
notExpression := Not(Eq(Literal(2), Literal(1)))
out := queryData{}
err := notExpression.Serialize(&out)
err := notExpression.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "NOT $1 = $2")
@ -60,7 +60,7 @@ func TestUnaryExpression(t *testing.T) {
alias := notExpression.AS("alias_not_expression")
out := queryData{}
err := alias.SerializeForProjection(&out)
err := alias.serializeForProjection(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `NOT $1 = $2 AS "alias_not_expression"`)
@ -70,7 +70,7 @@ func TestUnaryExpression(t *testing.T) {
exp := notExpression.AND(Eq(Literal(4), Literal(5)))
out := queryData{}
err := exp.Serialize(&out)
err := exp.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `(NOT $1 = $2 AND $3 = $4)`)
@ -81,7 +81,7 @@ func TestUnaryIsTrueExpression(t *testing.T) {
notExpression := IsTrue(Eq(Literal(2), Literal(1)))
out := queryData{}
err := notExpression.Serialize(&out)
err := notExpression.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "IS TRUE $1 = $2")
@ -90,7 +90,7 @@ func TestUnaryIsTrueExpression(t *testing.T) {
exp := notExpression.AND(Eq(Literal(4), Literal(5)))
out := queryData{}
err := exp.Serialize(&out)
err := exp.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `(IS TRUE $1 = $2 AND $3 = $4)`)
@ -101,7 +101,7 @@ func TestBoolLiteral(t *testing.T) {
literal := newBoolLiteralExpression(true)
out := queryData{}
err := literal.Serialize(&out)
err := literal.serialize(&out)
assert.NilError(t, err)
@ -116,7 +116,7 @@ func TestExists(t *testing.T) {
)
out := queryData{}
err := query.Serialize(&out)
err := query.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "EXISTS (SELECT $1 FROM db.table2 WHERE table1.col1 = table2.col3)")
@ -126,7 +126,7 @@ func TestIn(t *testing.T) {
query := Literal(1.11).IN(table1.SELECT(table1Col1))
out := queryData{}
err := query.Serialize(&out)
err := query.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `$1 IN (SELECT table1.col1 AS "table1.col1" FROM db.table1)`)
@ -134,7 +134,7 @@ func TestIn(t *testing.T) {
query2 := ROW(Literal(12), table1Col1).IN(table2.SELECT(table2Col3, table3Col1))
out = queryData{}
err = query2.Serialize(&out)
err = query2.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `(ROW($1, table1.col1) IN (SELECT table2.col3 AS "table2.col3", table3.col1 AS "table3.col1" FROM db.table2))`)

View file

@ -6,14 +6,8 @@ import (
"strconv"
)
type serializeOption int
const (
FOR_PROJECTION = iota
)
type Clause interface {
Serialize(out *queryData, options ...serializeOption) error
type clause interface {
serialize(out *queryData) error
}
type queryData struct {
@ -40,34 +34,34 @@ const (
having_clause
)
func (q *queryData) WriteProjection(projections []Projection) error {
func (q *queryData) WriteProjection(projections []projection) error {
q.clauseType = projection_clause
return serializeProjectionList(projections, q)
}
func (q *queryData) WriteWhere(where Expression) error {
func (q *queryData) WriteWhere(where expression) error {
q.clauseType = where_clause
q.WriteString(" WHERE ")
return where.Serialize(q)
return where.serialize(q)
}
func (q *queryData) WriteGroupBy(groupBy []Clause) error {
func (q *queryData) WriteGroupBy(groupBy []groupByClause) error {
q.clauseType = group_by_clause
q.WriteString(" GROUP BY ")
return serializeClauseList(groupBy, q)
return serializeGroupByClauseList(groupBy, q)
}
func (q *queryData) WriteOrderBy(orderBy []OrderByClause) error {
func (q *queryData) WriteOrderBy(orderBy []orderByClause) error {
q.clauseType = order_by_clause
q.WriteString(" ORDER BY ")
return serializeOrderByClauseList(orderBy, q)
}
func (q *queryData) WriteHaving(having Expression) error {
func (q *queryData) WriteHaving(having expression) error {
q.clauseType = having_clause
q.WriteString(" HAVING ")
return having.Serialize(q)
return having.serialize(q)
}
@ -141,12 +135,3 @@ func argToString(value interface{}) (string, error) {
return "", errors.New("Unsupported literal type. ")
}
}
func contains(s []serializeOption, e serializeOption) bool {
for _, a := range s {
if a == e {
return true
}
}
return false
}

View file

@ -6,13 +6,13 @@ import (
"strings"
)
type Column interface {
Expression
type column interface {
expression
Name() string
TableName() string
DefaultAlias() Projection
DefaultAlias() projection
// Internal function for tracking tableName that a column belongs to
// for the purpose of serialization
setTableName(table string)
@ -49,7 +49,7 @@ type baseColumn struct {
tableName string
}
func newBaseColumn(name string, nullable NullableColumn, tableName string, parent Column) baseColumn {
func newBaseColumn(name string, nullable NullableColumn, tableName string, parent column) baseColumn {
bc := baseColumn{
name: name,
nullable: nullable,
@ -73,11 +73,11 @@ func (c *baseColumn) setTableName(table string) {
c.tableName = table
}
func (c *baseColumn) DefaultAlias() Projection {
func (c *baseColumn) DefaultAlias() projection {
return c.AS(c.tableName + "." + c.name)
}
func (c baseColumn) Serialize(out *queryData, options ...serializeOption) error {
func (c baseColumn) serialize(out *queryData) error {
setOrderBy := out.statementType == set_statement && out.clauseType == order_by_clause

View file

@ -9,26 +9,26 @@ func TestNewBoolColumn(t *testing.T) {
boolColumn := NewBoolColumn("col", Nullable)
out := queryData{}
err := boolColumn.Serialize(&out)
err := boolColumn.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "col")
out.Reset()
err = boolColumn.Serialize(&out, FOR_PROJECTION)
err = boolColumn.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "col")
out.Reset()
boolColumn.setTableName("table1")
err = boolColumn.DefaultAlias().SerializeForProjection(&out)
err = boolColumn.DefaultAlias().serializeForProjection(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `table1.col AS "table1.col"`)
out.Reset()
boolColumn.setTableName("table1")
aliasedBoolColumn := boolColumn.AS("alias1")
err = aliasedBoolColumn.SerializeForProjection(&out)
err = aliasedBoolColumn.serializeForProjection(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `table1.col AS "alias1"`)
}
@ -37,26 +37,26 @@ func TestNewIntColumn(t *testing.T) {
integerColumn := NewIntegerColumn("col", Nullable)
out := queryData{}
err := integerColumn.Serialize(&out)
err := integerColumn.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "col")
out.Reset()
err = integerColumn.Serialize(&out, FOR_PROJECTION)
err = integerColumn.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "col")
out.Reset()
integerColumn.setTableName("table1")
err = integerColumn.DefaultAlias().SerializeForProjection(&out)
err = integerColumn.DefaultAlias().serializeForProjection(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `table1.col AS "table1.col"`)
out.Reset()
integerColumn.setTableName("table1")
aliasedBoolColumn := integerColumn.AS("alias1")
err = aliasedBoolColumn.SerializeForProjection(&out)
err = aliasedBoolColumn.serializeForProjection(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `table1.col AS "alias1"`)
}
@ -65,26 +65,26 @@ func TestNewNumericColumnColumn(t *testing.T) {
numericColumn := NewNumericColumn("col", Nullable)
out := queryData{}
err := numericColumn.Serialize(&out)
err := numericColumn.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "col")
out.Reset()
err = numericColumn.Serialize(&out)
err = numericColumn.serialize(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), "col")
out.Reset()
numericColumn.setTableName("table1")
err = numericColumn.DefaultAlias().SerializeForProjection(&out)
err = numericColumn.DefaultAlias().serializeForProjection(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `table1.col AS "table1.col"`)
out.Reset()
numericColumn.setTableName("table1")
aliasedBoolColumn := numericColumn.AS("alias1")
err = aliasedBoolColumn.SerializeForProjection(&out)
err = aliasedBoolColumn.serializeForProjection(&out)
assert.NilError(t, err)
assert.Equal(t, out.buff.String(), `table1.col AS "alias1"`)
}

View file

@ -6,24 +6,24 @@ import (
"github.com/sub0zero/go-sqlbuilder/types"
)
type DeleteStatement interface {
Statement
type deleteStatement interface {
statement
WHERE(expression BoolExpression) DeleteStatement
WHERE(expression boolExpression) deleteStatement
}
func newDeleteStatement(table WritableTable) DeleteStatement {
func newDeleteStatement(table writableTable) deleteStatement {
return &deleteStatementImpl{
table: table,
}
}
type deleteStatementImpl struct {
table WritableTable
where BoolExpression
table writableTable
where boolExpression
}
func (d *deleteStatementImpl) WHERE(expression BoolExpression) DeleteStatement {
func (d *deleteStatementImpl) WHERE(expression boolExpression) deleteStatement {
d.where = expression
return d
}
@ -38,7 +38,7 @@ func (d *deleteStatementImpl) Sql() (query string, args []interface{}, err error
return "", nil, errors.New("nil tableName.")
}
if err = d.table.SerializeSql(queryData); err != nil {
if err = d.table.serializeSql(queryData); err != nil {
return
}

View file

@ -5,63 +5,68 @@ import (
)
// An expression
type Expression interface {
Clause
Projection
type expression interface {
clause
projection
groupByClause
IN(subQuery SelectStatement) BoolExpression
NOT_IN(subQuery SelectStatement) BoolExpression
IN(subQuery selectStatement) boolExpression
NOT_IN(subQuery selectStatement) boolExpression
AS(alias string) Projection
IS_DISTINCT_FROM(expression Expression) BoolExpression
IS_NULL() BoolExpression
ASC() OrderByClause
DESC() OrderByClause
AS(alias string) projection
IS_DISTINCT_FROM(expression expression) boolExpression
IS_NULL() boolExpression
ASC() orderByClause
DESC() orderByClause
}
type expressionInterfaceImpl struct {
parent Expression
parent expression
}
func (e *expressionInterfaceImpl) IN(subQuery SelectStatement) BoolExpression {
func (e *expressionInterfaceImpl) IN(subQuery selectStatement) boolExpression {
return newBinaryBoolExpression(e.parent, subQuery, "IN")
}
func (e *expressionInterfaceImpl) NOT_IN(subQuery SelectStatement) BoolExpression {
func (e *expressionInterfaceImpl) NOT_IN(subQuery selectStatement) boolExpression {
return newBinaryBoolExpression(e.parent, subQuery, "NOT_IN")
}
func (e *expressionInterfaceImpl) AS(alias string) Projection {
func (e *expressionInterfaceImpl) AS(alias string) projection {
return NewAlias(e.parent, alias)
}
func (e *expressionInterfaceImpl) IS_DISTINCT_FROM(expression Expression) BoolExpression {
func (e *expressionInterfaceImpl) IS_DISTINCT_FROM(expression expression) boolExpression {
return newBinaryBoolExpression(e.parent, expression, "IS DISTINCT FROM")
}
func (e *expressionInterfaceImpl) IS_NULL() BoolExpression {
func (e *expressionInterfaceImpl) IS_NULL() boolExpression {
return nil
}
func (e *expressionInterfaceImpl) ASC() OrderByClause {
return &orderByClause{expression: e.parent, ascent: true}
func (e *expressionInterfaceImpl) ASC() orderByClause {
return &orderByClauseImpl{expression: e.parent, ascent: true}
}
func (e *expressionInterfaceImpl) DESC() OrderByClause {
return &orderByClause{expression: e.parent, ascent: false}
func (e *expressionInterfaceImpl) DESC() orderByClause {
return &orderByClauseImpl{expression: e.parent, ascent: false}
}
func (e *expressionInterfaceImpl) SerializeForProjection(out *queryData) error {
return e.parent.Serialize(out, FOR_PROJECTION)
func (e *expressionInterfaceImpl) serializeForGroupBy(out *queryData) error {
return e.parent.serialize(out)
}
func (e *expressionInterfaceImpl) serializeForProjection(out *queryData) error {
return e.parent.serialize(out)
}
// Representation of binary operations (e.g. comparisons, arithmetic)
type binaryExpression struct {
lhs, rhs Expression
lhs, rhs expression
operator string
}
func newBinaryExpression(lhs, rhs Expression, operator string, parent ...Expression) binaryExpression {
func newBinaryExpression(lhs, rhs expression, operator string, parent ...expression) binaryExpression {
binaryExpression := binaryExpression{
lhs: lhs,
rhs: rhs,
@ -71,11 +76,11 @@ func newBinaryExpression(lhs, rhs Expression, operator string, parent ...Express
return binaryExpression
}
func isSimpleOperand(expression Expression) bool {
func isSimpleOperand(expression expression) bool {
if _, ok := expression.(*literalExpression); ok {
return true
}
if _, ok := expression.(Column); ok {
if _, ok := expression.(column); ok {
return true
}
if _, ok := expression.(*numericFunc); ok {
@ -85,7 +90,7 @@ func isSimpleOperand(expression Expression) bool {
return false
}
func (c *binaryExpression) Serialize(out *queryData, options ...serializeOption) error {
func (c *binaryExpression) serialize(out *queryData) error {
if c.lhs == nil {
return errors.Newf("nil lhs.")
}
@ -99,13 +104,13 @@ func (c *binaryExpression) Serialize(out *queryData, options ...serializeOption)
out.WriteString("(")
}
if err := c.lhs.Serialize(out); err != nil {
if err := c.lhs.serialize(out); err != nil {
return err
}
out.WriteString(" " + c.operator + " ")
if err := c.rhs.Serialize(out); err != nil {
if err := c.rhs.serialize(out); err != nil {
return err
}
@ -118,11 +123,11 @@ func (c *binaryExpression) Serialize(out *queryData, options ...serializeOption)
// A not expression which negates a expression value
type prefixExpression struct {
expression Expression
expression expression
operator string
}
func newPrefixExpression(expression Expression, operator string) prefixExpression {
func newPrefixExpression(expression expression, operator string) prefixExpression {
prefixExpression := prefixExpression{
expression: expression,
operator: operator,
@ -131,13 +136,13 @@ func newPrefixExpression(expression Expression, operator string) prefixExpressio
return prefixExpression
}
func (p *prefixExpression) Serialize(out *queryData, options ...serializeOption) error {
func (p *prefixExpression) serialize(out *queryData) error {
out.WriteString(p.operator + " ")
if p.expression == nil {
return errors.Newf("nil prefix expression.")
}
if err := p.expression.Serialize(out); err != nil {
if err := p.expression.serialize(out); err != nil {
return err
}

View file

@ -14,7 +14,7 @@ type intervalExpression struct {
const intervalSep = ":"
func (c *intervalExpression) Serialize(out *queryData, options ...serializeOption) error {
func (c *intervalExpression) serialize(out *queryData) error {
out.WriteString("INTERVAL '")
duration := c.duration
@ -42,7 +42,7 @@ func (c *intervalExpression) Serialize(out *queryData, options ...serializeOptio
}
//// Interval returns a representation of duration
//func Interval(duration time.Duration) Expression {
//func Interval(duration time.Duration) expression {
// intervalExp := &intervalExpression{
// duration: duration,
// }

View file

@ -19,7 +19,7 @@ func (s *ExprSuite) TestConjunctExprEmptyList(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.NotNil)
}
@ -28,7 +28,7 @@ func (s *ExprSuite) TestConjunctExprNilInList(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.NotNil)
}
@ -37,7 +37,7 @@ func (s *ExprSuite) TestConjunctExprSingleElement(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -49,7 +49,7 @@ func (s *ExprSuite) TestLikeExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -65,7 +65,7 @@ func (s *ExprSuite) TestRegexExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -81,7 +81,7 @@ func (s *ExprSuite) TestAndExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -96,7 +96,7 @@ func (s *ExprSuite) TestOrExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -159,7 +159,7 @@ func (s *ExprSuite) TestBinaryExprNilLHS(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.NotNil)
}
@ -168,7 +168,7 @@ func (s *ExprSuite) TestNegateExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -180,7 +180,7 @@ func (s *ExprSuite) TestBinaryExprNilRHS(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.NotNil)
}
@ -189,7 +189,7 @@ func (s *ExprSuite) TestEqExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -201,7 +201,7 @@ func (s *ExprSuite) TestEqExprNilLHS(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -213,7 +213,7 @@ func (s *ExprSuite) TestNeqExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -225,7 +225,7 @@ func (s *ExprSuite) TestNeqExprNilLHS(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -237,7 +237,7 @@ func (s *ExprSuite) TestLtExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -249,7 +249,7 @@ func (s *ExprSuite) TestLteExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -264,7 +264,7 @@ func (s *ExprSuite) TestGtExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -276,7 +276,7 @@ func (s *ExprSuite) TestGteExpr(c *gc.C) {
buf := &bytes.Buffer{}
err := expr.Serialize(buf)
err := expr.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -343,20 +343,20 @@ func (s *ExprSuite) TestSqlFuncExprNonEmptyArgList(c *gc.C) {
}
func (s *ExprSuite) TestOrderByClauseNilExpr(c *gc.C) {
clause := Asc(nil)
clause := ASC(nil)
buf := &bytes.Buffer{}
err := clause.Serialize(buf)
err := clause.serialize(buf)
c.Assert(err, gc.NotNil)
}
func (s *ExprSuite) TestAsc(c *gc.C) {
clause := Asc(table1Col1)
clause := ASC(table1Col1)
buf := &bytes.Buffer{}
err := clause.Serialize(buf)
err := clause.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -364,11 +364,11 @@ func (s *ExprSuite) TestAsc(c *gc.C) {
}
func (s *ExprSuite) TestDesc(c *gc.C) {
clause := Desc(table1Col1)
clause := DESC(table1Col1)
buf := &bytes.Buffer{}
err := clause.Serialize(buf)
err := clause.serialize(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()

View file

@ -1,16 +1,16 @@
package sqlbuilder
type ExpressionTable interface {
ReadableTable
type expressionTable interface {
readableTable
RefIntColumnName(name string) *IntegerColumn
RefIntColumn(column Column) *IntegerColumn
RefStringColumn(column Column) *StringColumn
RefIntColumn(column column) *IntegerColumn
RefStringColumn(column column) *StringColumn
}
type expressionTableImpl struct {
statement Expression
columns []Column
statement expression
columns []column
alias string
}
@ -23,7 +23,7 @@ func (s *expressionTableImpl) TableName() string {
return s.alias
}
func (s *expressionTableImpl) Columns() []Column {
func (s *expressionTableImpl) Columns() []column {
return s.columns
}
@ -34,22 +34,22 @@ func (s *expressionTableImpl) RefIntColumnName(name string) *IntegerColumn {
return intColumn
}
func (s *expressionTableImpl) RefIntColumn(column Column) *IntegerColumn {
func (s *expressionTableImpl) RefIntColumn(column column) *IntegerColumn {
intColumn := NewIntegerColumn(column.TableName()+"."+column.Name(), NotNullable)
intColumn.setTableName(s.alias)
return intColumn
}
func (s *expressionTableImpl) RefStringColumn(column Column) *StringColumn {
func (s *expressionTableImpl) RefStringColumn(column column) *StringColumn {
strColumn := NewStringColumn(column.Name(), NotNullable)
strColumn.setTableName(column.TableName())
return strColumn
}
func (s *expressionTableImpl) SerializeSql(out *queryData) error {
func (s *expressionTableImpl) serializeSql(out *queryData) error {
out.WriteString("( ")
err := s.statement.Serialize(out)
err := s.statement.serialize(out)
if err != nil {
return err
@ -62,33 +62,33 @@ func (s *expressionTableImpl) SerializeSql(out *queryData) error {
}
// Generates a select query on the current tableName.
func (s *expressionTableImpl) SELECT(projections ...Projection) SelectStatement {
func (s *expressionTableImpl) SELECT(projections ...projection) selectStatement {
return newSelectStatement(s, projections)
}
// Creates a inner join tableName expression using onCondition.
func (s *expressionTableImpl) INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
func (s *expressionTableImpl) INNER_JOIN(table readableTable, onCondition boolExpression) readableTable {
return InnerJoinOn(s, table, onCondition)
}
//func (s *expressionTableImpl) InnerJoinUsing(table ReadableTable, col1 Column, col2 Column) ReadableTable {
//func (s *expressionTableImpl) InnerJoinUsing(table readableTable, col1 column, col2 column) readableTable {
// return INNER_JOIN(s, table, col1.Eq(col2))
//}
// Creates a left join tableName expression using onCondition.
func (s *expressionTableImpl) LEFT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
func (s *expressionTableImpl) LEFT_JOIN(table readableTable, onCondition boolExpression) readableTable {
return LeftJoinOn(s, table, onCondition)
}
// Creates a right join tableName expression using onCondition.
func (s *expressionTableImpl) RIGHT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
func (s *expressionTableImpl) RIGHT_JOIN(table readableTable, onCondition boolExpression) readableTable {
return RightJoinOn(s, table, onCondition)
}
func (s *expressionTableImpl) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
func (s *expressionTableImpl) FULL_JOIN(table readableTable, onCondition boolExpression) readableTable {
return FullJoin(s, table, onCondition)
}
func (s *expressionTableImpl) CROSS_JOIN(table ReadableTable) ReadableTable {
func (s *expressionTableImpl) CROSS_JOIN(table readableTable) readableTable {
return CrossJoin(s, table)
}

View file

@ -6,14 +6,14 @@ type funcExpressionImpl struct {
expressionInterfaceImpl
name string
expression []Expression
expression []expression
}
func ROW(expressions ...Expression) Expression {
func ROW(expressions ...expression) expression {
return newFunc("ROW", expressions, nil)
}
func newFunc(name string, expressions []Expression, parent Expression) *funcExpressionImpl {
func newFunc(name string, expressions []expression, parent expression) *funcExpressionImpl {
funcExp := &funcExpressionImpl{
name: name,
expression: expressions,
@ -28,7 +28,7 @@ func newFunc(name string, expressions []Expression, parent Expression) *funcExpr
return funcExp
}
func (f *funcExpressionImpl) Serialize(out *queryData, options ...serializeOption) error {
func (f *funcExpressionImpl) serialize(out *queryData) error {
out.WriteString(f.name)
out.WriteString("(")
err := serializeExpressionList(f.expression, ", ", out)
@ -45,7 +45,7 @@ type numericFunc struct {
numericInterfaceImpl
}
func NewNumericFunc(name string, expressions ...Expression) NumericExpression {
func NewNumericFunc(name string, expressions ...expression) numericExpression {
numericFunc := &numericFunc{}
numericFunc.funcExpressionImpl = *newFunc(name, expressions, numericFunc)
@ -55,35 +55,35 @@ func NewNumericFunc(name string, expressions ...Expression) NumericExpression {
}
//func (f *FuncExpression) SerializeSqlForColumnList(out *bytes.Buffer) error {
// return f.Serialize(out)
// return f.serialize(out)
//}
func MAX(expression NumericExpression) NumericExpression {
func MAX(expression numericExpression) numericExpression {
return NewNumericFunc("MAX", expression)
}
func SUM(expression NumericExpression) NumericExpression {
func SUM(expression numericExpression) numericExpression {
return NewNumericFunc("SUM", expression)
}
type caseInterface interface {
Expression
expression
WHEN(condition Expression) caseInterface
THEN(then Expression) caseInterface
ELSE(els Expression) caseInterface
WHEN(condition expression) caseInterface
THEN(then expression) caseInterface
ELSE(els expression) caseInterface
}
type caseExpression struct {
expressionInterfaceImpl
expression Expression
when []Expression
then []Expression
els Expression
expression expression
when []expression
then []expression
els expression
}
func CASE(expression ...Expression) caseInterface {
func CASE(expression ...expression) caseInterface {
caseExp := &caseExpression{}
if len(expression) == 1 {
@ -95,28 +95,28 @@ func CASE(expression ...Expression) caseInterface {
return caseExp
}
func (c *caseExpression) WHEN(when Expression) caseInterface {
func (c *caseExpression) WHEN(when expression) caseInterface {
c.when = append(c.when, when)
return c
}
func (c *caseExpression) THEN(then Expression) caseInterface {
func (c *caseExpression) THEN(then expression) caseInterface {
c.then = append(c.then, then)
return c
}
func (c *caseExpression) ELSE(els Expression) caseInterface {
func (c *caseExpression) ELSE(els expression) caseInterface {
c.els = els
return c
}
func (c *caseExpression) Serialize(out *queryData, options ...serializeOption) error {
func (c *caseExpression) serialize(out *queryData) error {
out.WriteString("(CASE")
if c.expression != nil {
out.WriteString(" ")
err := c.expression.Serialize(out)
err := c.expression.serialize(out)
if err != nil {
return err
@ -133,14 +133,14 @@ func (c *caseExpression) Serialize(out *queryData, options ...serializeOption) e
for i, when := range c.when {
out.WriteString(" WHEN ")
err := when.Serialize(out)
err := when.serialize(out)
if err != nil {
return err
}
out.WriteString(" THEN ")
err = c.then[i].Serialize(out)
err = c.then[i].serialize(out)
if err != nil {
return err
@ -149,7 +149,7 @@ func (c *caseExpression) Serialize(out *queryData, options ...serializeOption) e
if c.els != nil {
out.WriteString(" ELSE ")
err := c.els.Serialize(out)
err := c.els.serialize(out)
if err != nil {
return err

View file

@ -12,7 +12,7 @@ func TestCase1(t *testing.T) {
queryData := &queryData{}
err := query.Serialize(queryData)
err := query.serialize(queryData)
assert.NilError(t, err)
assert.Equal(t, queryData.buff.String(), `(CASE WHEN table3.col1 = $1 THEN table3.col1 + $2 WHEN table3.col1 = $3 THEN table3.col1 + $4 END)`)
@ -26,7 +26,7 @@ func TestCase2(t *testing.T) {
queryData := &queryData{}
err := query.Serialize(queryData)
err := query.serialize(queryData)
assert.NilError(t, err)
assert.Equal(t, queryData.buff.String(), `(CASE table3.col1 WHEN $1 THEN table3.col1 + $2 WHEN $3 THEN table3.col1 + $4 ELSE $5 END)`)
@ -37,7 +37,7 @@ func TestInterval(t *testing.T) {
queryData := &queryData{}
err := query.Serialize(queryData)
err := query.serialize(queryData)
assert.NilError(t, err)
assert.Equal(t, queryData.buff.String(), `INTERVAL $1`)

View file

@ -0,0 +1,7 @@
package sqlbuilder
type groupByClause interface {
serializeForGroupBy(out *queryData) error
}
// TODO: GROUPING SETS, CUBE, and ROLLUP

View file

@ -9,20 +9,20 @@ import (
"strings"
)
type InsertStatement interface {
Statement
type insertStatement interface {
statement
// Add a row of values to the insert statement.
VALUES(values ...interface{}) InsertStatement
VALUES(values ...interface{}) insertStatement
// Map or stracture mapped to column names
VALUES_MAPPING(data interface{}) InsertStatement
VALUES_MAPPING(data interface{}) insertStatement
RETURNING(projections ...Projection) InsertStatement
RETURNING(projections ...projection) insertStatement
QUERY(selectStatement SelectStatement) InsertStatement
QUERY(selectStatement selectStatement) insertStatement
}
func newInsertStatement(t WritableTable, columns ...Column) InsertStatement {
func newInsertStatement(t writableTable, columns ...column) insertStatement {
return &insertStatementImpl{
table: t,
columns: columns,
@ -30,11 +30,11 @@ func newInsertStatement(t WritableTable, columns ...Column) InsertStatement {
}
type insertStatementImpl struct {
table WritableTable
columns []Column
rows [][]Clause
query SelectStatement
returning []Projection
table writableTable
columns []column
rows [][]clause
query selectStatement
returning []projection
errors []string
}
@ -48,15 +48,15 @@ func (u *insertStatementImpl) Execute(db types.Db) (res sql.Result, err error) {
}
// expression or default keyword
func (s *insertStatementImpl) VALUES(values ...interface{}) InsertStatement {
func (s *insertStatementImpl) VALUES(values ...interface{}) insertStatement {
if len(values) == 0 {
return s
}
literalRow := []Clause{}
literalRow := []clause{}
for _, value := range values {
if clause, ok := value.(Clause); ok {
if clause, ok := value.(clause); ok {
literalRow = append(literalRow, clause)
} else {
literalRow = append(literalRow, Literal(value))
@ -67,7 +67,7 @@ func (s *insertStatementImpl) VALUES(values ...interface{}) InsertStatement {
return s
}
func (i *insertStatementImpl) VALUES_MAPPING(data interface{}) InsertStatement {
func (i *insertStatementImpl) VALUES_MAPPING(data interface{}) insertStatement {
if data == nil {
i.addError("Add method data is nil.")
return i
@ -84,7 +84,7 @@ func (i *insertStatementImpl) VALUES_MAPPING(data interface{}) InsertStatement {
return i
}
rowValues := []Clause{}
rowValues := []clause{}
for _, column := range i.columns {
columnName := column.Name()
@ -105,13 +105,13 @@ func (i *insertStatementImpl) VALUES_MAPPING(data interface{}) InsertStatement {
return i
}
func (i *insertStatementImpl) RETURNING(projections ...Projection) InsertStatement {
func (i *insertStatementImpl) RETURNING(projections ...projection) insertStatement {
i.returning = defaultProjectionAliasing(projections)
return i
}
func (i *insertStatementImpl) QUERY(selectStatement SelectStatement) InsertStatement {
func (i *insertStatementImpl) QUERY(selectStatement selectStatement) insertStatement {
i.query = selectStatement
return i
@ -134,7 +134,7 @@ func (s *insertStatementImpl) Sql() (sql string, args []interface{}, err error)
return "", nil, errors.Newf("nil tableName.")
}
err = s.table.SerializeSql(queryData)
err = s.table.serializeSql(queryData)
if err != nil {
return "", nil, err
@ -182,7 +182,7 @@ func (s *insertStatementImpl) Sql() (sql string, args []interface{}, err error)
}
if s.query != nil {
err = s.query.Serialize(queryData)
err = s.query.serialize(queryData)
if err != nil {
return

View file

@ -1,42 +1,42 @@
package sqlbuilder
type IntegerExpression interface {
NumericExpression
type integerExpression interface {
numericExpression
//AddInt(value int) IntegerExpression
//AddInt64(value int) IntegerExpression
//AddInt(value int) integerExpression
//AddInt64(value int) integerExpression
BitAnd(expression IntegerExpression) IntegerExpression
BitOr(expression IntegerExpression) IntegerExpression
BitXor(expression IntegerExpression) IntegerExpression
BitNot() IntegerExpression
BitAnd(expression integerExpression) integerExpression
BitOr(expression integerExpression) integerExpression
BitXor(expression integerExpression) integerExpression
BitNot() integerExpression
}
type integerInterfaceImpl struct {
parent IntegerExpression
parent integerExpression
}
//func (i *integerInterfaceImpl) AddInt(expression IntegerExpression) IntegerExpression {
//func (i *integerInterfaceImpl) AddInt(expression integerExpression) integerExpression {
// return NewBinaryIntegerExpression(i.parent, expression, " & ")
//}
//
//func (i *integerInterfaceImpl) AddInt64(expression IntegerExpression) IntegerExpression {
//func (i *integerInterfaceImpl) AddInt64(expression integerExpression) integerExpression {
// return NewBinaryIntegerExpression(i.parent, expression, " & ")
//}
func (i *integerInterfaceImpl) BitAnd(expression IntegerExpression) IntegerExpression {
func (i *integerInterfaceImpl) BitAnd(expression integerExpression) integerExpression {
return NewBinaryIntegerExpression(i.parent, expression, " & ")
}
func (i *integerInterfaceImpl) BitOr(expression IntegerExpression) IntegerExpression {
func (i *integerInterfaceImpl) BitOr(expression integerExpression) integerExpression {
return NewBinaryIntegerExpression(i.parent, expression, " | ")
}
func (i *integerInterfaceImpl) BitXor(expression IntegerExpression) IntegerExpression {
func (i *integerInterfaceImpl) BitXor(expression integerExpression) integerExpression {
return NewBinaryIntegerExpression(i.parent, expression, " # ")
}
func (i *integerInterfaceImpl) BitNot() IntegerExpression {
func (i *integerInterfaceImpl) BitNot() integerExpression {
return NewPrefixIntegerExpression(i.parent, " ~")
}
@ -49,7 +49,7 @@ type binaryIntegerExpression struct {
binaryExpression
}
func NewBinaryIntegerExpression(lhs, rhs IntegerExpression, operator string) IntegerExpression {
func NewBinaryIntegerExpression(lhs, rhs integerExpression, operator string) integerExpression {
integerExpression := binaryIntegerExpression{}
integerExpression.expressionInterfaceImpl.parent = &integerExpression
@ -70,7 +70,7 @@ type prefixIntegerExpression struct {
prefixExpression
}
func NewPrefixIntegerExpression(expression IntegerExpression, operator string) IntegerExpression {
func NewPrefixIntegerExpression(expression integerExpression, operator string) integerExpression {
integerExpression := prefixIntegerExpression{}
integerExpression.prefixExpression = newPrefixExpression(expression, operator)

View file

@ -6,7 +6,7 @@ const (
type keywordClause string
func (k keywordClause) Serialize(out *queryData, options ...serializeOption) error {
func (k keywordClause) serialize(out *queryData) error {
out.WriteString(string(k))
return nil

View file

@ -13,7 +13,7 @@ func Literal(value interface{}) *literalExpression {
return &exp
}
func (l literalExpression) Serialize(out *queryData, options ...serializeOption) error {
func (l literalExpression) serialize(out *queryData) error {
out.InsertArgument(l.value)
return nil
@ -24,7 +24,7 @@ type numLiteralExpression struct {
numericInterfaceImpl
}
func IntLiteral(value int) NumericExpression {
func IntLiteral(value int) numericExpression {
numLiteral := &numLiteralExpression{}
numLiteral.literalExpression = *Literal(value)

View file

@ -20,7 +20,7 @@ const (
)
type lockStatement interface {
Statement
statement
IN(lockMode lockMode) lockStatement
NOWAIT() lockStatement
@ -66,7 +66,7 @@ func (l *lockStatementImpl) Sql() (query string, args []interface{}, err error)
out.WriteString(", ")
}
err := table.SerializeSql(out)
err := table.serializeSql(out)
if err != nil {
return "", nil, err

View file

@ -1,79 +1,79 @@
package sqlbuilder
type NumericExpression interface {
Expression
type numericExpression interface {
expression
Eq(expression NumericExpression) BoolExpression
EqL(literal interface{}) BoolExpression
NotEq(expression NumericExpression) BoolExpression
NotEqL(literal interface{}) BoolExpression
Eq(expression numericExpression) boolExpression
EqL(literal interface{}) boolExpression
NotEq(expression numericExpression) boolExpression
NotEqL(literal interface{}) boolExpression
Gt(rhs NumericExpression) BoolExpression
GtEq(rhs NumericExpression) BoolExpression
GtEqL(literal interface{}) BoolExpression
Gt(rhs numericExpression) boolExpression
GtEq(rhs numericExpression) boolExpression
GtEqL(literal interface{}) boolExpression
LtEq(rhs NumericExpression) BoolExpression
LtEqL(literal interface{}) BoolExpression
LtEq(rhs numericExpression) boolExpression
LtEqL(literal interface{}) boolExpression
Add(expression NumericExpression) NumericExpression
Sub(expression NumericExpression) NumericExpression
Mul(expression NumericExpression) NumericExpression
Div(expression NumericExpression) NumericExpression
Add(expression numericExpression) numericExpression
Sub(expression numericExpression) numericExpression
Mul(expression numericExpression) numericExpression
Div(expression numericExpression) numericExpression
}
type numericInterfaceImpl struct {
parent NumericExpression
parent numericExpression
}
func (n *numericInterfaceImpl) Eq(expression NumericExpression) BoolExpression {
func (n *numericInterfaceImpl) Eq(expression numericExpression) boolExpression {
return Eq(n.parent, expression)
}
func (n *numericInterfaceImpl) EqL(literal interface{}) BoolExpression {
func (n *numericInterfaceImpl) EqL(literal interface{}) boolExpression {
return Eq(n.parent, Literal(literal))
}
func (n *numericInterfaceImpl) NotEq(expression NumericExpression) BoolExpression {
func (n *numericInterfaceImpl) NotEq(expression numericExpression) boolExpression {
return NotEq(n.parent, expression)
}
func (n *numericInterfaceImpl) NotEqL(literal interface{}) BoolExpression {
func (n *numericInterfaceImpl) NotEqL(literal interface{}) boolExpression {
return NotEq(n.parent, Literal(literal))
}
func (n *numericInterfaceImpl) Gt(expression NumericExpression) BoolExpression {
func (n *numericInterfaceImpl) Gt(expression numericExpression) boolExpression {
return Gt(n.parent, expression)
}
func (n *numericInterfaceImpl) GtEq(expression NumericExpression) BoolExpression {
func (n *numericInterfaceImpl) GtEq(expression numericExpression) boolExpression {
return GtEq(n.parent, expression)
}
func (n *numericInterfaceImpl) GtEqL(literal interface{}) BoolExpression {
func (n *numericInterfaceImpl) GtEqL(literal interface{}) boolExpression {
return GtEq(n.parent, Literal(literal))
}
func (n *numericInterfaceImpl) LtEq(expression NumericExpression) BoolExpression {
func (n *numericInterfaceImpl) LtEq(expression numericExpression) boolExpression {
return LtEq(n.parent, expression)
}
func (n *numericInterfaceImpl) LtEqL(literal interface{}) BoolExpression {
func (n *numericInterfaceImpl) LtEqL(literal interface{}) boolExpression {
return LtEq(n.parent, Literal(literal))
}
func (n *numericInterfaceImpl) Add(expression NumericExpression) NumericExpression {
func (n *numericInterfaceImpl) Add(expression numericExpression) numericExpression {
return newBinaryNumericExpression(n.parent, expression, "+")
}
func (n *numericInterfaceImpl) Sub(expression NumericExpression) NumericExpression {
func (n *numericInterfaceImpl) Sub(expression numericExpression) numericExpression {
return newBinaryNumericExpression(n.parent, expression, "-")
}
func (n *numericInterfaceImpl) Mul(expression NumericExpression) NumericExpression {
func (n *numericInterfaceImpl) Mul(expression numericExpression) numericExpression {
return newBinaryNumericExpression(n.parent, expression, "*")
}
func (n *numericInterfaceImpl) Div(expression NumericExpression) NumericExpression {
func (n *numericInterfaceImpl) Div(expression numericExpression) numericExpression {
return newBinaryNumericExpression(n.parent, expression, "/")
}
@ -83,7 +83,7 @@ type numericLiteral struct {
literalExpression
}
func NewNumericLiteral(value interface{}) NumericExpression {
func NewNumericLiteral(value interface{}) numericExpression {
numericLiteral := numericLiteral{}
numericLiteral.literalExpression = *Literal(value)
@ -100,7 +100,7 @@ type binaryNumericExpression struct {
binaryExpression
}
func newBinaryNumericExpression(lhs, rhs Expression, operator string) NumericExpression {
func newBinaryNumericExpression(lhs, rhs expression, operator string) numericExpression {
numericExpression := binaryNumericExpression{}
numericExpression.binaryExpression = newBinaryExpression(lhs, rhs, operator)
@ -116,10 +116,10 @@ type numericExpressionWrapper struct {
expressionInterfaceImpl
numericInterfaceImpl
expression Expression
expression expression
}
func newNumericExpressionWrap(expression Expression) NumericExpression {
func newNumericExpressionWrap(expression expression) numericExpression {
numericExpressionWrap := numericExpressionWrapper{}
numericExpressionWrap.expression = expression
@ -130,9 +130,9 @@ func newNumericExpressionWrap(expression Expression) NumericExpression {
return &numericExpressionWrap
}
func (c *numericExpressionWrapper) Serialize(out *queryData, options ...serializeOption) error {
func (c *numericExpressionWrapper) serialize(out *queryData) error {
out.WriteString("(")
err := c.expression.Serialize(out, options...)
err := c.expression.serialize(out)
out.WriteString(")")
return err

View file

@ -2,8 +2,8 @@ package sqlbuilder
import "github.com/dropbox/godropbox/errors"
type OrderByClause interface {
Clause
type orderByClause interface {
clause
isOrderByClauseType()
}
@ -13,27 +13,18 @@ type isOrderByClause struct {
func (o *isOrderByClause) isOrderByClauseType() {
}
type ColumnNameOrderBy string
func (o *ColumnNameOrderBy) isOrderByClauseType() {
}
func (o *ColumnNameOrderBy) Serialize(out *queryData, options ...serializeOption) error {
return nil
}
type orderByClause struct {
type orderByClauseImpl struct {
isOrderByClause
expression Expression
expression expression
ascent bool
}
func (o *orderByClause) Serialize(out *queryData, options ...serializeOption) error {
func (o *orderByClauseImpl) serialize(out *queryData) error {
if o.expression == nil {
return errors.Newf("nil orderBy by clause.")
}
if err := o.expression.Serialize(out); err != nil {
if err := o.expression.serialize(out); err != nil {
return err
}
@ -46,10 +37,10 @@ func (o *orderByClause) Serialize(out *queryData, options ...serializeOption) er
return nil
}
func Asc(expression Expression) OrderByClause {
return &orderByClause{expression: expression, ascent: true}
func ASC(expression expression) orderByClause {
return &orderByClauseImpl{expression: expression, ascent: true}
}
func Desc(expression Expression) OrderByClause {
return &orderByClause{expression: expression, ascent: false}
func DESC(expression expression) orderByClause {
return &orderByClauseImpl{expression: expression, ascent: false}
}

View file

@ -1,16 +1,18 @@
package sqlbuilder
type Projection interface {
SerializeForProjection(out *queryData) error
type projection interface {
serializeForProjection(out *queryData) error
}
//------------------------------------------------------//
// Dummy type for select * AllColumns
type ColumnList []Column
type ColumnList []column
func (cl ColumnList) SerializeForProjection(out *queryData) error {
func (cl ColumnList) isProjectionType() {}
func (cl ColumnList) serializeForProjection(out *queryData) error {
for i, column := range cl {
err := column.Serialize(out, FOR_PROJECTION)
err := column.serializeForProjection(out)
if err != nil {
return err
@ -23,8 +25,8 @@ func (cl ColumnList) SerializeForProjection(out *queryData) error {
return nil
}
func (cl ColumnList) DefaultAlias() []Projection {
newColumnList := []Projection{}
func (cl ColumnList) DefaultAlias() []projection {
newColumnList := []projection{}
for _, column := range cl {
newColumn := column.DefaultAlias()

View file

@ -6,52 +6,52 @@ import (
"github.com/sub0zero/go-sqlbuilder/types"
)
type SelectStatement interface {
Statement
Expression
type selectStatement interface {
statement
expression
DISTINCT() SelectStatement
FROM(table ReadableTable) SelectStatement
WHERE(expression BoolExpression) SelectStatement
GROUP_BY(expressions ...Clause) SelectStatement
HAVING(boolExpression BoolExpression) SelectStatement
ORDER_BY(clauses ...OrderByClause) SelectStatement
DISTINCT() selectStatement
FROM(table readableTable) selectStatement
WHERE(expression boolExpression) selectStatement
GROUP_BY(groupByClauses ...groupByClause) selectStatement
HAVING(boolExpression boolExpression) selectStatement
ORDER_BY(orderByClauses ...orderByClause) selectStatement
LIMIT(limit int64) SelectStatement
OFFSET(offset int64) SelectStatement
LIMIT(limit int64) selectStatement
OFFSET(offset int64) selectStatement
FOR_UPDATE() SelectStatement
FOR_UPDATE() selectStatement
AsTable(alias string) ExpressionTable
AsTable(alias string) expressionTable
}
var SELECT = func(projection ...Projection) SelectStatement {
var SELECT = func(projection ...projection) selectStatement {
return newSelectStatement(nil, projection)
}
// NOTE: SelectStatement purposely does not implement the Table interface since
// NOTE: selectStatement purposely does not implement the Table interface since
// mysql's subquery performance is horrible.
type selectStatementImpl struct {
expressionInterfaceImpl
table ReadableTable
table readableTable
distinct bool
projections []Projection
where BoolExpression
groupBy []Clause //can be ROLLUP, ... so clause for now
having BoolExpression
orderBy []OrderByClause
projections []projection
where boolExpression
groupBy []groupByClause
having boolExpression
orderBy []orderByClause
limit, offset int64
forUpdate bool
}
func defaultProjectionAliasing(projections []Projection) []Projection {
aliasedProjections := []Projection{}
func defaultProjectionAliasing(projections []projection) []projection {
aliasedProjections := []projection{}
for _, projection := range projections {
if column, ok := projection.(Column); ok {
if column, ok := projection.(column); ok {
aliasedProjections = append(aliasedProjections, column.DefaultAlias())
} else if columnList, ok := projection.(ColumnList); ok {
aliasedProjections = append(aliasedProjections, columnList.DefaultAlias()...)
@ -63,7 +63,7 @@ func defaultProjectionAliasing(projections []Projection) []Projection {
return aliasedProjections
}
func newSelectStatement(table ReadableTable, projections []Projection) SelectStatement {
func newSelectStatement(table readableTable, projections []projection) selectStatement {
newSelect := &selectStatementImpl{
table: table,
projections: defaultProjectionAliasing(projections),
@ -78,16 +78,16 @@ func newSelectStatement(table ReadableTable, projections []Projection) SelectSta
return newSelect
}
func (s *selectStatementImpl) FROM(table ReadableTable) SelectStatement {
func (s *selectStatementImpl) FROM(table readableTable) selectStatement {
s.table = table
return s
}
func (s *selectStatementImpl) Serialize(out *queryData, options ...serializeOption) error {
func (s *selectStatementImpl) serialize(out *queryData) error {
out.WriteString("(")
err := s.serializeImpl(out, options...)
err := s.serializeImpl(out)
if err != nil {
return err
@ -98,7 +98,7 @@ func (s *selectStatementImpl) Serialize(out *queryData, options ...serializeOpti
return nil
}
func (s *selectStatementImpl) serializeImpl(out *queryData, options ...serializeOption) error {
func (s *selectStatementImpl) serializeImpl(out *queryData) error {
out.WriteString("SELECT ")
out.statementType = select_statement
@ -123,7 +123,7 @@ func (s *selectStatementImpl) serializeImpl(out *queryData, options ...serialize
return errors.Newf("nil tableName.")
}
if err := s.table.SerializeSql(out); err != nil {
if err := s.table.serializeSql(out); err != nil {
return err
}
@ -189,51 +189,51 @@ func (q *selectStatementImpl) Sql() (query string, args []interface{}, err error
return queryData.buff.String(), queryData.args, nil
}
func (s *selectStatementImpl) AsTable(alias string) ExpressionTable {
func (s *selectStatementImpl) AsTable(alias string) expressionTable {
return &expressionTableImpl{
statement: s,
alias: alias,
}
}
func (q *selectStatementImpl) WHERE(expression BoolExpression) SelectStatement {
func (q *selectStatementImpl) WHERE(expression boolExpression) selectStatement {
q.where = expression
return q
}
func (s *selectStatementImpl) GROUP_BY(cluases ...Clause) SelectStatement {
s.groupBy = cluases
func (s *selectStatementImpl) GROUP_BY(groupByClauses ...groupByClause) selectStatement {
s.groupBy = groupByClauses
return s
}
func (q *selectStatementImpl) HAVING(expression BoolExpression) SelectStatement {
func (q *selectStatementImpl) HAVING(expression boolExpression) selectStatement {
q.having = expression
return q
}
func (q *selectStatementImpl) ORDER_BY(clauses ...OrderByClause) SelectStatement {
func (q *selectStatementImpl) ORDER_BY(clauses ...orderByClause) selectStatement {
q.orderBy = clauses
return q
}
func (q *selectStatementImpl) OFFSET(offset int64) SelectStatement {
func (q *selectStatementImpl) OFFSET(offset int64) selectStatement {
q.offset = offset
return q
}
func (q *selectStatementImpl) LIMIT(limit int64) SelectStatement {
func (q *selectStatementImpl) LIMIT(limit int64) selectStatement {
q.limit = limit
return q
}
func (q *selectStatementImpl) DISTINCT() SelectStatement {
func (q *selectStatementImpl) DISTINCT() selectStatement {
q.distinct = true
return q
}
func (q *selectStatementImpl) FOR_UPDATE() SelectStatement {
func (q *selectStatementImpl) FOR_UPDATE() selectStatement {
q.forUpdate = true
return q
}
@ -246,6 +246,6 @@ func (u *selectStatementImpl) Execute(db types.Db) (res sql.Result, err error) {
return Execute(u, db)
}
func NumExp(statement SelectStatement) NumericExpression {
func NumExp(statement selectStatement) numericExpression {
return newNumericExpressionWrap(statement)
}

View file

@ -12,38 +12,38 @@ const (
except = "EXCEPT"
)
type SetStatement interface {
Statement
Expression
type setStatement interface {
statement
expression
ORDER_BY(clauses ...OrderByClause) SetStatement
LIMIT(limit int64) SetStatement
OFFSET(offset int64) SetStatement
ORDER_BY(clauses ...orderByClause) setStatement
LIMIT(limit int64) setStatement
OFFSET(offset int64) setStatement
AsTable(alias string) ExpressionTable
AsTable(alias string) expressionTable
}
func UNION(selects ...SelectStatement) SetStatement {
func UNION(selects ...selectStatement) setStatement {
return newSetStatementImpl(union, false, selects...)
}
func UNION_ALL(selects ...SelectStatement) SetStatement {
func UNION_ALL(selects ...selectStatement) setStatement {
return newSetStatementImpl(union, true, selects...)
}
func INTERSECT(selects ...SelectStatement) SetStatement {
func INTERSECT(selects ...selectStatement) setStatement {
return newSetStatementImpl(intersect, false, selects...)
}
func INTERSECT_ALL(selects ...SelectStatement) SetStatement {
func INTERSECT_ALL(selects ...selectStatement) setStatement {
return newSetStatementImpl(intersect, true, selects...)
}
func EXCEPT(selects ...SelectStatement) SetStatement {
func EXCEPT(selects ...selectStatement) setStatement {
return newSetStatementImpl(except, false, selects...)
}
func EXCEPT_ALL(selects ...SelectStatement) SetStatement {
func EXCEPT_ALL(selects ...selectStatement) setStatement {
return newSetStatementImpl(except, true, selects...)
}
@ -52,14 +52,14 @@ type setStatementImpl struct {
expressionInterfaceImpl
operator string
selects []SelectStatement
orderBy []OrderByClause
selects []selectStatement
orderBy []orderByClause
limit, offset int64
// True if results of the union should be deduped.
all bool
}
func newSetStatementImpl(operator string, all bool, selects ...SelectStatement) SetStatement {
func newSetStatementImpl(operator string, all bool, selects ...selectStatement) setStatement {
setStatement := &setStatementImpl{
operator: operator,
selects: selects,
@ -73,30 +73,30 @@ func newSetStatementImpl(operator string, all bool, selects ...SelectStatement)
return setStatement
}
func (us *setStatementImpl) ORDER_BY(orderBy ...OrderByClause) SetStatement {
func (us *setStatementImpl) ORDER_BY(orderBy ...orderByClause) setStatement {
us.orderBy = orderBy
return us
}
func (us *setStatementImpl) LIMIT(limit int64) SetStatement {
func (us *setStatementImpl) LIMIT(limit int64) setStatement {
us.limit = limit
return us
}
func (us *setStatementImpl) OFFSET(offset int64) SetStatement {
func (us *setStatementImpl) OFFSET(offset int64) setStatement {
us.offset = offset
return us
}
func (us *setStatementImpl) AsTable(alias string) ExpressionTable {
func (us *setStatementImpl) AsTable(alias string) expressionTable {
return &expressionTableImpl{
statement: us,
alias: alias,
}
}
func (s *setStatementImpl) Serialize(out *queryData, options ...serializeOption) error {
func (s *setStatementImpl) serialize(out *queryData) error {
if s.orderBy != nil || s.limit >= 0 || s.offset >= 0 {
out.WriteString("(")
}
@ -114,7 +114,7 @@ func (s *setStatementImpl) Serialize(out *queryData, options ...serializeOption)
return nil
}
func (s *setStatementImpl) serializeImpl(out *queryData, options ...serializeOption) error {
func (s *setStatementImpl) serializeImpl(out *queryData) error {
if len(s.selects) < 2 {
return errors.Newf("UNION statement must have at least two SELECT statements.")
@ -131,7 +131,7 @@ func (s *setStatementImpl) serializeImpl(out *queryData, options ...serializeOpt
}
}
err := selectStmt.Serialize(out, options...)
err := selectStmt.serialize(out)
if err != nil {
return err

View file

@ -5,70 +5,10 @@ import (
"github.com/sub0zero/go-sqlbuilder/types"
)
type Statement interface {
type statement interface {
// String returns generated SQL as string.
Sql() (query string, args []interface{}, err error)
Query(db types.Db, destination interface{}) error
Execute(db types.Db) (sql.Result, error)
}
//// SetGtidNextStatement returns a SQL statement that can be used to explicitly set the next GTID.
//type GtidNextStatement interface {
// Statement
//}
//
//// SET GTID_NEXT statement returns a SQL statement that can be used to explicitly set the next GTID.
//func NewGtidNextStatement(sid []byte, gno uint64) GtidNextStatement {
// return &gtidNextStatementImpl{
// sid: sid,
// gno: gno,
// }
//}
//
//type gtidNextStatementImpl struct {
// sid []byte
// gno uint64
//}
//
//func (g *gtidNextStatementImpl) Execute(db *sql.DB, data interface{}) error {
// return nil
//}
//
//func (s *gtidNextStatementImpl) String() (sql string, err error) {
// // This statement sets a session local variable defining what the next transaction ID is. It
// // does not interact with other MySQL sessions. It is neither a DDL nor DML statement, so we
// // don't have to worry about data corruption.
// // Because of the string formatting (hex plus an integer), can't morph into another statement.
// // See: https://dev.mysql.com/doc/refman/5.7/en/replication-options-gtids.html
// const gtidFormatString = "SET GTID_NEXT=\"%x-%x-%x-%x-%x:%d\""
//
// buf := new(bytes.Buffer)
// _, _ = buf.WriteString(fmt.Sprintf(gtidFormatString,
// s.sid[:4], s.sid[4:6], s.sid[6:8], s.sid[8:10], s.sid[10:], s.gno))
// return buf.String(), nil
//}
//
// Util functions =============================================================
//
// Once again, teisenberger is lazy. Here's a quick filter on comments
//var validCommentRegexp *regexp.Regexp = regexp.MustCompile("^[\\w .?]*$")
//
//func isValidComment(comment string) bool {
// return validCommentRegexp.MatchString(comment)
//}
//
//func writeComment(comment string, buf *bytes.Buffer) error {
// if comment != "" {
// _, _ = buf.WriteString("/* ")
// if !isValidComment(comment) {
// return errors.Newf("Invalid comment: %s", comment)
// }
// _, _ = buf.WriteString(comment)
// _, _ = buf.WriteString(" */")
// }
// return nil
//}

View file

@ -157,7 +157,7 @@ func (s *StmtSuite) TestSelectSingleOrderBy(c *gc.C) {
}
func (s *StmtSuite) TestSelectOrderByAsc(c *gc.C) {
q := table1.Select(table1Col1, table1Col2).OrderBy(Asc(table1Col2))
q := table1.Select(table1Col1, table1Col2).OrderBy(ASC(table1Col2))
sql, err := q.String()
c.Assert(err, gc.IsNil)
@ -169,7 +169,7 @@ func (s *StmtSuite) TestSelectOrderByAsc(c *gc.C) {
}
func (s *StmtSuite) TestSelectOrderByDesc(c *gc.C) {
q := table1.Select(table1Col1, table1Col2).OrderBy(Desc(table1Col2))
q := table1.Select(table1Col1, table1Col2).OrderBy(DESC(table1Col2))
sql, err := q.String()
c.Assert(err, gc.IsNil)
@ -406,7 +406,7 @@ func (s *StmtSuite) TestUnlockStatement(c *gc.C) {
}
func (s *StmtSuite) TestUnionSelectStatement(c *gc.C) {
select_queries := make([]SelectStatement, 0, 3)
select_queries := make([]selectStatement, 0, 3)
select_queries = append(select_queries,
table1.Select(table1Col1).Where(GtL(table1Col1, 123)),
@ -428,7 +428,7 @@ func (s *StmtSuite) TestUnionSelectStatement(c *gc.C) {
}
func (s *StmtSuite) TestUnionLimitWithoutOrderBy(c *gc.C) {
select_queries := make([]SelectStatement, 0, 3)
select_queries := make([]selectStatement, 0, 3)
select_queries = append(select_queries,
table1.Select(table1Col1).Where(GtL(table1Col1, 123)).OrderBy(table1Col2),
@ -448,7 +448,7 @@ func (s *StmtSuite) TestUnionLimitWithoutOrderBy(c *gc.C) {
}
func (s *StmtSuite) TestUnionSelectWithMismatchedColumns(c *gc.C) {
select_queries := make([]SelectStatement, 0, 3)
select_queries := make([]selectStatement, 0, 3)
select_queries = append(select_queries,
@ -463,7 +463,7 @@ func (s *StmtSuite) TestUnionSelectWithMismatchedColumns(c *gc.C) {
q := UNION(select_queries...)
q = q.Where(And(LtL(table1Col1, 1000), GtL(table1Col1, 15)))
q = q.ORDER_BY(Desc(table1Col4), Asc(table1Col3))
q = q.ORDER_BY(DESC(table1Col4), ASC(table1Col3))
q = q.LIMIT(5)
_, err := q.String()
@ -483,7 +483,7 @@ func (s *StmtSuite) TestComplicatedUnionSelectWithWhereStatement(c *gc.C) {
// tests on outer statement: Group By, Order By, LIMIT
// on inner statement: AndWhere, WHERE (with AND), Order By, LIMIT
select_queries := make([]SelectStatement, 0, 3)
select_queries := make([]selectStatement, 0, 3)
// We're not trying to write a SQL parser, so we won't warn if you do something silly like
// try to apply a where clause on more columns than you've selected in your union select
@ -502,7 +502,7 @@ func (s *StmtSuite) TestComplicatedUnionSelectWithWhereStatement(c *gc.C) {
q := UNION(select_queries...)
q = q.Where(And(LtL(table1Col1, 1000), GtL(table1Col1, 15)))
q = q.ORDER_BY(Desc(table1Col4), Asc(table1Col3))
q = q.ORDER_BY(DESC(table1Col4), ASC(table1Col3))
q = q.LIMIT(5)
q = q.GroupBy(table1Col4)

View file

@ -1,30 +1,30 @@
package sqlbuilder
type StringExpression interface {
Expression
type stringExpression interface {
expression
Eq(expression StringExpression) BoolExpression
EqString(value string) BoolExpression
NotEq(expression StringExpression) BoolExpression
NotEqString(value string) BoolExpression
Eq(expression stringExpression) boolExpression
EqString(value string) boolExpression
NotEq(expression stringExpression) boolExpression
NotEqString(value string) boolExpression
}
type stringInterfaceImpl struct {
parent StringExpression
parent stringExpression
}
func (b *stringInterfaceImpl) Eq(expression StringExpression) BoolExpression {
func (b *stringInterfaceImpl) Eq(expression stringExpression) boolExpression {
return Eq(b.parent, expression)
}
func (b *stringInterfaceImpl) EqString(value string) BoolExpression {
func (b *stringInterfaceImpl) EqString(value string) boolExpression {
return EqL(b.parent, value)
}
func (b *stringInterfaceImpl) NotEq(expression StringExpression) BoolExpression {
func (b *stringInterfaceImpl) NotEq(expression stringExpression) boolExpression {
return NotEq(b.parent, expression)
}
func (b *stringInterfaceImpl) NotEqString(value string) BoolExpression {
func (b *stringInterfaceImpl) NotEqString(value string) boolExpression {
return NotEq(b.parent, Literal(value))
}

View file

@ -10,47 +10,47 @@ type tableInterface interface {
SchemaName() string
TableName() string
Columns() []Column
Columns() []column
// Generates the sql string for the current tableName expression.
SerializeSql(out *queryData) error
serializeSql(out *queryData) error
}
// The sql tableName read interface. NOTE: NATURAL JOINs, and join "USING" clause
// are not supported.
type ReadableTable interface {
type readableTable interface {
tableInterface
// Generates a select query on the current tableName.
SELECT(projections ...Projection) SelectStatement
SELECT(projections ...projection) selectStatement
// Creates a inner join tableName expression using onCondition.
INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
INNER_JOIN(table readableTable, onCondition boolExpression) readableTable
// Creates a left join tableName expression using onCondition.
LEFT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
LEFT_JOIN(table readableTable, onCondition boolExpression) readableTable
// Creates a right join tableName expression using onCondition.
RIGHT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
RIGHT_JOIN(table readableTable, onCondition boolExpression) readableTable
FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable
FULL_JOIN(table readableTable, onCondition boolExpression) readableTable
CROSS_JOIN(table ReadableTable) ReadableTable
CROSS_JOIN(table readableTable) readableTable
}
// The sql tableName write interface.
type WritableTable interface {
type writableTable interface {
tableInterface
INSERT(columns ...Column) InsertStatement
UPDATE(columns ...Column) UpdateStatement
DELETE() DeleteStatement
INSERT(columns ...column) insertStatement
UPDATE(columns ...column) updateStatement
DELETE() deleteStatement
LOCK() lockStatement
}
// Defines a physical tableName in the database that is both readable and writable.
// This function will panic if name is not valid
func NewTable(schemaName, name string, columns ...Column) *Table {
func NewTable(schemaName, name string, columns ...column) *Table {
t := &Table{
schemaName: schemaName,
@ -68,10 +68,10 @@ type Table struct {
schemaName string
name string
alias string
columns []Column
columns []column
}
func (t *Table) Column(name string) Column {
func (t *Table) Column(name string) column {
return &baseColumn{
name: name,
nullable: NotNullable,
@ -102,13 +102,13 @@ func (t *Table) SchemaTableName() string {
}
// Returns a list of the tableName's columns
func (t *Table) Columns() []Column {
func (t *Table) Columns() []column {
return t.columns
}
// Generates the sql string for the current tableName expression. Note: the
// generated string may not be a valid/executable sql statement.
func (t *Table) SerializeSql(out *queryData) error {
func (t *Table) serializeSql(out *queryData) error {
if t == nil {
return errors.Newf("nil tableName.")
}
@ -126,51 +126,51 @@ func (t *Table) SerializeSql(out *queryData) error {
}
// Generates a select query on the current tableName.
func (t *Table) SELECT(projections ...Projection) SelectStatement {
func (t *Table) SELECT(projections ...projection) selectStatement {
return newSelectStatement(t, projections)
}
// Creates a inner join tableName expression using onCondition.
func (t *Table) INNER_JOIN(
table ReadableTable,
onCondition BoolExpression) ReadableTable {
table readableTable,
onCondition boolExpression) readableTable {
return InnerJoinOn(t, table, onCondition)
}
// Creates a left join tableName expression using onCondition.
func (t *Table) LEFT_JOIN(
table ReadableTable,
onCondition BoolExpression) ReadableTable {
table readableTable,
onCondition boolExpression) readableTable {
return LeftJoinOn(t, table, onCondition)
}
// Creates a right join tableName expression using onCondition.
func (t *Table) RIGHT_JOIN(
table ReadableTable,
onCondition BoolExpression) ReadableTable {
table readableTable,
onCondition boolExpression) readableTable {
return RightJoinOn(t, table, onCondition)
}
func (t *Table) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
func (t *Table) FULL_JOIN(table readableTable, onCondition boolExpression) readableTable {
return FullJoin(t, table, onCondition)
}
func (t *Table) CROSS_JOIN(table ReadableTable) ReadableTable {
func (t *Table) CROSS_JOIN(table readableTable) readableTable {
return CrossJoin(t, table)
}
func (t *Table) INSERT(columns ...Column) InsertStatement {
func (t *Table) INSERT(columns ...column) insertStatement {
return newInsertStatement(t, columns...)
}
func (t *Table) UPDATE(columns ...Column) UpdateStatement {
func (t *Table) UPDATE(columns ...column) updateStatement {
return newUpdateStatement(t, columns)
}
func (t *Table) DELETE() DeleteStatement {
func (t *Table) DELETE() deleteStatement {
return newDeleteStatement(t)
}
@ -190,17 +190,17 @@ const (
// Join expressions are pseudo readable tables.
type joinTable struct {
lhs ReadableTable
rhs ReadableTable
lhs readableTable
rhs readableTable
join_type joinType
onCondition BoolExpression
onCondition boolExpression
}
func newJoinTable(
lhs ReadableTable,
rhs ReadableTable,
lhs readableTable,
rhs readableTable,
join_type joinType,
onCondition BoolExpression) ReadableTable {
onCondition boolExpression) readableTable {
return &joinTable{
lhs: lhs,
@ -211,40 +211,40 @@ func newJoinTable(
}
func InnerJoinOn(
lhs ReadableTable,
rhs ReadableTable,
onCondition BoolExpression) ReadableTable {
lhs readableTable,
rhs readableTable,
onCondition boolExpression) readableTable {
return newJoinTable(lhs, rhs, INNER_JOIN, onCondition)
}
func LeftJoinOn(
lhs ReadableTable,
rhs ReadableTable,
onCondition BoolExpression) ReadableTable {
lhs readableTable,
rhs readableTable,
onCondition boolExpression) readableTable {
return newJoinTable(lhs, rhs, LEFT_JOIN, onCondition)
}
func RightJoinOn(
lhs ReadableTable,
rhs ReadableTable,
onCondition BoolExpression) ReadableTable {
lhs readableTable,
rhs readableTable,
onCondition boolExpression) readableTable {
return newJoinTable(lhs, rhs, RIGHT_JOIN, onCondition)
}
func FullJoin(
lhs ReadableTable,
rhs ReadableTable,
onCondition BoolExpression) ReadableTable {
lhs readableTable,
rhs readableTable,
onCondition boolExpression) readableTable {
return newJoinTable(lhs, rhs, FULL_JOIN, onCondition)
}
func CrossJoin(
lhs ReadableTable,
rhs ReadableTable) ReadableTable {
lhs readableTable,
rhs readableTable) readableTable {
return newJoinTable(lhs, rhs, CROSS_JOIN, nil)
}
@ -257,22 +257,22 @@ func (t *joinTable) TableName() string {
return ""
}
func (t *joinTable) Columns() []Column {
columns := make([]Column, 0)
func (t *joinTable) Columns() []column {
columns := make([]column, 0)
columns = append(columns, t.lhs.Columns()...)
columns = append(columns, t.rhs.Columns()...)
return columns
}
func (t *joinTable) Column(name string) Column {
func (t *joinTable) Column(name string) column {
return &baseColumn{
name: name,
nullable: NotNullable,
}
}
func (t *joinTable) SerializeSql(out *queryData) (err error) {
func (t *joinTable) serializeSql(out *queryData) (err error) {
if t.lhs == nil {
return errors.Newf("nil lhs.")
@ -284,7 +284,7 @@ func (t *joinTable) SerializeSql(out *queryData) (err error) {
return errors.Newf("nil onCondition.")
}
if err = t.lhs.SerializeSql(out); err != nil {
if err = t.lhs.serializeSql(out); err != nil {
return
}
@ -301,13 +301,13 @@ func (t *joinTable) SerializeSql(out *queryData) (err error) {
out.WriteString(" CROSS JOIN ")
}
if err = t.rhs.SerializeSql(out); err != nil {
if err = t.rhs.serializeSql(out); err != nil {
return
}
if t.onCondition != nil {
out.WriteString(" ON ")
if err = t.onCondition.Serialize(out); err != nil {
if err = t.onCondition.serialize(out); err != nil {
return
}
}
@ -315,35 +315,35 @@ func (t *joinTable) SerializeSql(out *queryData) (err error) {
return nil
}
func (t *joinTable) SELECT(projections ...Projection) SelectStatement {
func (t *joinTable) SELECT(projections ...projection) selectStatement {
return newSelectStatement(t, projections)
}
func (t *joinTable) INNER_JOIN(
table ReadableTable,
onCondition BoolExpression) ReadableTable {
table readableTable,
onCondition boolExpression) readableTable {
return InnerJoinOn(t, table, onCondition)
}
func (t *joinTable) LEFT_JOIN(
table ReadableTable,
onCondition BoolExpression) ReadableTable {
table readableTable,
onCondition boolExpression) readableTable {
return LeftJoinOn(t, table, onCondition)
}
func (t *joinTable) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
func (t *joinTable) FULL_JOIN(table readableTable, onCondition boolExpression) readableTable {
return FullJoin(t, table, onCondition)
}
func (t *joinTable) CROSS_JOIN(table ReadableTable) ReadableTable {
func (t *joinTable) CROSS_JOIN(table readableTable) readableTable {
return CrossJoin(t, table)
}
func (t *joinTable) RIGHT_JOIN(
table ReadableTable,
onCondition BoolExpression) ReadableTable {
table readableTable,
onCondition boolExpression) readableTable {
return RightJoinOn(t, table, onCondition)
}

View file

@ -51,7 +51,7 @@ func (s *TableSuite) TestJoinNilLeftTable(c *gc.C) {
buf := &bytes.Buffer{}
err := join.SerializeSql(buf)
err := join.serializeSql(buf)
c.Assert(err, gc.NotNil)
}
@ -60,7 +60,7 @@ func (s *TableSuite) TestJoinNilRightTable(c *gc.C) {
buf := &bytes.Buffer{}
err := join.SerializeSql(buf)
err := join.serializeSql(buf)
c.Assert(err, gc.NotNil)
}
@ -69,7 +69,7 @@ func (s *TableSuite) TestJoinNilOnCondition(c *gc.C) {
buf := &bytes.Buffer{}
err := join.SerializeSql(buf)
err := join.serializeSql(buf)
c.Assert(err, gc.NotNil)
}
@ -93,7 +93,7 @@ func (s *TableSuite) TestLeftJoin(c *gc.C) {
buf := &bytes.Buffer{}
err := join.SerializeSql(buf)
err := join.serializeSql(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()
@ -109,7 +109,7 @@ func (s *TableSuite) TestRightJoin(c *gc.C) {
buf := &bytes.Buffer{}
err := join.SerializeSql(buf)
err := join.serializeSql(buf)
c.Assert(err, gc.IsNil)
sql := buf.String()

View file

@ -1,51 +1,51 @@
package sqlbuilder
type TimeExpression interface {
Expression
type timeExpression interface {
expression
Eq(expression TimeExpression) BoolExpression
EqL(literal string) BoolExpression
NotEq(expression TimeExpression) BoolExpression
NotEqL(literal string) BoolExpression
GtEq(rhs TimeExpression) BoolExpression
GtEqL(literal string) BoolExpression
LtEq(rhs TimeExpression) BoolExpression
LtEqL(literal string) BoolExpression
Eq(expression timeExpression) boolExpression
EqL(literal string) boolExpression
NotEq(expression timeExpression) boolExpression
NotEqL(literal string) boolExpression
GtEq(rhs timeExpression) boolExpression
GtEqL(literal string) boolExpression
LtEq(rhs timeExpression) boolExpression
LtEqL(literal string) boolExpression
}
type timeInterfaceImpl struct {
parent TimeExpression
parent timeExpression
}
func (t *timeInterfaceImpl) Eq(expression TimeExpression) BoolExpression {
func (t *timeInterfaceImpl) Eq(expression timeExpression) boolExpression {
return Eq(t.parent, expression)
}
func (t *timeInterfaceImpl) EqL(literal string) BoolExpression {
func (t *timeInterfaceImpl) EqL(literal string) boolExpression {
return Eq(t.parent, Literal(literal))
}
func (t *timeInterfaceImpl) NotEq(expression TimeExpression) BoolExpression {
func (t *timeInterfaceImpl) NotEq(expression timeExpression) boolExpression {
return NotEq(t.parent, expression)
}
func (t *timeInterfaceImpl) NotEqL(literal string) BoolExpression {
func (t *timeInterfaceImpl) NotEqL(literal string) boolExpression {
return NotEq(t.parent, Literal(literal))
}
func (t *timeInterfaceImpl) GtEq(expression TimeExpression) BoolExpression {
func (t *timeInterfaceImpl) GtEq(expression timeExpression) boolExpression {
return GtEq(t.parent, expression)
}
func (t *timeInterfaceImpl) GtEqL(literal string) BoolExpression {
func (t *timeInterfaceImpl) GtEqL(literal string) boolExpression {
return GtEq(t.parent, Literal(literal))
}
func (t *timeInterfaceImpl) LtEq(expression TimeExpression) BoolExpression {
func (t *timeInterfaceImpl) LtEq(expression timeExpression) boolExpression {
return LtEq(t.parent, expression)
}
func (t *timeInterfaceImpl) LtEqL(literal string) BoolExpression {
func (t *timeInterfaceImpl) LtEqL(literal string) boolExpression {
return LtEq(t.parent, Literal(literal))
}
@ -57,7 +57,7 @@ type prefixTimeExpression struct {
prefixExpression
}
func newPrefixTimeExpression(expression Expression, operator string) TimeExpression {
func newPrefixTimeExpression(expression expression, operator string) timeExpression {
timeExpr := prefixTimeExpression{}
timeExpr.prefixExpression = newPrefixExpression(expression, operator)
@ -67,6 +67,6 @@ func newPrefixTimeExpression(expression Expression, operator string) TimeExpress
return &timeExpr
}
func INTERVAL(interval string) Expression {
func INTERVAL(interval string) expression {
return newPrefixTimeExpression(Literal(interval), "INTERVAL")
}

View file

@ -3,44 +3,13 @@ package sqlbuilder
// A clause that can be used in orderBy by
// A clause that is selectable.
//type Projection interface {
// Clause
//type projection interface {
// clause
// isProjectionInterface
//
// SerializeSqlForColumnList(out *bytes.Buffer) error
//}
//type ColumnList []Column
//
//func (cl ColumnList) Serialize(out *bytes.Buffer, options ...serializeOption) error {
// for i, column := range cl {
// column.Serialize(out)
//
// if i != len(cl)-1 {
// out.WriteString(", ")
// }
// }
// return nil
//}
//
//func (cl ColumnList) isProjectionType() {
//}
//
//func (cl ColumnList) AS(name string) Clause {
// panic("Unallowed operation ")
//}
//func (cl ColumnList) SerializeSqlForColumnList(out *bytes.Buffer) error {
// for i, column := range cl {
// column.SerializeSqlForColumnList(out)
//
// if i != len(cl)-1 {
// out.WriteString(", ")
// }
// }
// return nil
//}
//
// Boiler plates ...
//

View file

@ -6,15 +6,15 @@ import (
"github.com/sub0zero/go-sqlbuilder/types"
)
type UpdateStatement interface {
Statement
type updateStatement interface {
statement
SET(values ...interface{}) UpdateStatement
WHERE(expression BoolExpression) UpdateStatement
RETURNING(projections ...Projection) UpdateStatement
SET(values ...interface{}) updateStatement
WHERE(expression boolExpression) updateStatement
RETURNING(projections ...projection) updateStatement
}
func newUpdateStatement(table WritableTable, columns []Column) UpdateStatement {
func newUpdateStatement(table writableTable, columns []column) updateStatement {
return &updateStatementImpl{
table: table,
columns: columns,
@ -22,17 +22,17 @@ func newUpdateStatement(table WritableTable, columns []Column) UpdateStatement {
}
type updateStatementImpl struct {
table WritableTable
columns []Column
updateValues []Clause
where BoolExpression
returning []Projection
table writableTable
columns []column
updateValues []clause
where boolExpression
returning []projection
}
func (u *updateStatementImpl) SET(values ...interface{}) UpdateStatement {
func (u *updateStatementImpl) SET(values ...interface{}) updateStatement {
for _, value := range values {
if clause, ok := value.(Clause); ok {
if clause, ok := value.(clause); ok {
u.updateValues = append(u.updateValues, clause)
} else {
u.updateValues = append(u.updateValues, Literal(value))
@ -42,12 +42,12 @@ func (u *updateStatementImpl) SET(values ...interface{}) UpdateStatement {
return u
}
func (u *updateStatementImpl) WHERE(expression BoolExpression) UpdateStatement {
func (u *updateStatementImpl) WHERE(expression boolExpression) updateStatement {
u.where = expression
return u
}
func (u *updateStatementImpl) RETURNING(projections ...Projection) UpdateStatement {
func (u *updateStatementImpl) RETURNING(projections ...projection) updateStatement {
u.returning = defaultProjectionAliasing(projections)
return u
}
@ -62,7 +62,7 @@ func (u *updateStatementImpl) Sql() (sql string, args []interface{}, err error)
return "", nil, errors.New("nil tableName.")
}
if err = u.table.SerializeSql(out); err != nil {
if err = u.table.serializeSql(out); err != nil {
return
}
@ -99,7 +99,7 @@ func (u *updateStatementImpl) Sql() (sql string, args []interface{}, err error)
out.WriteString(", ")
}
err = value.Serialize(out)
err = value.serialize(out)
if err != nil {
return

View file

@ -7,14 +7,14 @@ import (
"github.com/sub0zero/go-sqlbuilder/types"
)
func serializeOrderByClauseList(orderByClauses []OrderByClause, out *queryData) error {
func serializeOrderByClauseList(orderByClauses []orderByClause, out *queryData) error {
for i, value := range orderByClauses {
if i > 0 {
out.WriteString(", ")
}
err := value.Serialize(out)
err := value.serialize(out)
if err != nil {
return err
@ -24,7 +24,7 @@ func serializeOrderByClauseList(orderByClauses []OrderByClause, out *queryData)
return nil
}
func serializeClauseList(clauses []Clause, out *queryData) (err error) {
func serializeGroupByClauseList(clauses []groupByClause, out *queryData) (err error) {
for i, c := range clauses {
if i > 0 {
@ -35,7 +35,7 @@ func serializeClauseList(clauses []Clause, out *queryData) (err error) {
return errors.New("nil clause.")
}
if err = c.Serialize(out); err != nil {
if err = c.serializeForGroupBy(out); err != nil {
return
}
}
@ -43,14 +43,33 @@ func serializeClauseList(clauses []Clause, out *queryData) (err error) {
return nil
}
func serializeExpressionList(expressions []Expression, separator string, out *queryData) error {
func serializeClauseList(clauses []clause, out *queryData) (err error) {
for i, c := range clauses {
if i > 0 {
out.WriteString(", ")
}
if c == nil {
return errors.New("nil clause.")
}
if err = c.serialize(out); err != nil {
return
}
}
return nil
}
func serializeExpressionList(expressions []expression, separator string, out *queryData) error {
for i, value := range expressions {
if i > 0 {
out.WriteString(separator)
}
err := value.Serialize(out)
err := value.serialize(out)
if err != nil {
return err
@ -60,16 +79,16 @@ func serializeExpressionList(expressions []Expression, separator string, out *qu
return nil
}
func serializeProjectionList(projections []Projection, out *queryData) error {
func serializeProjectionList(projections []projection, out *queryData) error {
for i, col := range projections {
if i > 0 {
out.WriteString(", ")
}
if col == nil {
return errors.New("Projection expression is nil.")
return errors.New("projection expression is nil.")
}
if err := col.SerializeForProjection(out); err != nil {
if err := col.serializeForProjection(out); err != nil {
return err
}
}
@ -77,7 +96,7 @@ func serializeProjectionList(projections []Projection, out *queryData) error {
return nil
}
func serializeColumnList(columns []Column, out *queryData) error {
func serializeColumnList(columns []column, out *queryData) error {
for i, col := range columns {
if i > 0 {
out.WriteByte(',')
@ -93,7 +112,7 @@ func serializeColumnList(columns []Column, out *queryData) error {
return nil
}
func Query(statement Statement, db types.Db, destination interface{}) error {
func Query(statement statement, db types.Db, destination interface{}) error {
query, args, err := statement.Sql()
if err != nil {
@ -103,7 +122,7 @@ func Query(statement Statement, db types.Db, destination interface{}) error {
return execution.Query(db, query, args, destination)
}
func Execute(statement Statement, db types.Db) (res sql.Result, err error) {
func Execute(statement statement, db types.Db) (res sql.Result, err error) {
query, args, err := statement.Sql()
if err != nil {