package bun
import (
"fmt"
"reflect"
"strconv"
"github.com/uptrace/bun/dialect/feature"
"github.com/uptrace/bun/schema"
)
type ValuesQuery struct {
baseQuery
customValueQuery
withOrder bool
}
var _ schema .NamedArgAppender = (*ValuesQuery )(nil )
func NewValuesQuery (db *DB , model interface {}) *ValuesQuery {
q := &ValuesQuery {
baseQuery : baseQuery {
db : db ,
conn : db .DB ,
},
}
q .setTableModel (model )
return q
}
func (q *ValuesQuery ) Conn (db IConn ) *ValuesQuery {
q .setConn (db )
return q
}
func (q *ValuesQuery ) Value (column string , expr string , args ...interface {}) *ValuesQuery {
if q .table == nil {
q .err = errNilModel
return q
}
q .addValue (q .table , column , expr , args )
return q
}
func (q *ValuesQuery ) WithOrder () *ValuesQuery {
q .withOrder = true
return q
}
func (q *ValuesQuery ) AppendNamedArg (fmter schema .Formatter , b []byte , name string ) ([]byte , bool ) {
switch name {
case "Columns" :
bb , err := q .AppendColumns (fmter , b )
if err != nil {
q .setErr (err )
return b , true
}
return bb , true
}
return b , false
}
func (q *ValuesQuery ) AppendColumns (fmter schema .Formatter , b []byte ) (_ []byte , err error ) {
if q .err != nil {
return nil , q .err
}
if q .model == nil {
return nil , errNilModel
}
if q .tableModel != nil {
fields , err := q .getFields ()
if err != nil {
return nil , err
}
b = appendColumns (b , "" , fields )
if q .withOrder {
b = append (b , ", _order" ...)
}
return b , nil
}
switch model := q .model .(type ) {
case *mapSliceModel :
return model .appendColumns (fmter , b )
}
return nil , fmt .Errorf ("bun: Values does not support %T" , q .model )
}
func (q *ValuesQuery ) Operation () string {
return "SELECT"
}
func (q *ValuesQuery ) AppendQuery (fmter schema .Formatter , b []byte ) (_ []byte , err error ) {
if q .err != nil {
return nil , q .err
}
if q .model == nil {
return nil , errNilModel
}
fmter = formatterWithModel (fmter , q )
if q .tableModel != nil {
fields , err := q .getFields ()
if err != nil {
return nil , err
}
return q .appendQuery (fmter , b , fields )
}
switch model := q .model .(type ) {
case *mapSliceModel :
return model .appendValues (fmter , b )
}
return nil , fmt .Errorf ("bun: Values does not support %T" , q .model )
}
func (q *ValuesQuery ) appendQuery (
fmter schema .Formatter ,
b []byte ,
fields []*schema .Field ,
) (_ []byte , err error ) {
b = append (b , "VALUES " ...)
if q .db .features .Has (feature .ValuesRow ) {
b = append (b , "ROW(" ...)
} else {
b = append (b , '(' )
}
switch model := q .tableModel .(type ) {
case *structTableModel :
b , err = q .appendValues (fmter , b , fields , model .strct )
if err != nil {
return nil , err
}
if q .withOrder {
b = append (b , ", " ...)
b = strconv .AppendInt (b , 0 , 10 )
}
case *sliceTableModel :
slice := model .slice
sliceLen := slice .Len ()
for i := 0 ; i < sliceLen ; i ++ {
if i > 0 {
b = append (b , "), " ...)
if q .db .features .Has (feature .ValuesRow ) {
b = append (b , "ROW(" ...)
} else {
b = append (b , '(' )
}
}
b , err = q .appendValues (fmter , b , fields , slice .Index (i ))
if err != nil {
return nil , err
}
if q .withOrder {
b = append (b , ", " ...)
b = strconv .AppendInt (b , int64 (i ), 10 )
}
}
default :
return nil , fmt .Errorf ("bun: Values does not support %T" , q .model )
}
b = append (b , ')' )
return b , nil
}
func (q *ValuesQuery ) appendValues (
fmter schema .Formatter , b []byte , fields []*schema .Field , strct reflect .Value ,
) (_ []byte , err error ) {
isTemplate := fmter .IsNop ()
for i , f := range fields {
if i > 0 {
b = append (b , ", " ...)
}
app , ok := q .modelValues [f .Name ]
if ok {
b , err = app .AppendQuery (fmter , b )
if err != nil {
return nil , err
}
continue
}
if isTemplate {
b = append (b , '?' )
} else {
b = f .AppendValue (fmter , b , indirect (strct ))
}
if fmter .HasFeature (feature .DoubleColonCast ) {
b = append (b , "::" ...)
b = append (b , f .UserSQLType ...)
}
}
return b , nil
}
The pages are generated with Golds v0.3.6 . (GOOS=darwin GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds .