124 lines
2.4 KiB
Go
124 lines
2.4 KiB
Go
package dbr
|
|
|
|
import (
|
|
"bytes"
|
|
"reflect"
|
|
)
|
|
|
|
// InsertStmt builds `INSERT INTO ...`
|
|
type InsertStmt struct {
|
|
raw
|
|
|
|
Table string
|
|
Column []string
|
|
Value [][]interface{}
|
|
ReturnColumn []string
|
|
}
|
|
|
|
// Build builds `INSERT INTO ...` in dialect
|
|
func (b *InsertStmt) Build(d Dialect, buf Buffer) error {
|
|
if b.raw.Query != "" {
|
|
return b.raw.Build(d, buf)
|
|
}
|
|
|
|
if b.Table == "" {
|
|
return ErrTableNotSpecified
|
|
}
|
|
|
|
if len(b.Column) == 0 {
|
|
return ErrColumnNotSpecified
|
|
}
|
|
|
|
buf.WriteString("INSERT INTO ")
|
|
buf.WriteString(d.QuoteIdent(b.Table))
|
|
|
|
placeholderBuf := new(bytes.Buffer)
|
|
placeholderBuf.WriteString("(")
|
|
buf.WriteString(" (")
|
|
for i, col := range b.Column {
|
|
if i > 0 {
|
|
buf.WriteString(",")
|
|
placeholderBuf.WriteString(",")
|
|
}
|
|
buf.WriteString(d.QuoteIdent(col))
|
|
placeholderBuf.WriteString(placeholder)
|
|
}
|
|
buf.WriteString(") VALUES ")
|
|
placeholderBuf.WriteString(")")
|
|
placeholderStr := placeholderBuf.String()
|
|
|
|
for i, tuple := range b.Value {
|
|
if i > 0 {
|
|
buf.WriteString(", ")
|
|
}
|
|
buf.WriteString(placeholderStr)
|
|
|
|
buf.WriteValue(tuple...)
|
|
}
|
|
|
|
if len(b.ReturnColumn) > 0 {
|
|
buf.WriteString(" RETURNING ")
|
|
for i, col := range b.ReturnColumn {
|
|
if i > 0 {
|
|
buf.WriteString(",")
|
|
}
|
|
buf.WriteString(d.QuoteIdent(col))
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// InsertInto creates an InsertStmt
|
|
func InsertInto(table string) *InsertStmt {
|
|
return &InsertStmt{
|
|
Table: table,
|
|
}
|
|
}
|
|
|
|
// InsertBySql creates an InsertStmt from raw query
|
|
func InsertBySql(query string, value ...interface{}) *InsertStmt {
|
|
return &InsertStmt{
|
|
raw: raw{
|
|
Query: query,
|
|
Value: value,
|
|
},
|
|
}
|
|
}
|
|
|
|
// Columns adds columns
|
|
func (b *InsertStmt) Columns(column ...string) *InsertStmt {
|
|
b.Column = column
|
|
return b
|
|
}
|
|
|
|
// Values adds a tuple for columns
|
|
func (b *InsertStmt) Values(value ...interface{}) *InsertStmt {
|
|
b.Value = append(b.Value, value)
|
|
return b
|
|
}
|
|
|
|
// Record adds a tuple for columns from a struct
|
|
func (b *InsertStmt) Record(structValue interface{}) *InsertStmt {
|
|
v := reflect.Indirect(reflect.ValueOf(structValue))
|
|
|
|
if v.Kind() == reflect.Struct {
|
|
var value []interface{}
|
|
m := structMap(v)
|
|
for _, key := range b.Column {
|
|
if val, ok := m[key]; ok {
|
|
value = append(value, val.Interface())
|
|
} else {
|
|
value = append(value, nil)
|
|
}
|
|
}
|
|
b.Values(value...)
|
|
}
|
|
return b
|
|
}
|
|
|
|
func (b *InsertStmt) Returning(column ...string) *InsertStmt {
|
|
b.ReturnColumn = column
|
|
return b
|
|
}
|