any.go 1.67 KB
Newer Older
Vladimir Barsukov's avatar
Vladimir Barsukov committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package zdb

import (
	"fmt"
	"github.com/google/uuid"
	"github.com/jackc/pgx/v5"
	"github.com/jackc/pgx/v5/pgtype"
	"reflect"
)

func (d *Pool) WAny(dst any, sql string, args ...any) error {
	return d.qAny(d.SrvMaster, dst, sql, args...)
}
func (d *Pool) Any(dst any, sql string, args ...any) error {
	return d.execWrapper(ConnModeSync, dst, func(conn *Conn, dst1 any) error {
		return d.qAny(conn, dst1, sql, args...)
	})
}
func (d *Pool) AnyAsync(dst any, sql string, args ...any) error {
	return d.execWrapper(ConnModeAsync, dst, func(conn *Conn, dst1 any) error {
		return d.qAny(conn, dst1, sql, args...)
	})
}

func (d *Pool) qAny(q *Conn, dst any, sql string, args ...any) error {
	var rows pgx.Rows
	var err error

	dstVal := reflect.ValueOf(dst)

	if !dstVal.IsValid() || (dstVal.Kind() == reflect.Ptr && dstVal.IsNil()) {
		return fmt.Errorf("destination must be a non nil pointer")
	}
	if dstVal.Kind() != reflect.Ptr {
		return fmt.Errorf("destination must be a pointer, got: %v", dstVal.Type())
	}

	if rows, err = q.Query(d.ctx, sql, args...); err != nil {
		return err
	}
	defer rows.Close()

	var out []map[string]any

	desc := rows.FieldDescriptions()

	for rows.Next() {
		r := map[string]any{}
		v, _ := rows.Values()

		for i, f := range desc {
Vladimir Barsukov's avatar
lint    
Vladimir Barsukov committed
52
53
			switch {
			case v[i] == nil:
Vladimir Barsukov's avatar
Vladimir Barsukov committed
54
				r[f.Name] = nil
Vladimir Barsukov's avatar
lint    
Vladimir Barsukov committed
55
			case f.DataTypeOID == pgtype.NumericOID:
Vladimir Barsukov's avatar
Vladimir Barsukov committed
56
57
				ff, _ := v[i].(pgtype.Numeric).Float64Value()
				r[f.Name] = ff.Float64
Vladimir Barsukov's avatar
lint    
Vladimir Barsukov committed
58
			case f.DataTypeOID == pgtype.UUIDOID:
Vladimir Barsukov's avatar
Vladimir Barsukov committed
59
60
61
				bb := v[i].([16]byte)
				u, _ := uuid.FromBytes(bb[:])
				r[f.Name] = u.String()
Vladimir Barsukov's avatar
lint    
Vladimir Barsukov committed
62
			default:
Vladimir Barsukov's avatar
Vladimir Barsukov committed
63
64
65
66
67
68
69
70
71
72
73
74
				r[f.Name] = v[i]
			}
		}

		out = append(out, r)
	}

	dstVal = dstVal.Elem()
	dstVal.Set(reflect.ValueOf(out))

	return nil
}