summaryrefslogtreecommitdiff
path: root/vendor/github.com/uptrace/bun/query_values.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/uptrace/bun/query_values.go')
-rw-r--r--vendor/github.com/uptrace/bun/query_values.go198
1 files changed, 198 insertions, 0 deletions
diff --git a/vendor/github.com/uptrace/bun/query_values.go b/vendor/github.com/uptrace/bun/query_values.go
new file mode 100644
index 000000000..323ac68ef
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/query_values.go
@@ -0,0 +1,198 @@
+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) 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
+}
+
+// AppendColumns appends the table columns. It is used by CTE.
+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) 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
+}