127 lines
2.8 KiB
Go
127 lines
2.8 KiB
Go
package dbr
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"reflect"
|
|
)
|
|
|
|
type InsertBuilder struct {
|
|
runner
|
|
EventReceiver
|
|
Dialect Dialect
|
|
|
|
RecordID reflect.Value
|
|
|
|
*InsertStmt
|
|
}
|
|
|
|
func (sess *Session) InsertInto(table string) *InsertBuilder {
|
|
return &InsertBuilder{
|
|
runner: sess,
|
|
EventReceiver: sess,
|
|
Dialect: sess.Dialect,
|
|
InsertStmt: InsertInto(table),
|
|
}
|
|
}
|
|
|
|
func (tx *Tx) InsertInto(table string) *InsertBuilder {
|
|
return &InsertBuilder{
|
|
runner: tx,
|
|
EventReceiver: tx,
|
|
Dialect: tx.Dialect,
|
|
InsertStmt: InsertInto(table),
|
|
}
|
|
}
|
|
|
|
func (sess *Session) InsertBySql(query string, value ...interface{}) *InsertBuilder {
|
|
return &InsertBuilder{
|
|
runner: sess,
|
|
EventReceiver: sess,
|
|
Dialect: sess.Dialect,
|
|
InsertStmt: InsertBySql(query, value...),
|
|
}
|
|
}
|
|
|
|
func (tx *Tx) InsertBySql(query string, value ...interface{}) *InsertBuilder {
|
|
return &InsertBuilder{
|
|
runner: tx,
|
|
EventReceiver: tx,
|
|
Dialect: tx.Dialect,
|
|
InsertStmt: InsertBySql(query, value...),
|
|
}
|
|
}
|
|
|
|
func (b *InsertBuilder) Pair(column string, value interface{}) *InsertBuilder {
|
|
b.Column = append(b.Column, column)
|
|
switch len(b.Value) {
|
|
case 0:
|
|
b.InsertStmt.Values(value)
|
|
case 1:
|
|
b.Value[0] = append(b.Value[0], value)
|
|
default:
|
|
panic("pair only allows one record to insert")
|
|
}
|
|
return b
|
|
}
|
|
|
|
func (b *InsertBuilder) Exec() (sql.Result, error) {
|
|
return b.ExecContext(context.Background())
|
|
}
|
|
|
|
func (b *InsertBuilder) ExecContext(ctx context.Context) (sql.Result, error) {
|
|
result, err := exec(ctx, b.runner, b.EventReceiver, b, b.Dialect)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if b.RecordID.IsValid() {
|
|
if id, err := result.LastInsertId(); err == nil {
|
|
b.RecordID.SetInt(id)
|
|
}
|
|
}
|
|
|
|
return result, nil
|
|
}
|
|
|
|
func (b *InsertBuilder) LoadContext(ctx context.Context, value interface{}) error {
|
|
_, err := query(ctx, b.runner, b.EventReceiver, b, b.Dialect, value)
|
|
return err
|
|
}
|
|
|
|
func (b *InsertBuilder) Load(value interface{}) error {
|
|
return b.LoadContext(context.Background(), value)
|
|
}
|
|
|
|
func (b *InsertBuilder) Columns(column ...string) *InsertBuilder {
|
|
b.InsertStmt.Columns(column...)
|
|
return b
|
|
}
|
|
|
|
func (b *InsertBuilder) Returning(column ...string) *InsertBuilder {
|
|
b.InsertStmt.Returning(column...)
|
|
return b
|
|
}
|
|
|
|
func (b *InsertBuilder) Record(structValue interface{}) *InsertBuilder {
|
|
v := reflect.Indirect(reflect.ValueOf(structValue))
|
|
if v.Kind() == reflect.Struct && v.CanSet() {
|
|
// ID is recommended by golint here
|
|
for _, name := range []string{"Id", "ID"} {
|
|
field := v.FieldByName(name)
|
|
if field.IsValid() && field.Kind() == reflect.Int64 {
|
|
b.RecordID = field
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
b.InsertStmt.Record(structValue)
|
|
return b
|
|
}
|
|
|
|
func (b *InsertBuilder) Values(value ...interface{}) *InsertBuilder {
|
|
b.InsertStmt.Values(value...)
|
|
return b
|
|
}
|