Postgres refactor.
This commit is contained in:
parent
d00167cbba
commit
8519ccbdd0
57 changed files with 2451 additions and 598 deletions
|
|
@ -14,7 +14,7 @@ func newAlias(expression Expression, aliasName string) Projection {
|
|||
|
||||
func (a *alias) fromImpl(subQuery SelectTable) Projection {
|
||||
column := newColumn(a.alias, "", nil)
|
||||
column.parent = &column
|
||||
column.Parent = &column
|
||||
column.subQuery = subQuery
|
||||
|
||||
return &column
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ func (b *boolInterfaceImpl) IS_NOT_UNKNOWN() BoolExpression {
|
|||
|
||||
//---------------------------------------------------//
|
||||
type binaryBoolExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
boolInterfaceImpl
|
||||
|
||||
binaryOpExpression
|
||||
|
|
@ -96,7 +96,7 @@ func newBinaryBoolOperator(lhs, rhs Expression, operator string) BoolExpression
|
|||
binaryBoolExpression := binaryBoolExpression{}
|
||||
|
||||
binaryBoolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator)
|
||||
binaryBoolExpression.expressionInterfaceImpl.parent = &binaryBoolExpression
|
||||
binaryBoolExpression.ExpressionInterfaceImpl.Parent = &binaryBoolExpression
|
||||
binaryBoolExpression.boolInterfaceImpl.parent = &binaryBoolExpression
|
||||
|
||||
return &binaryBoolExpression
|
||||
|
|
@ -104,7 +104,7 @@ func newBinaryBoolOperator(lhs, rhs Expression, operator string) BoolExpression
|
|||
|
||||
//---------------------------------------------------//
|
||||
type prefixBoolExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
boolInterfaceImpl
|
||||
|
||||
prefixOpExpression
|
||||
|
|
@ -114,7 +114,7 @@ func newPrefixBoolOperator(expression Expression, operator string) BoolExpressio
|
|||
exp := prefixBoolExpression{}
|
||||
exp.prefixOpExpression = newPrefixExpression(expression, operator)
|
||||
|
||||
exp.expressionInterfaceImpl.parent = &exp
|
||||
exp.ExpressionInterfaceImpl.Parent = &exp
|
||||
exp.boolInterfaceImpl.parent = &exp
|
||||
|
||||
return &exp
|
||||
|
|
@ -122,7 +122,7 @@ func newPrefixBoolOperator(expression Expression, operator string) BoolExpressio
|
|||
|
||||
//---------------------------------------------------//
|
||||
type postfixBoolOpExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
boolInterfaceImpl
|
||||
|
||||
postfixOpExpression
|
||||
|
|
@ -132,7 +132,7 @@ func newPostifxBoolExpression(expression Expression, operator string) BoolExpres
|
|||
exp := postfixBoolOpExpression{}
|
||||
exp.postfixOpExpression = newPostfixOpExpression(expression, operator)
|
||||
|
||||
exp.expressionInterfaceImpl.parent = &exp
|
||||
exp.ExpressionInterfaceImpl.Parent = &exp
|
||||
exp.boolInterfaceImpl.parent = &exp
|
||||
|
||||
return &exp
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ func (b *CastImpl) AS(castType string) Expression {
|
|||
cast: string(castType),
|
||||
}
|
||||
|
||||
castExp.expressionInterfaceImpl.parent = castExp
|
||||
castExp.ExpressionInterfaceImpl.Parent = castExp
|
||||
|
||||
return castExp
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ func (b *CastImpl) AS_TIME() TimeExpression {
|
|||
}
|
||||
|
||||
type castExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
|
||||
expression Expression
|
||||
cast string
|
||||
|
|
|
|||
|
|
@ -1,270 +1,702 @@
|
|||
package jet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/go-jet/jet/internal/utils"
|
||||
"github.com/google/uuid"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SerializeOption int
|
||||
|
||||
const (
|
||||
noWrap SerializeOption = iota
|
||||
)
|
||||
|
||||
type Clause interface {
|
||||
serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error
|
||||
Serialize(statementType StatementType, out *SqlBuilder) error
|
||||
}
|
||||
|
||||
func Serialize(exp Clause, statementType StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
||||
return exp.serialize(statementType, out, options...)
|
||||
type ClauseWithProjections interface {
|
||||
Clause
|
||||
|
||||
projections() []Projection
|
||||
}
|
||||
|
||||
func contains(options []SerializeOption, option SerializeOption) bool {
|
||||
for _, opt := range options {
|
||||
if opt == option {
|
||||
return true
|
||||
type ClauseSelect struct {
|
||||
Distinct bool
|
||||
Projections []Projection
|
||||
}
|
||||
|
||||
func (s *ClauseSelect) projections() []Projection {
|
||||
return s.Projections
|
||||
}
|
||||
|
||||
func (s *ClauseSelect) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
out.newLine()
|
||||
out.WriteString("SELECT")
|
||||
|
||||
if s.Distinct {
|
||||
out.WriteString("DISTINCT")
|
||||
}
|
||||
|
||||
if len(s.Projections) == 0 {
|
||||
return errors.New("jet: no column selected for Projection")
|
||||
}
|
||||
|
||||
return out.writeProjections(statementType, s.Projections)
|
||||
}
|
||||
|
||||
type ClauseFrom struct {
|
||||
Table Serializer
|
||||
}
|
||||
|
||||
func (f *ClauseFrom) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if f.Table == nil {
|
||||
return nil
|
||||
}
|
||||
return out.writeFrom(statementType, f.Table)
|
||||
}
|
||||
|
||||
type ClauseWhere struct {
|
||||
Condition BoolExpression
|
||||
Mandatory bool
|
||||
}
|
||||
|
||||
func (c *ClauseWhere) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if c.Condition == nil {
|
||||
if c.Mandatory {
|
||||
return errors.New("jet: WHERE clause not set")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return false
|
||||
return out.writeWhere(statementType, c.Condition)
|
||||
}
|
||||
|
||||
type SqlBuilder struct {
|
||||
Dialect Dialect
|
||||
Buff bytes.Buffer
|
||||
Args []interface{}
|
||||
|
||||
lastChar byte
|
||||
ident int
|
||||
type ClauseGroupBy struct {
|
||||
List []GroupByClause
|
||||
}
|
||||
|
||||
func (s *SqlBuilder) DebugSQL() string {
|
||||
return queryStringToDebugString(s.Buff.String(), s.Args, s.Dialect)
|
||||
}
|
||||
|
||||
type StatementType string
|
||||
|
||||
const (
|
||||
SelectStatementType StatementType = "SELECT"
|
||||
InsertStatementType StatementType = "INSERT"
|
||||
UpdateStatementType StatementType = "UPDATE"
|
||||
DeleteStatementType StatementType = "DELETE"
|
||||
SetStatementType StatementType = "SET"
|
||||
LockStatementType StatementType = "LOCK"
|
||||
)
|
||||
|
||||
const defaultIdent = 5
|
||||
|
||||
func (q *SqlBuilder) increaseIdent() {
|
||||
q.ident += defaultIdent
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) decreaseIdent() {
|
||||
if q.ident < defaultIdent {
|
||||
q.ident = 0
|
||||
}
|
||||
|
||||
q.ident -= defaultIdent
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeProjections(statement StatementType, projections []Projection) error {
|
||||
q.increaseIdent()
|
||||
err := SerializeProjectionList(statement, projections, q)
|
||||
q.decreaseIdent()
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeFrom(statement StatementType, table ReadableTable) error {
|
||||
q.newLine()
|
||||
q.WriteString("FROM")
|
||||
|
||||
q.increaseIdent()
|
||||
err := table.serialize(statement, q)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeWhere(statement StatementType, where Expression) error {
|
||||
q.newLine()
|
||||
q.WriteString("WHERE")
|
||||
|
||||
q.increaseIdent()
|
||||
err := where.serialize(statement, q, noWrap)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeGroupBy(statement StatementType, groupBy []groupByClause) error {
|
||||
q.newLine()
|
||||
q.WriteString("GROUP BY")
|
||||
|
||||
q.increaseIdent()
|
||||
err := serializeGroupByClauseList(statement, groupBy, q)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeOrderBy(statement StatementType, orderBy []orderByClause) error {
|
||||
q.newLine()
|
||||
q.WriteString("ORDER BY")
|
||||
|
||||
q.increaseIdent()
|
||||
err := serializeOrderByClauseList(statement, orderBy, q)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeHaving(statement StatementType, having Expression) error {
|
||||
q.newLine()
|
||||
q.WriteString("HAVING")
|
||||
|
||||
q.increaseIdent()
|
||||
err := having.serialize(statement, q, noWrap)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeReturning(statement StatementType, returning []Projection) error {
|
||||
if len(returning) == 0 {
|
||||
func (c *ClauseGroupBy) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if len(c.List) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !q.Dialect.SupportsReturning() {
|
||||
panic("jet: " + q.Dialect.Name() + " dialect does not support RETURNING.")
|
||||
out.newLine()
|
||||
out.WriteString("GROUP BY")
|
||||
|
||||
out.increaseIdent()
|
||||
err := serializeGroupByClauseList(statementType, c.List, out)
|
||||
out.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
type ClauseHaving struct {
|
||||
Condition BoolExpression
|
||||
}
|
||||
|
||||
func (c *ClauseHaving) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if c.Condition == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
q.newLine()
|
||||
q.WriteString("RETURNING")
|
||||
q.increaseIdent()
|
||||
|
||||
return q.writeProjections(statement, returning)
|
||||
return out.writeHaving(statementType, c.Condition)
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) newLine() {
|
||||
q.write([]byte{'\n'})
|
||||
q.write(bytes.Repeat([]byte{' '}, q.ident))
|
||||
type ClauseOrderBy struct {
|
||||
List []OrderByClause
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) write(data []byte) {
|
||||
if len(data) == 0 {
|
||||
func (o *ClauseOrderBy) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if o.List == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return out.writeOrderBy(statementType, o.List)
|
||||
}
|
||||
|
||||
type ClauseLimit struct {
|
||||
Count int64
|
||||
}
|
||||
|
||||
func (l *ClauseLimit) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if l.Count >= 0 {
|
||||
out.newLine()
|
||||
out.WriteString("LIMIT")
|
||||
out.insertParametrizedArgument(l.Count)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseOffset struct {
|
||||
Count int64
|
||||
}
|
||||
|
||||
func (o *ClauseOffset) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if o.Count >= 0 {
|
||||
out.newLine()
|
||||
out.WriteString("OFFSET")
|
||||
out.insertParametrizedArgument(o.Count)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseFor struct {
|
||||
Lock SelectLock
|
||||
}
|
||||
|
||||
func (f *ClauseFor) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if f.Lock == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
out.newLine()
|
||||
out.WriteString("FOR")
|
||||
return f.Lock.serialize(statementType, out)
|
||||
}
|
||||
|
||||
type ClauseSetStmtOperator struct {
|
||||
Operator string
|
||||
All bool
|
||||
Selects []StatementWithProjections
|
||||
OrderBy ClauseOrderBy
|
||||
Limit ClauseLimit
|
||||
Offset ClauseOffset
|
||||
}
|
||||
|
||||
func (s *ClauseSetStmtOperator) projections() []Projection {
|
||||
if len(s.Selects) > 0 {
|
||||
return s.Selects[0].projections()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if len(s.Selects) < 2 {
|
||||
return errors.New("jet: UNION Statement must have at least two SELECT statements")
|
||||
}
|
||||
|
||||
wrap := s.OrderBy.List != nil || s.Limit.Count >= 0 || s.Offset.Count >= 0
|
||||
|
||||
//if wrap {
|
||||
// out.WriteString("(")
|
||||
// out.increaseIdent()
|
||||
//}
|
||||
|
||||
if wrap {
|
||||
out.newLine()
|
||||
out.WriteString("(")
|
||||
out.increaseIdent()
|
||||
}
|
||||
|
||||
for i, selectStmt := range s.Selects {
|
||||
out.newLine()
|
||||
if i > 0 {
|
||||
out.WriteString(s.Operator)
|
||||
|
||||
if s.All {
|
||||
out.WriteString("ALL")
|
||||
}
|
||||
out.newLine()
|
||||
}
|
||||
|
||||
if selectStmt == nil {
|
||||
return errors.New("jet: select statement is nil")
|
||||
}
|
||||
|
||||
err := selectStmt.serialize(statementType, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if wrap {
|
||||
out.decreaseIdent()
|
||||
out.newLine()
|
||||
out.WriteString(")")
|
||||
}
|
||||
|
||||
if err := s.OrderBy.Serialize(statementType, out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Limit.Serialize(statementType, out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.Offset.Serialize(statementType, out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//if wrap {
|
||||
// out.decreaseIdent()
|
||||
// out.newLine()
|
||||
// out.WriteString(")")
|
||||
//}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseUpdate struct {
|
||||
Table SerializerTable
|
||||
}
|
||||
|
||||
func (u *ClauseUpdate) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
out.newLine()
|
||||
out.WriteString("UPDATE")
|
||||
|
||||
if utils.IsNil(u.Table) {
|
||||
return errors.New("jet: table to update is nil")
|
||||
}
|
||||
|
||||
if err := u.Table.serialize(statementType, out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseSet struct {
|
||||
Columns []IColumn
|
||||
Values []Serializer
|
||||
}
|
||||
|
||||
func (s *ClauseSet) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
out.newLine()
|
||||
out.WriteString("SET")
|
||||
|
||||
if len(s.Columns) == 0 {
|
||||
return errors.New("jet: no columns selected")
|
||||
}
|
||||
|
||||
if len(s.Columns) > 1 {
|
||||
out.WriteString("(")
|
||||
}
|
||||
|
||||
err := SerializeColumnNames(s.Columns, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(s.Columns) > 1 {
|
||||
out.WriteString(")")
|
||||
}
|
||||
|
||||
out.WriteString("=")
|
||||
|
||||
if len(s.Values) > 1 {
|
||||
out.WriteString("(")
|
||||
}
|
||||
|
||||
err = SerializeClauseList(statementType, s.Values, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(s.Values) > 1 {
|
||||
out.WriteString(")")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseReturning struct {
|
||||
Projections []Projection
|
||||
}
|
||||
|
||||
func (r *ClauseReturning) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
return out.WriteReturning(statementType, r.Projections)
|
||||
}
|
||||
|
||||
type ClauseInsert struct {
|
||||
Table SerializerTable
|
||||
Columns []IColumn
|
||||
}
|
||||
|
||||
func (i *ClauseInsert) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
out.newLine()
|
||||
out.WriteString("INSERT INTO")
|
||||
|
||||
if utils.IsNil(i.Table) {
|
||||
return errors.New("jet: table is nil")
|
||||
}
|
||||
|
||||
err := i.Table.serialize(statementType, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(i.Columns) > 0 {
|
||||
out.WriteString("(")
|
||||
|
||||
err = SerializeColumnNames(i.Columns, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.WriteString(")")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseValues struct {
|
||||
Rows [][]Serializer
|
||||
}
|
||||
|
||||
func (v *ClauseValues) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if len(v.Rows) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
out.WriteString("VALUES")
|
||||
|
||||
for rowIndex, row := range v.Rows {
|
||||
if rowIndex > 0 {
|
||||
out.WriteString(",")
|
||||
}
|
||||
|
||||
out.increaseIdent()
|
||||
out.newLine()
|
||||
out.WriteString("(")
|
||||
|
||||
err := SerializeClauseList(statementType, row, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.writeByte(')')
|
||||
out.decreaseIdent()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseQuery struct {
|
||||
Query SerializerStatement
|
||||
}
|
||||
|
||||
func (v *ClauseQuery) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if v.Query == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return v.Query.serialize(statementType, out)
|
||||
}
|
||||
|
||||
type ClauseDelete struct {
|
||||
Table SerializerTable
|
||||
}
|
||||
|
||||
func (d *ClauseDelete) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
out.newLine()
|
||||
out.WriteString("DELETE FROM")
|
||||
|
||||
if d.Table == nil {
|
||||
return errors.New("jet: nil tableName")
|
||||
}
|
||||
|
||||
if err := d.Table.serialize(statementType, out); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseStatementBegin struct {
|
||||
Name string
|
||||
Tables []SerializerTable
|
||||
}
|
||||
|
||||
func (d *ClauseStatementBegin) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
out.newLine()
|
||||
out.WriteString(d.Name)
|
||||
|
||||
for i, table := range d.Tables {
|
||||
if i > 0 {
|
||||
out.WriteString(", ")
|
||||
}
|
||||
|
||||
err := table.serialize(statementType, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseString struct {
|
||||
Name string
|
||||
Data string
|
||||
}
|
||||
|
||||
func (d *ClauseString) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
out.newLine()
|
||||
out.WriteString(d.Name)
|
||||
out.WriteString(d.Data)
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseOptional struct {
|
||||
Name string
|
||||
Show bool
|
||||
}
|
||||
|
||||
func (d *ClauseOptional) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if !d.Show {
|
||||
return nil
|
||||
}
|
||||
//out.newLine()
|
||||
out.WriteString(d.Name)
|
||||
return nil
|
||||
}
|
||||
|
||||
type ClauseIn struct {
|
||||
LockMode string
|
||||
}
|
||||
|
||||
func (i *ClauseIn) Serialize(statementType StatementType, out *SqlBuilder) error {
|
||||
if i.LockMode == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
out.WriteString("IN")
|
||||
out.WriteString(string(i.LockMode))
|
||||
out.WriteString("MODE")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewTable creates new table with schema Name, table Name and list of columns
|
||||
func NewTable2(Dialect Dialect, schemaName, name string, columns ...Column) TableImpl2 {
|
||||
|
||||
t := TableImpl2{
|
||||
Dialect: Dialect,
|
||||
schemaName: schemaName,
|
||||
name: name,
|
||||
columnList: columns,
|
||||
}
|
||||
|
||||
for _, c := range columns {
|
||||
c.SetTableName(name)
|
||||
}
|
||||
|
||||
return t
|
||||
}
|
||||
|
||||
type TableImpl2 struct {
|
||||
Dialect Dialect
|
||||
schemaName string
|
||||
name string
|
||||
alias string
|
||||
columnList []Column
|
||||
}
|
||||
|
||||
func (t *TableImpl2) AS(alias string) {
|
||||
t.alias = alias
|
||||
|
||||
for _, c := range t.columnList {
|
||||
c.SetTableName(alias)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *TableImpl2) SchemaName() string {
|
||||
return t.schemaName
|
||||
}
|
||||
|
||||
func (t *TableImpl2) TableName() string {
|
||||
return t.name
|
||||
}
|
||||
|
||||
func (t *TableImpl2) Columns() []IColumn {
|
||||
ret := []IColumn{}
|
||||
|
||||
for _, col := range t.columnList {
|
||||
ret = append(ret, col)
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func (t *TableImpl2) dialect() Dialect {
|
||||
return t.Dialect
|
||||
}
|
||||
|
||||
func (t *TableImpl2) accept(visitor visitor) {
|
||||
visitor.visit(t)
|
||||
}
|
||||
|
||||
func (t *TableImpl2) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
||||
if t == nil {
|
||||
return errors.New("jet: tableImpl is nil. ")
|
||||
}
|
||||
|
||||
out.writeIdentifier(t.schemaName)
|
||||
out.WriteString(".")
|
||||
out.writeIdentifier(t.name)
|
||||
|
||||
if len(t.alias) > 0 {
|
||||
out.WriteString("AS")
|
||||
out.writeIdentifier(t.alias)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Join expressions are pseudo readable tables.
|
||||
type JoinTableImpl struct {
|
||||
lhs Serializer
|
||||
rhs Serializer
|
||||
joinType JoinType
|
||||
onCondition BoolExpression
|
||||
}
|
||||
|
||||
func NewJoinTableImpl(lhs Serializer, rhs Serializer, joinType JoinType, onCondition BoolExpression) JoinTableImpl {
|
||||
|
||||
joinTable := JoinTableImpl{
|
||||
lhs: lhs,
|
||||
rhs: rhs,
|
||||
joinType: joinType,
|
||||
onCondition: onCondition,
|
||||
}
|
||||
|
||||
return joinTable
|
||||
}
|
||||
|
||||
func (t *JoinTableImpl) SchemaName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (t *JoinTableImpl) TableName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (t *JoinTableImpl) columns() []IColumn {
|
||||
//return append(t.lhs.columns(), t.rhs.columns()...)
|
||||
panic("Unimplemented")
|
||||
}
|
||||
|
||||
func (t *JoinTableImpl) accept(visitor visitor) {
|
||||
//t.lhs.accept(visitor)
|
||||
//t.rhs.accept(visitor)
|
||||
//TODO: uncoment
|
||||
}
|
||||
|
||||
func (t *JoinTableImpl) dialect() Dialect {
|
||||
return detectDialect(t)
|
||||
}
|
||||
|
||||
func (t *JoinTableImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) (err error) {
|
||||
if t == nil {
|
||||
return errors.New("jet: Join table is nil. ")
|
||||
}
|
||||
|
||||
if utils.IsNil(t.lhs) {
|
||||
return errors.New("jet: left hand side of join operation is nil table")
|
||||
}
|
||||
|
||||
if err = t.lhs.serialize(statement, out); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !isPreSeparator(q.lastChar) && !isPostSeparator(data[0]) && q.Buff.Len() > 0 {
|
||||
q.Buff.WriteByte(' ')
|
||||
out.newLine()
|
||||
|
||||
switch t.joinType {
|
||||
case InnerJoin:
|
||||
out.WriteString("INNER JOIN")
|
||||
case LeftJoin:
|
||||
out.WriteString("LEFT JOIN")
|
||||
case RightJoin:
|
||||
out.WriteString("RIGHT JOIN")
|
||||
case FullJoin:
|
||||
out.WriteString("FULL JOIN")
|
||||
case CrossJoin:
|
||||
out.WriteString("CROSS JOIN")
|
||||
}
|
||||
|
||||
q.Buff.Write(data)
|
||||
q.lastChar = data[len(data)-1]
|
||||
}
|
||||
|
||||
func isPreSeparator(b byte) bool {
|
||||
return b == ' ' || b == '.' || b == ',' || b == '(' || b == '\n' || b == ':'
|
||||
}
|
||||
|
||||
func isPostSeparator(b byte) bool {
|
||||
return b == ' ' || b == '.' || b == ',' || b == ')' || b == '\n' || b == ':'
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeAlias(str string) {
|
||||
aliasQuoteChar := string(q.Dialect.AliasQuoteChar())
|
||||
q.WriteString(aliasQuoteChar + str + aliasQuoteChar)
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) WriteString(str string) {
|
||||
q.write([]byte(str))
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeIdentifier(name string, alwaysQuote ...bool) {
|
||||
quoteWrap := name != strings.ToLower(name) || strings.ContainsAny(name, ". -")
|
||||
|
||||
if quoteWrap || len(alwaysQuote) > 0 {
|
||||
identQuoteChar := string(q.Dialect.IdentifierQuoteChar())
|
||||
q.WriteString(identQuoteChar + name + identQuoteChar)
|
||||
} else {
|
||||
q.WriteString(name)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeByte(b byte) {
|
||||
q.write([]byte{b})
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) finalize() (string, []interface{}) {
|
||||
return q.Buff.String() + ";\n", q.Args
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) insertConstantArgument(arg interface{}) {
|
||||
q.WriteString(argToString(arg))
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) insertParametrizedArgument(arg interface{}) {
|
||||
q.Args = append(q.Args, arg)
|
||||
argPlaceholder := q.Dialect.ArgumentPlaceholder()(len(q.Args))
|
||||
|
||||
q.WriteString(argPlaceholder)
|
||||
}
|
||||
|
||||
func argToString(value interface{}) string {
|
||||
if utils.IsNil(value) {
|
||||
return "NULL"
|
||||
if utils.IsNil(t.rhs) {
|
||||
return errors.New("jet: right hand side of join operation is nil table")
|
||||
}
|
||||
|
||||
switch bindVal := value.(type) {
|
||||
case bool:
|
||||
if bindVal {
|
||||
return "TRUE"
|
||||
if err = t.rhs.serialize(statement, out); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if t.onCondition == nil && t.joinType != CrossJoin {
|
||||
return errors.New("jet: join condition is nil")
|
||||
}
|
||||
|
||||
if t.onCondition != nil {
|
||||
out.WriteString("ON")
|
||||
if err = t.onCondition.serialize(statement, out); err != nil {
|
||||
return
|
||||
}
|
||||
return "FALSE"
|
||||
case int8:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
case int:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
case int16:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
case int32:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
case int64:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
|
||||
case uint8:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
case uint:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
case uint16:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
case uint32:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
case uint64:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
|
||||
case float32:
|
||||
return strconv.FormatFloat(float64(bindVal), 'f', -1, 64)
|
||||
case float64:
|
||||
return strconv.FormatFloat(float64(bindVal), 'f', -1, 64)
|
||||
|
||||
case string:
|
||||
return stringQuote(bindVal)
|
||||
case []byte:
|
||||
return stringQuote(string(bindVal))
|
||||
case uuid.UUID:
|
||||
return stringQuote(bindVal.String())
|
||||
case time.Time:
|
||||
return stringQuote(string(utils.FormatTimestamp(bindVal)))
|
||||
default:
|
||||
return "[Unsupported type]"
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func stringQuote(value string) string {
|
||||
return `'` + strings.Replace(value, "'", "''", -1) + `'`
|
||||
// SelectTable is interface for SELECT sub-queries
|
||||
type SelectTable interface {
|
||||
Alias() string
|
||||
AllColumns() ProjectionList
|
||||
}
|
||||
|
||||
type SelectTableImpl2 struct {
|
||||
selectStmt StatementWithProjections
|
||||
alias string
|
||||
|
||||
projections []Projection
|
||||
}
|
||||
|
||||
func NewSelectTable(selectStmt StatementWithProjections, alias string) SelectTableImpl2 {
|
||||
selectTable := SelectTableImpl2{selectStmt: selectStmt, alias: alias}
|
||||
|
||||
for _, projection := range selectStmt.projections() {
|
||||
newProjection := projection.fromImpl(&selectTable)
|
||||
|
||||
selectTable.projections = append(selectTable.projections, newProjection)
|
||||
}
|
||||
|
||||
return selectTable
|
||||
}
|
||||
|
||||
func (s *SelectTableImpl2) Alias() string {
|
||||
return s.alias
|
||||
}
|
||||
|
||||
func (s *SelectTableImpl2) columns() []IColumn {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SelectTableImpl2) accept(visitor visitor) {
|
||||
visitor.visit(s)
|
||||
s.selectStmt.accept(visitor)
|
||||
}
|
||||
|
||||
func (s *SelectTableImpl2) dialect() Dialect {
|
||||
return detectDialect(s.selectStmt)
|
||||
}
|
||||
|
||||
func (s *SelectTableImpl2) AllColumns() ProjectionList {
|
||||
return s.projections
|
||||
}
|
||||
|
||||
func (s *SelectTableImpl2) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
||||
if s == nil {
|
||||
return errors.New("jet: Expression table is nil. ")
|
||||
}
|
||||
|
||||
err := s.selectStmt.serialize(statement, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.WriteString("AS")
|
||||
out.writeIdentifier(s.alias)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ type Column interface {
|
|||
|
||||
// The base type for real materialized columns.
|
||||
type columnImpl struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
noOpVisitorImpl
|
||||
|
||||
name string
|
||||
|
|
@ -34,7 +34,7 @@ func newColumn(name string, tableName string, parent Column) columnImpl {
|
|||
tableName: tableName,
|
||||
}
|
||||
|
||||
bc.expressionInterfaceImpl.parent = parent
|
||||
bc.ExpressionInterfaceImpl.Parent = parent
|
||||
|
||||
return bc
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import "testing"
|
|||
|
||||
func TestColumn(t *testing.T) {
|
||||
column := newColumn("col", "", nil)
|
||||
column.expressionInterfaceImpl.parent = &column
|
||||
column.ExpressionInterfaceImpl.Parent = &column
|
||||
|
||||
assertClauseSerialize(t, column, "col")
|
||||
column.SetTableName("table1")
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ func (d *deleteStatementImpl) serializeImpl(out *SqlBuilder) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := out.writeReturning(DeleteStatementType, d.returning); err != nil {
|
||||
if err := out.WriteReturning(DeleteStatementType, d.returning); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ type Dialect interface {
|
|||
AliasQuoteChar() byte
|
||||
IdentifierQuoteChar() byte
|
||||
ArgumentPlaceholder() QueryPlaceholderFunc
|
||||
SetClause() func(columns []IColumn, values []Clause, out *SqlBuilder) (err error)
|
||||
SetClause() func(columns []IColumn, values []Serializer, out *SqlBuilder) (err error)
|
||||
SupportsReturning() bool
|
||||
}
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ type SerializeFunc func(statement StatementType, out *SqlBuilder, options ...Ser
|
|||
type SerializeOverride func(expressions ...Expression) SerializeFunc
|
||||
|
||||
type QueryPlaceholderFunc func(ord int) string
|
||||
type UpdateAssigmentFunc func(columns []IColumn, values []Clause, out *SqlBuilder) (err error)
|
||||
type UpdateAssigmentFunc func(columns []IColumn, values []Serializer, out *SqlBuilder) (err error)
|
||||
|
||||
type DialectParams struct {
|
||||
Name string
|
||||
|
|
@ -38,7 +38,7 @@ type DialectParams struct {
|
|||
AliasQuoteChar byte
|
||||
IdentifierQuoteChar byte
|
||||
ArgumentPlaceholder QueryPlaceholderFunc
|
||||
SetClause func(columns []IColumn, values []Clause, out *SqlBuilder) (err error)
|
||||
SetClause func(columns []IColumn, values []Serializer, out *SqlBuilder) (err error)
|
||||
|
||||
SupportsReturning bool
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ func (d *dialectImpl) ArgumentPlaceholder() QueryPlaceholderFunc {
|
|||
return d.argumentPlaceholder
|
||||
}
|
||||
|
||||
func (d *dialectImpl) SetClause() func(columns []IColumn, values []Clause, out *SqlBuilder) (err error) {
|
||||
func (d *dialectImpl) SetClause() func(columns []IColumn, values []Serializer, out *SqlBuilder) (err error) {
|
||||
if d.setClause != nil {
|
||||
return d.setClause
|
||||
}
|
||||
|
|
@ -103,7 +103,7 @@ func (d *dialectImpl) SupportsReturning() bool {
|
|||
return d.supportsReturning
|
||||
}
|
||||
|
||||
func setClause(columns []IColumn, values []Clause, out *SqlBuilder) (err error) {
|
||||
func setClause(columns []IColumn, values []Serializer, out *SqlBuilder) (err error) {
|
||||
|
||||
if len(columns) != len(values) {
|
||||
return errors.New("jet: mismatch in numers of columns and values")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package jet
|
||||
|
||||
type enumValue struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
stringInterfaceImpl
|
||||
noOpVisitorImpl
|
||||
|
||||
|
|
@ -12,7 +12,7 @@ type enumValue struct {
|
|||
func NewEnumValue(name string) StringExpression {
|
||||
enumValue := &enumValue{name: name}
|
||||
|
||||
enumValue.expressionInterfaceImpl.parent = enumValue
|
||||
enumValue.ExpressionInterfaceImpl.Parent = enumValue
|
||||
enumValue.stringInterfaceImpl.parent = enumValue
|
||||
|
||||
return enumValue
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ import (
|
|||
type Expression interface {
|
||||
acceptsVisitor
|
||||
|
||||
expression
|
||||
IExpression
|
||||
}
|
||||
|
||||
type expression interface {
|
||||
Clause
|
||||
type IExpression interface {
|
||||
Serializer
|
||||
Projection
|
||||
groupByClause
|
||||
orderByClause
|
||||
GroupByClause
|
||||
OrderByClause
|
||||
|
||||
// Test expression whether it is a NULL value.
|
||||
IS_NULL() BoolExpression
|
||||
|
|
@ -32,57 +32,57 @@ type expression interface {
|
|||
AS(alias string) Projection
|
||||
|
||||
// Expression will be used to sort query result in ascending order
|
||||
ASC() orderByClause
|
||||
ASC() OrderByClause
|
||||
// Expression will be used to sort query result in ascending order
|
||||
DESC() orderByClause
|
||||
DESC() OrderByClause
|
||||
}
|
||||
|
||||
type expressionInterfaceImpl struct {
|
||||
parent Expression
|
||||
type ExpressionInterfaceImpl struct {
|
||||
Parent Expression
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) fromImpl(subQuery SelectTable) Projection {
|
||||
return e.parent
|
||||
func (e *ExpressionInterfaceImpl) fromImpl(subQuery SelectTable) Projection {
|
||||
return e.Parent
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) IS_NULL() BoolExpression {
|
||||
return newPostifxBoolExpression(e.parent, "IS NULL")
|
||||
func (e *ExpressionInterfaceImpl) IS_NULL() BoolExpression {
|
||||
return newPostifxBoolExpression(e.Parent, "IS NULL")
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) IS_NOT_NULL() BoolExpression {
|
||||
return newPostifxBoolExpression(e.parent, "IS NOT NULL")
|
||||
func (e *ExpressionInterfaceImpl) IS_NOT_NULL() BoolExpression {
|
||||
return newPostifxBoolExpression(e.Parent, "IS NOT NULL")
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) IN(expressions ...Expression) BoolExpression {
|
||||
return newBinaryBoolOperator(e.parent, WRAP(expressions...), "IN")
|
||||
func (e *ExpressionInterfaceImpl) IN(expressions ...Expression) BoolExpression {
|
||||
return newBinaryBoolOperator(e.Parent, WRAP(expressions...), "IN")
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) NOT_IN(expressions ...Expression) BoolExpression {
|
||||
return newBinaryBoolOperator(e.parent, WRAP(expressions...), "NOT IN")
|
||||
func (e *ExpressionInterfaceImpl) NOT_IN(expressions ...Expression) BoolExpression {
|
||||
return newBinaryBoolOperator(e.Parent, WRAP(expressions...), "NOT IN")
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) AS(alias string) Projection {
|
||||
return newAlias(e.parent, alias)
|
||||
func (e *ExpressionInterfaceImpl) AS(alias string) Projection {
|
||||
return newAlias(e.Parent, alias)
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) ASC() orderByClause {
|
||||
return newOrderByClause(e.parent, true)
|
||||
func (e *ExpressionInterfaceImpl) ASC() OrderByClause {
|
||||
return newOrderByClause(e.Parent, true)
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) DESC() orderByClause {
|
||||
return newOrderByClause(e.parent, false)
|
||||
func (e *ExpressionInterfaceImpl) DESC() OrderByClause {
|
||||
return newOrderByClause(e.Parent, false)
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) serializeForGroupBy(statement StatementType, out *SqlBuilder) error {
|
||||
return e.parent.serialize(statement, out, noWrap)
|
||||
func (e *ExpressionInterfaceImpl) serializeForGroupBy(statement StatementType, out *SqlBuilder) error {
|
||||
return e.Parent.serialize(statement, out, noWrap)
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) serializeForProjection(statement StatementType, out *SqlBuilder) error {
|
||||
return e.parent.serialize(statement, out, noWrap)
|
||||
func (e *ExpressionInterfaceImpl) serializeForProjection(statement StatementType, out *SqlBuilder) error {
|
||||
return e.Parent.serialize(statement, out, noWrap)
|
||||
}
|
||||
|
||||
func (e *expressionInterfaceImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) error {
|
||||
return e.parent.serialize(statement, out, noWrap)
|
||||
func (e *ExpressionInterfaceImpl) serializeForOrderBy(statement StatementType, out *SqlBuilder) error {
|
||||
return e.Parent.serialize(statement, out, noWrap)
|
||||
}
|
||||
|
||||
// Representation of binary operations (e.g. comparisons, arithmetic)
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ func (n *floatInterfaceImpl) POW(expression NumericExpression) FloatExpression {
|
|||
|
||||
//---------------------------------------------------//
|
||||
type binaryFloatExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
floatInterfaceImpl
|
||||
|
||||
binaryOpExpression
|
||||
|
|
@ -97,7 +97,7 @@ func newBinaryFloatExpression(lhs, rhs Expression, operator string) FloatExpress
|
|||
|
||||
floatExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator)
|
||||
|
||||
floatExpression.expressionInterfaceImpl.parent = &floatExpression
|
||||
floatExpression.ExpressionInterfaceImpl.Parent = &floatExpression
|
||||
floatExpression.floatInterfaceImpl.parent = &floatExpression
|
||||
|
||||
return &floatExpression
|
||||
|
|
|
|||
|
|
@ -478,7 +478,7 @@ func LEAST(value Expression, values ...Expression) Expression {
|
|||
//--------------------------------------------------------------------//
|
||||
|
||||
type funcExpressionImpl struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
|
||||
name string
|
||||
expressions []Expression
|
||||
|
|
@ -492,9 +492,9 @@ func newFunc(name string, expressions []Expression, parent Expression) *funcExpr
|
|||
}
|
||||
|
||||
if parent != nil {
|
||||
funcExp.expressionInterfaceImpl.parent = parent
|
||||
funcExp.ExpressionInterfaceImpl.Parent = parent
|
||||
} else {
|
||||
funcExp.expressionInterfaceImpl.parent = funcExp
|
||||
funcExp.ExpressionInterfaceImpl.Parent = funcExp
|
||||
}
|
||||
|
||||
return funcExp
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
package jet
|
||||
|
||||
type groupByClause interface {
|
||||
type GroupByClause interface {
|
||||
serializeForGroupBy(statement StatementType, out *SqlBuilder) error
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,23 +35,23 @@ func newInsertStatement(t WritableTable, columns []IColumn) InsertStatement {
|
|||
type insertStatementImpl struct {
|
||||
table WritableTable
|
||||
columns []IColumn
|
||||
rows [][]Clause
|
||||
rows [][]Serializer
|
||||
query SelectStatement
|
||||
returning []Projection
|
||||
}
|
||||
|
||||
func (i *insertStatementImpl) VALUES(value interface{}, values ...interface{}) InsertStatement {
|
||||
i.rows = append(i.rows, unwindRowFromValues(value, values))
|
||||
i.rows = append(i.rows, UnwindRowFromValues(value, values))
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *insertStatementImpl) MODEL(data interface{}) InsertStatement {
|
||||
i.rows = append(i.rows, unwindRowFromModel(i.getColumns(), data))
|
||||
i.rows = append(i.rows, UnwindRowFromModel(i.getColumns(), data))
|
||||
return i
|
||||
}
|
||||
|
||||
func (i *insertStatementImpl) MODELS(data interface{}) InsertStatement {
|
||||
i.rows = append(i.rows, unwindRowsFromModels(i.getColumns(), data)...)
|
||||
i.rows = append(i.rows, UnwindRowsFromModels(i.getColumns(), data)...)
|
||||
return i
|
||||
}
|
||||
|
||||
|
|
@ -113,6 +113,8 @@ func (i *insertStatementImpl) Sql(dialect ...Dialect) (query string, args []inte
|
|||
out.WriteString(")")
|
||||
}
|
||||
|
||||
//TODO:
|
||||
|
||||
if len(i.rows) == 0 && i.query == nil {
|
||||
return "", nil, errors.New("jet: no row values or query specified")
|
||||
}
|
||||
|
|
@ -152,7 +154,7 @@ func (i *insertStatementImpl) Sql(dialect ...Dialect) (query string, args []inte
|
|||
}
|
||||
}
|
||||
|
||||
if err = out.writeReturning(InsertStatementType, i.returning); err != nil {
|
||||
if err = out.WriteReturning(InsertStatementType, i.returning); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@ func TestInsertValuesFromModel(t *testing.T) {
|
|||
MODEL(&toInsert)
|
||||
|
||||
expectedSQL := `
|
||||
INSERT INTO db.table1 (col1, col_float) VALUES
|
||||
($1, $2),
|
||||
($3, $4);
|
||||
INSERT INTO db.table1 (col1, col_float)
|
||||
VALUES ($1, $2),
|
||||
($3, $4);
|
||||
`
|
||||
|
||||
assertStatement(t, stmt, expectedSQL, int(1), float64(1.11), int(1), float64(1.11))
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ func (i *integerInterfaceImpl) BIT_SHIFT_RIGHT(intExpression IntegerExpression)
|
|||
|
||||
//---------------------------------------------------//
|
||||
type binaryIntegerExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
integerInterfaceImpl
|
||||
|
||||
binaryOpExpression
|
||||
|
|
@ -140,7 +140,7 @@ type binaryIntegerExpression struct {
|
|||
func newBinaryIntegerExpression(lhs, rhs IntegerExpression, operator string) IntegerExpression {
|
||||
integerExpression := binaryIntegerExpression{}
|
||||
|
||||
integerExpression.expressionInterfaceImpl.parent = &integerExpression
|
||||
integerExpression.ExpressionInterfaceImpl.Parent = &integerExpression
|
||||
integerExpression.integerInterfaceImpl.parent = &integerExpression
|
||||
|
||||
integerExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator)
|
||||
|
|
@ -150,7 +150,7 @@ func newBinaryIntegerExpression(lhs, rhs IntegerExpression, operator string) Int
|
|||
|
||||
//---------------------------------------------------//
|
||||
type prefixIntegerOpExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
integerInterfaceImpl
|
||||
|
||||
prefixOpExpression
|
||||
|
|
@ -160,7 +160,7 @@ func newPrefixIntegerOperator(expression IntegerExpression, operator string) Int
|
|||
integerExpression := prefixIntegerOpExpression{}
|
||||
integerExpression.prefixOpExpression = newPrefixExpression(expression, operator)
|
||||
|
||||
integerExpression.expressionInterfaceImpl.parent = &integerExpression
|
||||
integerExpression.ExpressionInterfaceImpl.Parent = &integerExpression
|
||||
integerExpression.integerInterfaceImpl.parent = &integerExpression
|
||||
|
||||
return &integerExpression
|
||||
|
|
@ -168,7 +168,7 @@ func newPrefixIntegerOperator(expression IntegerExpression, operator string) Int
|
|||
|
||||
//---------------------------------------------------//
|
||||
type prefixFloatOpExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
floatInterfaceImpl
|
||||
|
||||
prefixOpExpression
|
||||
|
|
@ -178,7 +178,7 @@ func newPrefixFloatOperator(expression FloatExpression, operator string) FloatEx
|
|||
floatOpExpression := prefixFloatOpExpression{}
|
||||
floatOpExpression.prefixOpExpression = newPrefixExpression(expression, operator)
|
||||
|
||||
floatOpExpression.expressionInterfaceImpl.parent = &floatOpExpression
|
||||
floatOpExpression.ExpressionInterfaceImpl.Parent = &floatOpExpression
|
||||
floatOpExpression.floatInterfaceImpl.parent = &floatOpExpression
|
||||
|
||||
return &floatOpExpression
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ type LiteralExpression interface {
|
|||
}
|
||||
|
||||
type literalExpressionImpl struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
noOpVisitorImpl
|
||||
|
||||
value interface{}
|
||||
|
|
@ -29,7 +29,7 @@ func literal(value interface{}, optionalConstant ...bool) *literalExpressionImpl
|
|||
exp.constant = optionalConstant[0]
|
||||
}
|
||||
|
||||
exp.expressionInterfaceImpl.parent = &exp
|
||||
exp.ExpressionInterfaceImpl.Parent = &exp
|
||||
|
||||
return &exp
|
||||
}
|
||||
|
|
@ -73,7 +73,7 @@ func Int(value int64, constant ...bool) IntegerExpression {
|
|||
numLiteral.constant = true
|
||||
}
|
||||
|
||||
numLiteral.literalExpressionImpl.parent = numLiteral
|
||||
numLiteral.literalExpressionImpl.Parent = numLiteral
|
||||
numLiteral.integerInterfaceImpl.parent = numLiteral
|
||||
|
||||
return numLiteral
|
||||
|
|
@ -204,14 +204,14 @@ func DateT(t time.Time) DateExpression {
|
|||
|
||||
//--------------------------------------------------//
|
||||
type nullLiteral struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
noOpVisitorImpl
|
||||
}
|
||||
|
||||
func newNullLiteral() Expression {
|
||||
nullExpression := &nullLiteral{}
|
||||
|
||||
nullExpression.expressionInterfaceImpl.parent = nullExpression
|
||||
nullExpression.ExpressionInterfaceImpl.Parent = nullExpression
|
||||
|
||||
return nullExpression
|
||||
}
|
||||
|
|
@ -223,14 +223,14 @@ func (n *nullLiteral) serialize(statement StatementType, out *SqlBuilder, option
|
|||
|
||||
//--------------------------------------------------//
|
||||
type starLiteral struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
noOpVisitorImpl
|
||||
}
|
||||
|
||||
func newStarLiteral() Expression {
|
||||
starExpression := &starLiteral{}
|
||||
|
||||
starExpression.expressionInterfaceImpl.parent = starExpression
|
||||
starExpression.ExpressionInterfaceImpl.Parent = starExpression
|
||||
|
||||
return starExpression
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ func (n *starLiteral) serialize(statement StatementType, out *SqlBuilder, option
|
|||
//---------------------------------------------------//
|
||||
|
||||
type wrap struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
expressions []Expression
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ func (n *wrap) serialize(statement StatementType, out *SqlBuilder, options ...Se
|
|||
// WRAP wraps list of expressions with brackets '(' and ')'
|
||||
func WRAP(expression ...Expression) Expression {
|
||||
wrap := &wrap{expressions: expression}
|
||||
wrap.expressionInterfaceImpl.parent = wrap
|
||||
wrap.ExpressionInterfaceImpl.Parent = wrap
|
||||
|
||||
return wrap
|
||||
}
|
||||
|
|
@ -271,7 +271,7 @@ func WRAP(expression ...Expression) Expression {
|
|||
//---------------------------------------------------//
|
||||
|
||||
type rawExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
noOpVisitorImpl
|
||||
|
||||
raw string
|
||||
|
|
@ -286,7 +286,7 @@ func (n *rawExpression) serialize(statement StatementType, out *SqlBuilder, opti
|
|||
// For example: Raw("current_database()")
|
||||
func Raw(raw string) Expression {
|
||||
rawExp := &rawExpression{raw: raw}
|
||||
rawExp.expressionInterfaceImpl.parent = rawExp
|
||||
rawExp.ExpressionInterfaceImpl.Parent = rawExp
|
||||
|
||||
return rawExp
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ type CaseOperator interface {
|
|||
}
|
||||
|
||||
type caseOperatorImpl struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
|
||||
expression Expression
|
||||
when []Expression
|
||||
|
|
@ -87,7 +87,7 @@ func CASE(expression ...Expression) CaseOperator {
|
|||
caseExp.expression = expression[0]
|
||||
}
|
||||
|
||||
caseExp.expressionInterfaceImpl.parent = caseExp
|
||||
caseExp.ExpressionInterfaceImpl.Parent = caseExp
|
||||
|
||||
return caseExp
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package jet
|
|||
import "errors"
|
||||
|
||||
// OrderByClause
|
||||
type orderByClause interface {
|
||||
type OrderByClause interface {
|
||||
serializeForOrderBy(statement StatementType, out *SqlBuilder) error
|
||||
}
|
||||
|
||||
|
|
@ -30,6 +30,6 @@ func (o *orderByClauseImpl) serializeForOrderBy(statement StatementType, out *Sq
|
|||
return nil
|
||||
}
|
||||
|
||||
func newOrderByClause(expression Expression, ascent bool) orderByClause {
|
||||
func newOrderByClause(expression Expression, ascent bool) OrderByClause {
|
||||
return &orderByClauseImpl{expression: expression, ascent: ascent}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,14 +10,14 @@ import (
|
|||
// SelectStatement is interface for SQL SELECT statements
|
||||
type SelectStatement interface {
|
||||
Statement
|
||||
expression
|
||||
IExpression
|
||||
|
||||
DISTINCT() SelectStatement
|
||||
FROM(table ReadableTable) SelectStatement
|
||||
WHERE(expression BoolExpression) SelectStatement
|
||||
GROUP_BY(groupByClauses ...groupByClause) SelectStatement
|
||||
GROUP_BY(groupByClauses ...GroupByClause) SelectStatement
|
||||
HAVING(boolExpression BoolExpression) SelectStatement
|
||||
ORDER_BY(orderByClauses ...orderByClause) SelectStatement
|
||||
ORDER_BY(orderByClauses ...OrderByClause) SelectStatement
|
||||
LIMIT(limit int64) SelectStatement
|
||||
OFFSET(offset int64) SelectStatement
|
||||
FOR(lock SelectLock) SelectStatement
|
||||
|
|
@ -40,17 +40,17 @@ func SELECT(projection1 Projection, projections ...Projection) SelectStatement {
|
|||
}
|
||||
|
||||
type selectStatementImpl struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
parent SelectStatement
|
||||
|
||||
table ReadableTable
|
||||
distinct bool
|
||||
projectionList []Projection
|
||||
where BoolExpression
|
||||
groupBy []groupByClause
|
||||
groupBy []GroupByClause
|
||||
having BoolExpression
|
||||
|
||||
orderBy []orderByClause
|
||||
orderBy []OrderByClause
|
||||
limit, offset int64
|
||||
|
||||
lockFor SelectLock
|
||||
|
|
@ -65,7 +65,7 @@ func newSelectStatement(table ReadableTable, projections []Projection) SelectSta
|
|||
distinct: false,
|
||||
}
|
||||
|
||||
newSelect.expressionInterfaceImpl.parent = newSelect
|
||||
newSelect.ExpressionInterfaceImpl.Parent = newSelect
|
||||
newSelect.parent = newSelect
|
||||
|
||||
return newSelect
|
||||
|
|
@ -77,7 +77,8 @@ func (s *selectStatementImpl) FROM(table ReadableTable) SelectStatement {
|
|||
}
|
||||
|
||||
func (s *selectStatementImpl) AsTable(alias string) SelectTable {
|
||||
return newSelectTable(s.parent, alias)
|
||||
//return newSelectTable(s.parent, alias)
|
||||
panic("UNimplemented.")
|
||||
}
|
||||
|
||||
func (s *selectStatementImpl) WHERE(expression BoolExpression) SelectStatement {
|
||||
|
|
@ -85,7 +86,7 @@ func (s *selectStatementImpl) WHERE(expression BoolExpression) SelectStatement {
|
|||
return s.parent
|
||||
}
|
||||
|
||||
func (s *selectStatementImpl) GROUP_BY(groupByClauses ...groupByClause) SelectStatement {
|
||||
func (s *selectStatementImpl) GROUP_BY(groupByClauses ...GroupByClause) SelectStatement {
|
||||
s.groupBy = groupByClauses
|
||||
return s.parent
|
||||
}
|
||||
|
|
@ -95,7 +96,7 @@ func (s *selectStatementImpl) HAVING(expression BoolExpression) SelectStatement
|
|||
return s.parent
|
||||
}
|
||||
|
||||
func (s *selectStatementImpl) ORDER_BY(clauses ...orderByClause) SelectStatement {
|
||||
func (s *selectStatementImpl) ORDER_BY(clauses ...OrderByClause) SelectStatement {
|
||||
s.orderBy = clauses
|
||||
return s.parent
|
||||
}
|
||||
|
|
@ -308,7 +309,7 @@ func (s *selectStatementImpl) ExecContext(context context.Context, db execution.
|
|||
|
||||
// SelectLock is interface for SELECT statement locks
|
||||
type SelectLock interface {
|
||||
Clause
|
||||
Serializer
|
||||
|
||||
NOWAIT() SelectLock
|
||||
SKIP_LOCKED() SelectLock
|
||||
|
|
|
|||
|
|
@ -1,72 +1,70 @@
|
|||
package jet
|
||||
|
||||
import "errors"
|
||||
|
||||
// SelectTable is interface for SELECT sub-queries
|
||||
type SelectTable interface {
|
||||
ReadableTable
|
||||
|
||||
Alias() string
|
||||
|
||||
AllColumns() ProjectionList
|
||||
}
|
||||
|
||||
type selectTableImpl struct {
|
||||
readableTableInterfaceImpl
|
||||
selectStmt SelectStatement
|
||||
alias string
|
||||
|
||||
projections []Projection
|
||||
}
|
||||
|
||||
func newSelectTable(selectStmt SelectStatement, alias string) SelectTable {
|
||||
expTable := &selectTableImpl{selectStmt: selectStmt, alias: alias}
|
||||
|
||||
expTable.readableTableInterfaceImpl.parent = expTable
|
||||
|
||||
for _, projection := range selectStmt.projections() {
|
||||
newProjection := projection.fromImpl(expTable)
|
||||
|
||||
expTable.projections = append(expTable.projections, newProjection)
|
||||
}
|
||||
|
||||
return expTable
|
||||
}
|
||||
|
||||
func (s *selectTableImpl) Alias() string {
|
||||
return s.alias
|
||||
}
|
||||
|
||||
func (s *selectTableImpl) columns() []IColumn {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *selectTableImpl) accept(visitor visitor) {
|
||||
visitor.visit(s)
|
||||
s.selectStmt.accept(visitor)
|
||||
}
|
||||
|
||||
func (s *selectTableImpl) dialect() Dialect {
|
||||
return detectDialect(s.selectStmt)
|
||||
}
|
||||
|
||||
func (s *selectTableImpl) AllColumns() ProjectionList {
|
||||
return s.projections
|
||||
}
|
||||
|
||||
func (s *selectTableImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
||||
if s == nil {
|
||||
return errors.New("jet: Expression table is nil. ")
|
||||
}
|
||||
|
||||
err := s.selectStmt.serialize(statement, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.WriteString("AS")
|
||||
out.writeIdentifier(s.alias)
|
||||
|
||||
return nil
|
||||
}
|
||||
//// SelectTable is interface for SELECT sub-queries
|
||||
//type SelectTable interface {
|
||||
// ReadableTable
|
||||
//
|
||||
// Alias() string
|
||||
//
|
||||
// AllColumns() ProjectionList
|
||||
//}
|
||||
//
|
||||
//type selectTableImpl struct {
|
||||
// readableTableInterfaceImpl
|
||||
// selectStmt SelectStatement
|
||||
// alias string
|
||||
//
|
||||
// projections []Projection
|
||||
//}
|
||||
//
|
||||
//func newSelectTable(selectStmt SelectStatement, alias string) SelectTable {
|
||||
// expTable := &selectTableImpl{selectStmt: selectStmt, alias: alias}
|
||||
//
|
||||
// expTable.readableTableInterfaceImpl.parent = expTable
|
||||
//
|
||||
// for _, projection := range selectStmt.projections() {
|
||||
// newProjection := projection.fromImpl(expTable)
|
||||
//
|
||||
// expTable.projections = append(expTable.projections, newProjection)
|
||||
// }
|
||||
//
|
||||
// return expTable
|
||||
//}
|
||||
//
|
||||
//func (s *selectTableImpl) Alias() string {
|
||||
// return s.alias
|
||||
//}
|
||||
//
|
||||
//func (s *selectTableImpl) columns() []IColumn {
|
||||
// return nil
|
||||
//}
|
||||
//
|
||||
//func (s *selectTableImpl) accept(visitor visitor) {
|
||||
// visitor.visit(s)
|
||||
// s.selectStmt.accept(visitor)
|
||||
//}
|
||||
//
|
||||
//func (s *selectTableImpl) dialect() Dialect {
|
||||
// return detectDialect(s.selectStmt)
|
||||
//}
|
||||
//
|
||||
//func (s *selectTableImpl) AllColumns() ProjectionList {
|
||||
// return s.projections
|
||||
//}
|
||||
//
|
||||
//func (s *selectTableImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
||||
// if s == nil {
|
||||
// return errors.New("jet: Expression table is nil. ")
|
||||
// }
|
||||
//
|
||||
// err := s.selectStmt.serialize(statement, out)
|
||||
//
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
//
|
||||
// out.WriteString("AS")
|
||||
// out.writeIdentifier(s.alias)
|
||||
//
|
||||
// return nil
|
||||
//}
|
||||
|
|
|
|||
36
internal/jet/serializer.go
Normal file
36
internal/jet/serializer.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
package jet
|
||||
|
||||
type SerializeOption int
|
||||
|
||||
const (
|
||||
noWrap SerializeOption = iota
|
||||
)
|
||||
|
||||
type StatementType string
|
||||
|
||||
const (
|
||||
SelectStatementType StatementType = "SELECT"
|
||||
InsertStatementType StatementType = "INSERT"
|
||||
UpdateStatementType StatementType = "UPDATE"
|
||||
DeleteStatementType StatementType = "DELETE"
|
||||
SetStatementType StatementType = "SET"
|
||||
LockStatementType StatementType = "LOCK"
|
||||
)
|
||||
|
||||
type Serializer interface {
|
||||
serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error
|
||||
}
|
||||
|
||||
func Serialize(exp Serializer, statementType StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
||||
return exp.serialize(statementType, out, options...)
|
||||
}
|
||||
|
||||
func contains(options []SerializeOption, option SerializeOption) bool {
|
||||
for _, opt := range options {
|
||||
if opt == option {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
@ -66,7 +66,7 @@ func newSetStatementImpl(operator string, all bool, selects []SelectStatement) S
|
|||
selects: selects,
|
||||
}
|
||||
|
||||
setStatement.selectStatementImpl.expressionInterfaceImpl.parent = setStatement
|
||||
setStatement.selectStatementImpl.ExpressionInterfaceImpl.Parent = setStatement
|
||||
setStatement.selectStatementImpl.parent = setStatement
|
||||
setStatement.limit = -1
|
||||
setStatement.offset = -1
|
||||
|
|
|
|||
235
internal/jet/sql_builder.go
Normal file
235
internal/jet/sql_builder.go
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
package jet
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/go-jet/jet/internal/utils"
|
||||
"github.com/google/uuid"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type SqlBuilder struct {
|
||||
Dialect Dialect
|
||||
Buff bytes.Buffer
|
||||
Args []interface{}
|
||||
|
||||
lastChar byte
|
||||
ident int
|
||||
}
|
||||
|
||||
func (s *SqlBuilder) DebugSQL() string {
|
||||
return queryStringToDebugString(s.Buff.String(), s.Args, s.Dialect)
|
||||
}
|
||||
|
||||
const defaultIdent = 5
|
||||
|
||||
func (q *SqlBuilder) increaseIdent() {
|
||||
q.ident += defaultIdent
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) decreaseIdent() {
|
||||
if q.ident < defaultIdent {
|
||||
q.ident = 0
|
||||
}
|
||||
|
||||
q.ident -= defaultIdent
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeProjections(statement StatementType, projections []Projection) error {
|
||||
q.increaseIdent()
|
||||
err := SerializeProjectionList(statement, projections, q)
|
||||
q.decreaseIdent()
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeFrom(statement StatementType, table Serializer) error {
|
||||
q.newLine()
|
||||
q.WriteString("FROM")
|
||||
|
||||
q.increaseIdent()
|
||||
err := table.serialize(statement, q)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeWhere(statement StatementType, where Expression) error {
|
||||
q.newLine()
|
||||
q.WriteString("WHERE")
|
||||
|
||||
q.increaseIdent()
|
||||
err := where.serialize(statement, q, noWrap)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeGroupBy(statement StatementType, groupBy []GroupByClause) error {
|
||||
q.newLine()
|
||||
q.WriteString("GROUP BY")
|
||||
|
||||
q.increaseIdent()
|
||||
err := serializeGroupByClauseList(statement, groupBy, q)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeOrderBy(statement StatementType, orderBy []OrderByClause) error {
|
||||
q.newLine()
|
||||
q.WriteString("ORDER BY")
|
||||
|
||||
q.increaseIdent()
|
||||
err := serializeOrderByClauseList(statement, orderBy, q)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeHaving(statement StatementType, having Expression) error {
|
||||
q.newLine()
|
||||
q.WriteString("HAVING")
|
||||
|
||||
q.increaseIdent()
|
||||
err := having.serialize(statement, q, noWrap)
|
||||
q.decreaseIdent()
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) WriteReturning(statement StatementType, returning []Projection) error {
|
||||
if len(returning) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !q.Dialect.SupportsReturning() {
|
||||
panic("jet: " + q.Dialect.Name() + " dialect does not support RETURNING.")
|
||||
}
|
||||
|
||||
q.newLine()
|
||||
q.WriteString("RETURNING")
|
||||
q.increaseIdent()
|
||||
|
||||
return q.writeProjections(statement, returning)
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) newLine() {
|
||||
q.write([]byte{'\n'})
|
||||
q.write(bytes.Repeat([]byte{' '}, q.ident))
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) write(data []byte) {
|
||||
if len(data) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
if !isPreSeparator(q.lastChar) && !isPostSeparator(data[0]) && q.Buff.Len() > 0 {
|
||||
q.Buff.WriteByte(' ')
|
||||
}
|
||||
|
||||
q.Buff.Write(data)
|
||||
q.lastChar = data[len(data)-1]
|
||||
}
|
||||
|
||||
func isPreSeparator(b byte) bool {
|
||||
return b == ' ' || b == '.' || b == ',' || b == '(' || b == '\n' || b == ':'
|
||||
}
|
||||
|
||||
func isPostSeparator(b byte) bool {
|
||||
return b == ' ' || b == '.' || b == ',' || b == ')' || b == '\n' || b == ':'
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeAlias(str string) {
|
||||
aliasQuoteChar := string(q.Dialect.AliasQuoteChar())
|
||||
q.WriteString(aliasQuoteChar + str + aliasQuoteChar)
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) WriteString(str string) {
|
||||
q.write([]byte(str))
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeIdentifier(name string, alwaysQuote ...bool) {
|
||||
quoteWrap := name != strings.ToLower(name) || strings.ContainsAny(name, ". -")
|
||||
|
||||
if quoteWrap || len(alwaysQuote) > 0 {
|
||||
identQuoteChar := string(q.Dialect.IdentifierQuoteChar())
|
||||
q.WriteString(identQuoteChar + name + identQuoteChar)
|
||||
} else {
|
||||
q.WriteString(name)
|
||||
}
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) writeByte(b byte) {
|
||||
q.write([]byte{b})
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) finalize() (string, []interface{}) {
|
||||
return q.Buff.String() + ";\n", q.Args
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) insertConstantArgument(arg interface{}) {
|
||||
q.WriteString(argToString(arg))
|
||||
}
|
||||
|
||||
func (q *SqlBuilder) insertParametrizedArgument(arg interface{}) {
|
||||
q.Args = append(q.Args, arg)
|
||||
argPlaceholder := q.Dialect.ArgumentPlaceholder()(len(q.Args))
|
||||
|
||||
q.WriteString(argPlaceholder)
|
||||
}
|
||||
|
||||
func argToString(value interface{}) string {
|
||||
if utils.IsNil(value) {
|
||||
return "NULL"
|
||||
}
|
||||
|
||||
switch bindVal := value.(type) {
|
||||
case bool:
|
||||
if bindVal {
|
||||
return "TRUE"
|
||||
}
|
||||
return "FALSE"
|
||||
case int8:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
case int:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
case int16:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
case int32:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
case int64:
|
||||
return strconv.FormatInt(int64(bindVal), 10)
|
||||
|
||||
case uint8:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
case uint:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
case uint16:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
case uint32:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
case uint64:
|
||||
return strconv.FormatUint(uint64(bindVal), 10)
|
||||
|
||||
case float32:
|
||||
return strconv.FormatFloat(float64(bindVal), 'f', -1, 64)
|
||||
case float64:
|
||||
return strconv.FormatFloat(float64(bindVal), 'f', -1, 64)
|
||||
|
||||
case string:
|
||||
return stringQuote(bindVal)
|
||||
case []byte:
|
||||
return stringQuote(string(bindVal))
|
||||
case uuid.UUID:
|
||||
return stringQuote(bindVal.String())
|
||||
case time.Time:
|
||||
return stringQuote(string(utils.FormatTimestamp(bindVal)))
|
||||
default:
|
||||
return "[Unsupported type]"
|
||||
}
|
||||
}
|
||||
|
||||
func stringQuote(value string) string {
|
||||
return `'` + strings.Replace(value, "'", "''", -1) + `'`
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package jet
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"github.com/go-jet/jet/execution"
|
||||
"strings"
|
||||
)
|
||||
|
|
@ -31,9 +32,66 @@ type Statement interface {
|
|||
ExecContext(context context.Context, db execution.DB) (sql.Result, error)
|
||||
}
|
||||
|
||||
type SerializerStatement interface {
|
||||
Serializer
|
||||
Statement
|
||||
}
|
||||
|
||||
type StatementWithProjections interface {
|
||||
Statement
|
||||
HasProjections
|
||||
Serializer
|
||||
}
|
||||
|
||||
type HasProjections interface {
|
||||
projections() []Projection
|
||||
}
|
||||
|
||||
type SerializerStatementInterfaceImpl struct {
|
||||
noOpVisitorImpl
|
||||
Parent SerializerStatement
|
||||
Dialect Dialect
|
||||
StatementType StatementType
|
||||
}
|
||||
|
||||
func (s *SerializerStatementInterfaceImpl) Sql(dialect ...Dialect) (query string, args []interface{}, err error) {
|
||||
|
||||
queryData := &SqlBuilder{Dialect: s.Dialect}
|
||||
|
||||
err = s.Parent.serialize(s.StatementType, queryData, noWrap)
|
||||
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
query, args = queryData.finalize()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (s *SerializerStatementInterfaceImpl) DebugSql(dialect ...Dialect) (query string, err error) {
|
||||
return debugSql(s.Parent, s.Dialect)
|
||||
}
|
||||
|
||||
func (s *SerializerStatementInterfaceImpl) Query(db execution.DB, destination interface{}) error {
|
||||
return query(s.Parent, db, destination)
|
||||
}
|
||||
|
||||
func (s *SerializerStatementInterfaceImpl) QueryContext(context context.Context, db execution.DB, destination interface{}) error {
|
||||
return queryContext(context, s.Parent, db, destination)
|
||||
}
|
||||
|
||||
func (s *SerializerStatementInterfaceImpl) Exec(db execution.DB) (res sql.Result, err error) {
|
||||
return exec(s.Parent, db)
|
||||
}
|
||||
|
||||
func (s *SerializerStatementInterfaceImpl) ExecContext(context context.Context, db execution.DB) (res sql.Result, err error) {
|
||||
return execContext(context, s.Parent, db)
|
||||
}
|
||||
|
||||
func debugSql(statement Statement, overrideDialect ...Dialect) (string, error) {
|
||||
dialect := detectDialect(statement, overrideDialect...)
|
||||
sqlQuery, args, err := statement.Sql()
|
||||
sqlQuery, args, err := statement.Sql(dialect)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
|
|
@ -100,3 +158,68 @@ func execContext(context context.Context, statement Statement, db execution.DB)
|
|||
|
||||
return db.ExecContext(context, query, args...)
|
||||
}
|
||||
|
||||
type ExpressionStatementImpl struct {
|
||||
ExpressionInterfaceImpl
|
||||
StatementImpl
|
||||
}
|
||||
|
||||
func (s *ExpressionStatementImpl) serializeForProjection(statement StatementType, out *SqlBuilder) error {
|
||||
return s.serialize(statement, out)
|
||||
}
|
||||
|
||||
func NewStatementImpl(Dialect Dialect, statementType StatementType, parent SerializerStatement, clauses ...Clause) StatementImpl {
|
||||
return StatementImpl{
|
||||
SerializerStatementInterfaceImpl: SerializerStatementInterfaceImpl{
|
||||
Parent: parent,
|
||||
Dialect: Dialect,
|
||||
StatementType: statementType,
|
||||
},
|
||||
Clauses: clauses,
|
||||
}
|
||||
}
|
||||
|
||||
type StatementImpl struct {
|
||||
SerializerStatementInterfaceImpl
|
||||
acceptsVisitor
|
||||
|
||||
Clauses []Clause
|
||||
}
|
||||
|
||||
func (s *StatementImpl) projections() []Projection {
|
||||
for _, clause := range s.Clauses {
|
||||
if selectClause, ok := clause.(ClauseWithProjections); ok {
|
||||
return selectClause.projections()
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StatementImpl) serialize(statement StatementType, out *SqlBuilder, options ...SerializeOption) error {
|
||||
if s == nil {
|
||||
return errors.New("jet: Select expression is nil. ")
|
||||
}
|
||||
|
||||
if !contains(options, noWrap) {
|
||||
out.WriteString("(")
|
||||
|
||||
out.increaseIdent()
|
||||
}
|
||||
|
||||
for _, clause := range s.Clauses {
|
||||
err := clause.Serialize(statement, out)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if !contains(options, noWrap) {
|
||||
out.decreaseIdent()
|
||||
out.newLine()
|
||||
out.WriteString(")")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ func (s *stringInterfaceImpl) REGEXP_LIKE(pattern StringExpression, matchType ..
|
|||
|
||||
//---------------------------------------------------//
|
||||
type binaryStringExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
stringInterfaceImpl
|
||||
|
||||
binaryOpExpression
|
||||
|
|
@ -90,7 +90,7 @@ func newBinaryStringExpression(lhs, rhs Expression, operator string) StringExpre
|
|||
boolExpression := binaryStringExpression{}
|
||||
|
||||
boolExpression.binaryOpExpression = newBinaryExpression(lhs, rhs, operator)
|
||||
boolExpression.expressionInterfaceImpl.parent = &boolExpression
|
||||
boolExpression.ExpressionInterfaceImpl.Parent = &boolExpression
|
||||
boolExpression.stringInterfaceImpl.parent = &boolExpression
|
||||
|
||||
return &boolExpression
|
||||
|
|
|
|||
|
|
@ -5,7 +5,19 @@ import (
|
|||
"github.com/go-jet/jet/internal/utils"
|
||||
)
|
||||
|
||||
type table interface {
|
||||
type SerializerTable interface {
|
||||
Serializer
|
||||
Columns() []IColumn
|
||||
//SchemaName() string
|
||||
//TableName() string
|
||||
//AS(alias string)
|
||||
}
|
||||
|
||||
type TableInterface interface {
|
||||
Columns() []IColumn
|
||||
}
|
||||
|
||||
type TableBase interface {
|
||||
dialect() Dialect
|
||||
columns() []IColumn
|
||||
}
|
||||
|
|
@ -40,26 +52,26 @@ type writableTable interface {
|
|||
|
||||
// ReadableTable interface
|
||||
type ReadableTable interface {
|
||||
table
|
||||
TableBase
|
||||
readableTable
|
||||
Clause
|
||||
Serializer
|
||||
acceptsVisitor
|
||||
}
|
||||
|
||||
// WritableTable interface
|
||||
type WritableTable interface {
|
||||
table
|
||||
TableBase
|
||||
writableTable
|
||||
Clause
|
||||
Serializer
|
||||
acceptsVisitor
|
||||
}
|
||||
|
||||
// Table interface
|
||||
type Table interface {
|
||||
table
|
||||
TableBase
|
||||
readableTable
|
||||
writableTable
|
||||
Clause
|
||||
Serializer
|
||||
acceptsVisitor
|
||||
|
||||
SchemaName() string
|
||||
|
|
@ -78,25 +90,25 @@ func (r *readableTableInterfaceImpl) SELECT(projection1 Projection, projections
|
|||
|
||||
// Creates a inner join tableName Expression using onCondition.
|
||||
func (r *readableTableInterfaceImpl) INNER_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
return newJoinTable(r.parent, table, innerJoin, onCondition)
|
||||
return newJoinTable(r.parent, table, InnerJoin, onCondition)
|
||||
}
|
||||
|
||||
// Creates a left join tableName Expression using onCondition.
|
||||
func (r *readableTableInterfaceImpl) LEFT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
return newJoinTable(r.parent, table, leftJoin, onCondition)
|
||||
return newJoinTable(r.parent, table, LeftJoin, onCondition)
|
||||
}
|
||||
|
||||
// Creates a right join tableName Expression using onCondition.
|
||||
func (r *readableTableInterfaceImpl) RIGHT_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
return newJoinTable(r.parent, table, rightJoin, onCondition)
|
||||
return newJoinTable(r.parent, table, RightJoin, onCondition)
|
||||
}
|
||||
|
||||
func (r *readableTableInterfaceImpl) FULL_JOIN(table ReadableTable, onCondition BoolExpression) ReadableTable {
|
||||
return newJoinTable(r.parent, table, fullJoin, onCondition)
|
||||
return newJoinTable(r.parent, table, FullJoin, onCondition)
|
||||
}
|
||||
|
||||
func (r *readableTableInterfaceImpl) CROSS_JOIN(table ReadableTable) ReadableTable {
|
||||
return newJoinTable(r.parent, table, crossJoin, nil)
|
||||
return newJoinTable(r.parent, table, CrossJoin, nil)
|
||||
}
|
||||
|
||||
type writableTableInterfaceImpl struct {
|
||||
|
|
@ -104,11 +116,11 @@ type writableTableInterfaceImpl struct {
|
|||
}
|
||||
|
||||
func (w *writableTableInterfaceImpl) INSERT(columns ...IColumn) InsertStatement {
|
||||
return newInsertStatement(w.parent, unwidColumnList(columns))
|
||||
return newInsertStatement(w.parent, UnwidColumnList(columns))
|
||||
}
|
||||
|
||||
func (w *writableTableInterfaceImpl) UPDATE(column IColumn, columns ...IColumn) UpdateStatement {
|
||||
return newUpdateStatement(w.parent, unwindColumns(column, columns...))
|
||||
return newUpdateStatement(w.parent, UnwindColumns(column, columns...))
|
||||
}
|
||||
|
||||
func (w *writableTableInterfaceImpl) DELETE() DeleteStatement {
|
||||
|
|
@ -200,14 +212,14 @@ func (t *tableImpl) serialize(statement StatementType, out *SqlBuilder, options
|
|||
return nil
|
||||
}
|
||||
|
||||
type joinType int
|
||||
type JoinType int
|
||||
|
||||
const (
|
||||
innerJoin joinType = iota
|
||||
leftJoin
|
||||
rightJoin
|
||||
fullJoin
|
||||
crossJoin
|
||||
InnerJoin JoinType = iota
|
||||
LeftJoin
|
||||
RightJoin
|
||||
FullJoin
|
||||
CrossJoin
|
||||
)
|
||||
|
||||
// Join expressions are pseudo readable tables.
|
||||
|
|
@ -216,15 +228,15 @@ type joinTable struct {
|
|||
|
||||
lhs ReadableTable
|
||||
rhs ReadableTable
|
||||
joinType joinType
|
||||
joinType JoinType
|
||||
onCondition BoolExpression
|
||||
}
|
||||
|
||||
func newJoinTable(
|
||||
lhs ReadableTable,
|
||||
rhs ReadableTable,
|
||||
joinType joinType,
|
||||
onCondition BoolExpression) ReadableTable {
|
||||
joinType JoinType,
|
||||
onCondition BoolExpression) *joinTable {
|
||||
|
||||
joinTable := &joinTable{
|
||||
lhs: lhs,
|
||||
|
|
@ -275,15 +287,15 @@ func (t *joinTable) serialize(statement StatementType, out *SqlBuilder, options
|
|||
out.newLine()
|
||||
|
||||
switch t.joinType {
|
||||
case innerJoin:
|
||||
case InnerJoin:
|
||||
out.WriteString("INNER JOIN")
|
||||
case leftJoin:
|
||||
case LeftJoin:
|
||||
out.WriteString("LEFT JOIN")
|
||||
case rightJoin:
|
||||
case RightJoin:
|
||||
out.WriteString("RIGHT JOIN")
|
||||
case fullJoin:
|
||||
case FullJoin:
|
||||
out.WriteString("FULL JOIN")
|
||||
case crossJoin:
|
||||
case CrossJoin:
|
||||
out.WriteString("CROSS JOIN")
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +307,7 @@ func (t *joinTable) serialize(statement StatementType, out *SqlBuilder, options
|
|||
return
|
||||
}
|
||||
|
||||
if t.onCondition == nil && t.joinType != crossJoin {
|
||||
if t.onCondition == nil && t.joinType != CrossJoin {
|
||||
return errors.New("jet: join condition is nil")
|
||||
}
|
||||
|
||||
|
|
@ -309,7 +321,7 @@ func (t *joinTable) serialize(statement StatementType, out *SqlBuilder, options
|
|||
return nil
|
||||
}
|
||||
|
||||
func unwindColumns(column1 IColumn, columns ...IColumn) []IColumn {
|
||||
func UnwindColumns(column1 IColumn, columns ...IColumn) []IColumn {
|
||||
columnList := []IColumn{}
|
||||
|
||||
if val, ok := column1.(IColumnList); ok {
|
||||
|
|
@ -325,7 +337,7 @@ func unwindColumns(column1 IColumn, columns ...IColumn) []IColumn {
|
|||
return columnList
|
||||
}
|
||||
|
||||
func unwidColumnList(columns []IColumn) []IColumn {
|
||||
func UnwidColumnList(columns []IColumn) []IColumn {
|
||||
ret := []IColumn{}
|
||||
|
||||
for _, col := range columns {
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ var table3 = NewTable(
|
|||
table3ColInt,
|
||||
table3StrCol)
|
||||
|
||||
func assertClauseSerialize(t *testing.T, clause Clause, query string, args ...interface{}) {
|
||||
func assertClauseSerialize(t *testing.T, clause Serializer, query string, args ...interface{}) {
|
||||
out := SqlBuilder{Dialect: ANSII}
|
||||
err := clause.serialize(SelectStatementType, &out)
|
||||
|
||||
|
|
@ -82,7 +82,7 @@ func assertClauseSerialize(t *testing.T, clause Clause, query string, args ...in
|
|||
assert.DeepEqual(t, out.Args, args)
|
||||
}
|
||||
|
||||
func assertClauseSerializeErr(t *testing.T, clause Clause, errString string) {
|
||||
func assertClauseSerializeErr(t *testing.T, clause Serializer, errString string) {
|
||||
out := SqlBuilder{Dialect: ANSII}
|
||||
err := clause.serialize(SelectStatementType, &out)
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ func (t *timeInterfaceImpl) GT_EQ(rhs TimeExpression) BoolExpression {
|
|||
|
||||
//---------------------------------------------------//
|
||||
type prefixTimeExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
timeInterfaceImpl
|
||||
|
||||
prefixOpExpression
|
||||
|
|
@ -63,8 +63,8 @@ type prefixTimeExpression struct {
|
|||
// timeExpr := prefixTimeExpression{}
|
||||
// timeExpr.prefixOpExpression = newPrefixExpression(expression, operator)
|
||||
//
|
||||
// timeExpr.expressionInterfaceImpl.parent = &timeExpr
|
||||
// timeExpr.timeInterfaceImpl.parent = &timeExpr
|
||||
// timeExpr.ExpressionInterfaceImpl.Parent = &timeExpr
|
||||
// timeExpr.timeInterfaceImpl.Parent = &timeExpr
|
||||
//
|
||||
// return &timeExpr
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ func (t *timestampzInterfaceImpl) GT_EQ(rhs TimestampzExpression) BoolExpression
|
|||
//---------------------------------------------------//
|
||||
|
||||
type prefixTimestampzOperator struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
timestampzInterfaceImpl
|
||||
|
||||
prefixOpExpression
|
||||
|
|
@ -64,7 +64,7 @@ func NewPrefixTimestampOperator(operator string, expression Expression) Timestam
|
|||
timeExpr := prefixTimestampzOperator{}
|
||||
timeExpr.prefixOpExpression = newPrefixExpression(expression, operator)
|
||||
|
||||
timeExpr.expressionInterfaceImpl.parent = &timeExpr
|
||||
timeExpr.ExpressionInterfaceImpl.Parent = &timeExpr
|
||||
timeExpr.timestampzInterfaceImpl.parent = &timeExpr
|
||||
|
||||
return &timeExpr
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ func (t *timezInterfaceImpl) GT_EQ(rhs TimezExpression) BoolExpression {
|
|||
|
||||
//---------------------------------------------------//
|
||||
type prefixTimezExpression struct {
|
||||
expressionInterfaceImpl
|
||||
ExpressionInterfaceImpl
|
||||
timezInterfaceImpl
|
||||
|
||||
prefixOpExpression
|
||||
|
|
@ -71,8 +71,8 @@ type prefixTimezExpression struct {
|
|||
// timeExpr := prefixTimezExpression{}
|
||||
// timeExpr.prefixOpExpression = newPrefixExpression(expression, operator)
|
||||
//
|
||||
// timeExpr.expressionInterfaceImpl.parent = &timeExpr
|
||||
// timeExpr.timezInterfaceImpl.parent = &timeExpr
|
||||
// timeExpr.ExpressionInterfaceImpl.Parent = &timeExpr
|
||||
// timeExpr.timezInterfaceImpl.Parent = &timeExpr
|
||||
//
|
||||
// return &timeExpr
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -23,26 +23,26 @@ func newUpdateStatement(table WritableTable, columns []IColumn) UpdateStatement
|
|||
return &updateStatementImpl{
|
||||
table: table,
|
||||
columns: columns,
|
||||
values: make([]Clause, 0, len(columns)),
|
||||
values: make([]Serializer, 0, len(columns)),
|
||||
}
|
||||
}
|
||||
|
||||
type updateStatementImpl struct {
|
||||
table WritableTable
|
||||
columns []IColumn
|
||||
values []Clause
|
||||
values []Serializer
|
||||
where BoolExpression
|
||||
returning []Projection
|
||||
}
|
||||
|
||||
func (u *updateStatementImpl) SET(value interface{}, values ...interface{}) UpdateStatement {
|
||||
u.values = unwindRowFromValues(value, values)
|
||||
u.values = UnwindRowFromValues(value, values)
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
func (u *updateStatementImpl) MODEL(data interface{}) UpdateStatement {
|
||||
u.values = unwindRowFromModel(u.columns, data)
|
||||
u.values = UnwindRowFromModel(u.columns, data)
|
||||
|
||||
return u
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ func (u *updateStatementImpl) Sql(dialect ...Dialect) (query string, args []inte
|
|||
return
|
||||
}
|
||||
|
||||
if err = out.writeReturning(UpdateStatementType, u.returning); err != nil {
|
||||
if err = out.WriteReturning(UpdateStatementType, u.returning); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"strings"
|
||||
)
|
||||
|
||||
func serializeOrderByClauseList(statement StatementType, orderByClauses []orderByClause, out *SqlBuilder) error {
|
||||
func serializeOrderByClauseList(statement StatementType, orderByClauses []OrderByClause, out *SqlBuilder) error {
|
||||
|
||||
for i, value := range orderByClauses {
|
||||
if i > 0 {
|
||||
|
|
@ -24,7 +24,7 @@ func serializeOrderByClauseList(statement StatementType, orderByClauses []orderB
|
|||
return nil
|
||||
}
|
||||
|
||||
func serializeGroupByClauseList(statement StatementType, clauses []groupByClause, out *SqlBuilder) (err error) {
|
||||
func serializeGroupByClauseList(statement StatementType, clauses []GroupByClause, out *SqlBuilder) (err error) {
|
||||
|
||||
for i, c := range clauses {
|
||||
if i > 0 {
|
||||
|
|
@ -43,7 +43,7 @@ func serializeGroupByClauseList(statement StatementType, clauses []groupByClause
|
|||
return nil
|
||||
}
|
||||
|
||||
func SerializeClauseList(statement StatementType, clauses []Clause, out *SqlBuilder) (err error) {
|
||||
func SerializeClauseList(statement StatementType, clauses []Serializer, out *SqlBuilder) (err error) {
|
||||
|
||||
for i, c := range clauses {
|
||||
if i > 0 {
|
||||
|
|
@ -124,18 +124,18 @@ func ColumnListToProjectionList(columns []Column) []Projection {
|
|||
return ret
|
||||
}
|
||||
|
||||
func valueToClause(value interface{}) Clause {
|
||||
if clause, ok := value.(Clause); ok {
|
||||
func valueToClause(value interface{}) Serializer {
|
||||
if clause, ok := value.(Serializer); ok {
|
||||
return clause
|
||||
}
|
||||
|
||||
return literal(value)
|
||||
}
|
||||
|
||||
func unwindRowFromModel(columns []IColumn, data interface{}) []Clause {
|
||||
func UnwindRowFromModel(columns []IColumn, data interface{}) []Serializer {
|
||||
structValue := reflect.Indirect(reflect.ValueOf(data))
|
||||
|
||||
row := []Clause{}
|
||||
row := []Serializer{}
|
||||
|
||||
mustBe(structValue, reflect.Struct)
|
||||
|
||||
|
|
@ -163,23 +163,23 @@ func unwindRowFromModel(columns []IColumn, data interface{}) []Clause {
|
|||
return row
|
||||
}
|
||||
|
||||
func unwindRowsFromModels(columns []IColumn, data interface{}) [][]Clause {
|
||||
func UnwindRowsFromModels(columns []IColumn, data interface{}) [][]Serializer {
|
||||
sliceValue := reflect.Indirect(reflect.ValueOf(data))
|
||||
mustBe(sliceValue, reflect.Slice)
|
||||
|
||||
rows := [][]Clause{}
|
||||
rows := [][]Serializer{}
|
||||
|
||||
for i := 0; i < sliceValue.Len(); i++ {
|
||||
structValue := sliceValue.Index(i)
|
||||
|
||||
rows = append(rows, unwindRowFromModel(columns, structValue.Interface()))
|
||||
rows = append(rows, UnwindRowFromModel(columns, structValue.Interface()))
|
||||
}
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
func unwindRowFromValues(value interface{}, values []interface{}) []Clause {
|
||||
row := []Clause{}
|
||||
func UnwindRowFromValues(value interface{}, values []interface{}) []Serializer {
|
||||
row := []Serializer{}
|
||||
|
||||
allValues := append([]interface{}{value}, values...)
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ func (f *DialectFinder) mustGetDialect() Dialect {
|
|||
|
||||
func (f *DialectFinder) visit(element acceptsVisitor) {
|
||||
|
||||
if table, ok := element.(table); ok {
|
||||
if table, ok := element.(TableBase); ok {
|
||||
dialect := table.dialect()
|
||||
f.dialects[dialect.Name()] = dialect
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue