[postgres] Add support for ON CONFLICT clause
This commit is contained in:
parent
eea776a1ac
commit
14e1863456
42 changed files with 827 additions and 277 deletions
|
|
@ -6,7 +6,7 @@ import (
|
|||
|
||||
// Clause interface
|
||||
type Clause interface {
|
||||
Serialize(statementType StatementType, out *SQLBuilder)
|
||||
Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption)
|
||||
}
|
||||
|
||||
// ClauseWithProjections interface
|
||||
|
|
@ -27,7 +27,7 @@ func (s *ClauseSelect) projections() ProjectionList {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (s *ClauseSelect) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (s *ClauseSelect) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
out.NewLine()
|
||||
out.WriteString("SELECT")
|
||||
|
||||
|
|
@ -48,7 +48,7 @@ type ClauseFrom struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (f *ClauseFrom) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (f *ClauseFrom) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if f.Table == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -56,7 +56,7 @@ func (f *ClauseFrom) Serialize(statementType StatementType, out *SQLBuilder) {
|
|||
out.WriteString("FROM")
|
||||
|
||||
out.IncreaseIdent()
|
||||
f.Table.serialize(statementType, out)
|
||||
f.Table.serialize(statementType, out, FallTrough(options)...)
|
||||
out.DecreaseIdent()
|
||||
}
|
||||
|
||||
|
|
@ -67,18 +67,20 @@ type ClauseWhere struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (c *ClauseWhere) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (c *ClauseWhere) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if c.Condition == nil {
|
||||
if c.Mandatory {
|
||||
panic("jet: WHERE clause not set")
|
||||
}
|
||||
return
|
||||
}
|
||||
out.NewLine()
|
||||
if !contains(options, SkipNewLine) {
|
||||
out.NewLine()
|
||||
}
|
||||
out.WriteString("WHERE")
|
||||
|
||||
out.IncreaseIdent()
|
||||
c.Condition.serialize(statementType, out, noWrap)
|
||||
c.Condition.serialize(statementType, out, NoWrap.WithFallTrough(options)...)
|
||||
out.DecreaseIdent()
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +90,7 @@ type ClauseGroupBy struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (c *ClauseGroupBy) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (c *ClauseGroupBy) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if len(c.List) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
@ -119,7 +121,7 @@ type ClauseHaving struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (c *ClauseHaving) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (c *ClauseHaving) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if c.Condition == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -128,7 +130,7 @@ func (c *ClauseHaving) Serialize(statementType StatementType, out *SQLBuilder) {
|
|||
out.WriteString("HAVING")
|
||||
|
||||
out.IncreaseIdent()
|
||||
c.Condition.serialize(statementType, out, noWrap)
|
||||
c.Condition.serialize(statementType, out, NoWrap.WithFallTrough(options)...)
|
||||
out.DecreaseIdent()
|
||||
}
|
||||
|
||||
|
|
@ -139,7 +141,7 @@ type ClauseOrderBy struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (o *ClauseOrderBy) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (o *ClauseOrderBy) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if o.List == nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -168,7 +170,7 @@ type ClauseLimit struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (l *ClauseLimit) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (l *ClauseLimit) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if l.Count >= 0 {
|
||||
out.NewLine()
|
||||
out.WriteString("LIMIT")
|
||||
|
|
@ -182,7 +184,7 @@ type ClauseOffset struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (o *ClauseOffset) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (o *ClauseOffset) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if o.Count >= 0 {
|
||||
out.NewLine()
|
||||
out.WriteString("OFFSET")
|
||||
|
|
@ -196,14 +198,14 @@ type ClauseFor struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (f *ClauseFor) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (f *ClauseFor) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if f.Lock == nil {
|
||||
return
|
||||
}
|
||||
|
||||
out.NewLine()
|
||||
out.WriteString("FOR")
|
||||
f.Lock.serialize(statementType, out)
|
||||
f.Lock.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
|
||||
// ClauseSetStmtOperator struct
|
||||
|
|
@ -224,7 +226,7 @@ func (s *ClauseSetStmtOperator) projections() ProjectionList {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if len(s.Selects) < 2 {
|
||||
panic("jet: UNION Statement must contain at least two SELECT statements")
|
||||
}
|
||||
|
|
@ -244,7 +246,7 @@ func (s *ClauseSetStmtOperator) Serialize(statementType StatementType, out *SQLB
|
|||
panic("jet: select statement of '" + s.Operator + "' is nil")
|
||||
}
|
||||
|
||||
selectStmt.serialize(statementType, out)
|
||||
selectStmt.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
|
||||
s.OrderBy.Serialize(statementType, out)
|
||||
|
|
@ -258,7 +260,7 @@ type ClauseUpdate struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (u *ClauseUpdate) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (u *ClauseUpdate) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
out.NewLine()
|
||||
out.WriteString("UPDATE")
|
||||
|
||||
|
|
@ -266,7 +268,7 @@ func (u *ClauseUpdate) Serialize(statementType StatementType, out *SQLBuilder) {
|
|||
panic("jet: table to update is nil")
|
||||
}
|
||||
|
||||
u.Table.serialize(statementType, out)
|
||||
u.Table.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
|
||||
// ClauseSet struct
|
||||
|
|
@ -276,7 +278,7 @@ type ClauseSet struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (s *ClauseSet) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (s *ClauseSet) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
out.NewLine()
|
||||
out.WriteString("SET")
|
||||
|
||||
|
|
@ -299,7 +301,7 @@ func (s *ClauseSet) Serialize(statementType StatementType, out *SQLBuilder) {
|
|||
|
||||
out.WriteString(" = ")
|
||||
|
||||
s.Values[i].serialize(UpdateStatementType, out)
|
||||
s.Values[i].serialize(UpdateStatementType, out, FallTrough(options)...)
|
||||
}
|
||||
out.DecreaseIdent(4)
|
||||
}
|
||||
|
|
@ -320,7 +322,7 @@ func (i *ClauseInsert) GetColumns() []Column {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (i *ClauseInsert) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (i *ClauseInsert) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
out.NewLine()
|
||||
out.WriteString("INSERT INTO")
|
||||
|
||||
|
|
@ -346,7 +348,7 @@ type ClauseValuesQuery struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (v *ClauseValuesQuery) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (v *ClauseValuesQuery) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if len(v.Rows) == 0 && v.Query == nil {
|
||||
panic("jet: VALUES or QUERY has to be specified for INSERT statement")
|
||||
}
|
||||
|
|
@ -355,8 +357,8 @@ func (v *ClauseValuesQuery) Serialize(statementType StatementType, out *SQLBuild
|
|||
panic("jet: VALUES or QUERY has to be specified for INSERT statement")
|
||||
}
|
||||
|
||||
v.ClauseValues.Serialize(statementType, out)
|
||||
v.ClauseQuery.Serialize(statementType, out)
|
||||
v.ClauseValues.Serialize(statementType, out, FallTrough(options)...)
|
||||
v.ClauseQuery.Serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
|
||||
// ClauseValues struct
|
||||
|
|
@ -365,27 +367,29 @@ type ClauseValues struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (v *ClauseValues) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (v *ClauseValues) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if len(v.Rows) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
out.NewLine()
|
||||
out.WriteString("VALUES")
|
||||
|
||||
for rowIndex, row := range v.Rows {
|
||||
if rowIndex > 0 {
|
||||
out.WriteString(",")
|
||||
out.NewLine()
|
||||
} else {
|
||||
out.IncreaseIdent(7)
|
||||
}
|
||||
|
||||
out.IncreaseIdent()
|
||||
out.NewLine()
|
||||
out.WriteString("(")
|
||||
|
||||
SerializeClauseList(statementType, row, out)
|
||||
|
||||
out.WriteByte(')')
|
||||
out.DecreaseIdent()
|
||||
}
|
||||
out.DecreaseIdent(7)
|
||||
}
|
||||
|
||||
// ClauseQuery struct
|
||||
|
|
@ -394,12 +398,12 @@ type ClauseQuery struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (v *ClauseQuery) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (v *ClauseQuery) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if v.Query == nil {
|
||||
return
|
||||
}
|
||||
|
||||
v.Query.serialize(statementType, out)
|
||||
v.Query.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
|
||||
// ClauseDelete struct
|
||||
|
|
@ -408,7 +412,7 @@ type ClauseDelete struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (d *ClauseDelete) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (d *ClauseDelete) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
out.NewLine()
|
||||
out.WriteString("DELETE FROM")
|
||||
|
||||
|
|
@ -416,7 +420,7 @@ func (d *ClauseDelete) Serialize(statementType StatementType, out *SQLBuilder) {
|
|||
panic("jet: nil table in DELETE clause")
|
||||
}
|
||||
|
||||
d.Table.serialize(statementType, out)
|
||||
d.Table.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
|
||||
// ClauseStatementBegin struct
|
||||
|
|
@ -426,7 +430,7 @@ type ClauseStatementBegin struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (d *ClauseStatementBegin) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (d *ClauseStatementBegin) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
out.NewLine()
|
||||
out.WriteString(d.Name)
|
||||
|
||||
|
|
@ -435,7 +439,7 @@ func (d *ClauseStatementBegin) Serialize(statementType StatementType, out *SQLBu
|
|||
out.WriteString(", ")
|
||||
}
|
||||
|
||||
table.serialize(statementType, out)
|
||||
table.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -447,7 +451,7 @@ type ClauseOptional struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (d *ClauseOptional) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (d *ClauseOptional) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if !d.Show {
|
||||
return
|
||||
}
|
||||
|
|
@ -463,7 +467,7 @@ type ClauseIn struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (i *ClauseIn) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (i *ClauseIn) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if i.LockMode == "" {
|
||||
return
|
||||
}
|
||||
|
|
@ -485,7 +489,7 @@ type ClauseWindow struct {
|
|||
}
|
||||
|
||||
// Serialize serializes clause into SQLBuilder
|
||||
func (i *ClauseWindow) Serialize(statementType StatementType, out *SQLBuilder) {
|
||||
func (i *ClauseWindow) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
if len(i.Definitions) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
@ -503,6 +507,44 @@ func (i *ClauseWindow) Serialize(statementType StatementType, out *SQLBuilder) {
|
|||
out.WriteString("()")
|
||||
continue
|
||||
}
|
||||
def.Window.serialize(statementType, out)
|
||||
def.Window.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
}
|
||||
|
||||
// SetPair clause
|
||||
type SetPair struct {
|
||||
Column ColumnSerializer
|
||||
Value Serializer
|
||||
}
|
||||
|
||||
// SetClause clause
|
||||
type SetClause []SetPair
|
||||
|
||||
// Serialize for SetClause
|
||||
func (s SetClause) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
out.NewLine()
|
||||
out.WriteString("SET")
|
||||
out.IncreaseIdent(4)
|
||||
|
||||
for i, pair := range s {
|
||||
if i > 0 {
|
||||
out.WriteString(",")
|
||||
out.NewLine()
|
||||
}
|
||||
|
||||
pair.Column.serialize(statementType, out, ShortName.WithFallTrough(options)...)
|
||||
out.WriteString("=")
|
||||
pair.Value.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
out.DecreaseIdent(4)
|
||||
}
|
||||
|
||||
// KeywordClause type
|
||||
type KeywordClause struct {
|
||||
Keyword
|
||||
}
|
||||
|
||||
// Serialize for KeywordClause
|
||||
func (k KeywordClause) Serialize(statementType StatementType, out *SQLBuilder, options ...SerializeOption) {
|
||||
k.serialize(statementType, out, FallTrough(options)...)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue