summaryrefslogtreecommitdiff
path: root/vendor/github.com/uptrace/bun/model_map_slice.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/uptrace/bun/model_map_slice.go')
-rw-r--r--vendor/github.com/uptrace/bun/model_map_slice.go162
1 files changed, 162 insertions, 0 deletions
diff --git a/vendor/github.com/uptrace/bun/model_map_slice.go b/vendor/github.com/uptrace/bun/model_map_slice.go
new file mode 100644
index 000000000..5c6f48e44
--- /dev/null
+++ b/vendor/github.com/uptrace/bun/model_map_slice.go
@@ -0,0 +1,162 @@
+package bun
+
+import (
+ "context"
+ "database/sql"
+ "errors"
+ "sort"
+
+ "github.com/uptrace/bun/dialect/feature"
+ "github.com/uptrace/bun/schema"
+)
+
+type mapSliceModel struct {
+ mapModel
+ dest *[]map[string]interface{}
+
+ keys []string
+}
+
+var _ model = (*mapSliceModel)(nil)
+
+func newMapSliceModel(db *DB, dest *[]map[string]interface{}) *mapSliceModel {
+ return &mapSliceModel{
+ mapModel: mapModel{
+ db: db,
+ },
+ dest: dest,
+ }
+}
+
+func (m *mapSliceModel) Value() interface{} {
+ return m.dest
+}
+
+func (m *mapSliceModel) SetCap(cap int) {
+ if cap > 100 {
+ cap = 100
+ }
+ if slice := *m.dest; len(slice) < cap {
+ *m.dest = make([]map[string]interface{}, 0, cap)
+ }
+}
+
+func (m *mapSliceModel) ScanRows(ctx context.Context, rows *sql.Rows) (int, error) {
+ columns, err := rows.Columns()
+ if err != nil {
+ return 0, err
+ }
+
+ m.rows = rows
+ m.columns = columns
+ dest := makeDest(m, len(columns))
+
+ slice := *m.dest
+ if len(slice) > 0 {
+ slice = slice[:0]
+ }
+
+ var n int
+
+ for rows.Next() {
+ m.m = make(map[string]interface{}, len(m.columns))
+
+ m.scanIndex = 0
+ if err := rows.Scan(dest...); err != nil {
+ return 0, err
+ }
+
+ slice = append(slice, m.m)
+ n++
+ }
+ if err := rows.Err(); err != nil {
+ return 0, err
+ }
+
+ *m.dest = slice
+ return n, nil
+}
+
+func (m *mapSliceModel) appendColumns(fmter schema.Formatter, b []byte) (_ []byte, err error) {
+ if err := m.initKeys(); err != nil {
+ return nil, err
+ }
+
+ for i, k := range m.keys {
+ if i > 0 {
+ b = append(b, ", "...)
+ }
+ b = fmter.AppendIdent(b, k)
+ }
+
+ return b, nil
+}
+
+func (m *mapSliceModel) appendValues(fmter schema.Formatter, b []byte) (_ []byte, err error) {
+ if err := m.initKeys(); err != nil {
+ return nil, err
+ }
+ slice := *m.dest
+
+ b = append(b, "VALUES "...)
+ if m.db.features.Has(feature.ValuesRow) {
+ b = append(b, "ROW("...)
+ } else {
+ b = append(b, '(')
+ }
+
+ if fmter.IsNop() {
+ for i := range m.keys {
+ if i > 0 {
+ b = append(b, ", "...)
+ }
+ b = append(b, '?')
+ }
+ return b, nil
+ }
+
+ for i, el := range slice {
+ if i > 0 {
+ b = append(b, "), "...)
+ if m.db.features.Has(feature.ValuesRow) {
+ b = append(b, "ROW("...)
+ } else {
+ b = append(b, '(')
+ }
+ }
+
+ for j, key := range m.keys {
+ if j > 0 {
+ b = append(b, ", "...)
+ }
+ b = fmter.Dialect().Append(fmter, b, el[key])
+ }
+ }
+
+ b = append(b, ')')
+
+ return b, nil
+}
+
+func (m *mapSliceModel) initKeys() error {
+ if m.keys != nil {
+ return nil
+ }
+
+ slice := *m.dest
+ if len(slice) == 0 {
+ return errors.New("bun: map slice is empty")
+ }
+
+ first := slice[0]
+ keys := make([]string, 0, len(first))
+
+ for k := range first {
+ keys = append(keys, k)
+ }
+
+ sort.Strings(keys)
+ m.keys = keys
+
+ return nil
+}