Skip to content

Commit a857954

Browse files
* #104: Change Pluck/PluckMap to return slice/map of structs (#105)
Add common abstract method with EachToStruct processing data Add more tests to cover errs - Remove outdated Get method
1 parent c257705 commit a857954

File tree

5 files changed

+481
-197
lines changed

5 files changed

+481
-197
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ library [![Tweet](http://jpillora.com/github-twitter-button/img/tweet.png)](http
3434
* [Create table](#user-content-create-table)
3535
* [Add / Modify / Drop columns](#user-content-add--modify--drop-columns)
3636
* [Chunking Results](#user-content-chunking-results)
37+
* [Pluck / PluckMap](#user-content-pluck--pluckmap)
3738

3839
## Installation
3940

@@ -438,7 +439,7 @@ dataStruct := &DataStructUser{}
438439
err = db.Table(UsersTable).Select("name", "points").Chunk(dataStruct, 100, func(users []any) bool {
439440
for _, v := range users {
440441
user := v.(DataStructUser)
441-
// your code goes here e.g.:
442+
// your code goes here e.g.:
442443
sumOfPoints += user.Points
443444
}
444445

@@ -447,6 +448,28 @@ err = db.Table(UsersTable).Select("name", "points").Chunk(dataStruct, 100, func(
447448
})
448449
```
449450

451+
## Pluck / PluckMap
452+
453+
If you would like to get values of a particular column(s) of a struct and place them into slice - use `Pluck` method:
454+
```go
455+
dataStruct := &DataStructUser{}
456+
res, err := db.Table(UsersTable).Pluck(dataStruct)
457+
for k, v := range res {
458+
val := v.(DataStructUser)
459+
fmt.Println(val.Name) // f.e.: Alex Shmidt
460+
}
461+
462+
// or use a PluckMap method to aggregate key/value pairs to a map
463+
res, err := db.Table(UsersTable).PluckMap(dataStruct, "name", "points")
464+
for k, m := range res {
465+
for key, value := range m {
466+
keyVal := key.(string)
467+
valueVal := value.(DataStructUser)
468+
// rest of the code ...
469+
}
470+
}
471+
```
472+
450473
PS Why use buildsqlx? Because it is simple and fast, yet versatile. The builder code-style has been inherited from greatest web-frameworks, so u can easily query anything from db.
451474

452475
Supporters gratitude:

advanced.go

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,32 +33,35 @@ func (r *DB) Find(src any, id uint64) error {
3333
return r.Where("id", "=", id).First(src)
3434
}
3535

36-
// Pluck getting values of a particular column and place them into slice
37-
func (r *DB) Pluck(column string) (val []interface{}, err error) {
38-
res, err := r.Get()
36+
// Pluck getting values of a particular column(s) of a struct and place them into slice
37+
func (r *DB) Pluck(src any) ([]any, error) {
38+
res, err := r.eachToStructRows(src, r.Builder.offset, r.Builder.limit)
3939
if err != nil {
4040
return nil, err
4141
}
4242

43-
val = make([]interface{}, len(res))
44-
for k, m := range res {
45-
val[k] = m[column]
46-
}
47-
48-
return
43+
return res, nil
4944
}
5045

5146
// PluckMap getting values of a particular key/value columns and place them into map
52-
func (r *DB) PluckMap(colKey, colValue string) (val []map[interface{}]interface{}, err error) {
53-
res, err := r.Get()
47+
// values of the returning map is a structure passed as src and filled with data from DB
48+
func (r *DB) PluckMap(src any, colKey, colValue string) (val []map[any]any, err error) {
49+
resource := reflect.ValueOf(src).Elem()
50+
if err = validateFields(resource, src, []string{colKey, colValue}); err != nil {
51+
return nil, err
52+
}
53+
54+
res, err := r.eachToStructRows(src, r.Builder.offset, r.Builder.limit)
5455
if err != nil {
5556
return nil, err
5657
}
5758

58-
val = make([]map[interface{}]interface{}, len(res))
59+
val = make([]map[any]any, len(res))
5960
for k, m := range res {
60-
val[k] = make(map[interface{}]interface{})
61-
val[k][m[colKey]] = m[colValue]
61+
val[k] = make(map[any]any)
62+
63+
fieldKeyData := getFieldValue(m, colKey)
64+
val[k][fieldKeyData] = reflect.ValueOf(m).Interface()
6265
}
6366

6467
return
@@ -99,8 +102,8 @@ func (r *DB) Decrement(column string, on uint64) (int64, error) {
99102

100103
// increments or decrements depending on sign
101104
func (r *DB) incrDecr(column, sign string, on uint64) (int64, error) {
102-
builder := r.Builder
103-
if builder.table == "" {
105+
bldr := r.Builder
106+
if bldr.table == "" {
104107
return 0, errTableCallBeforeOp
105108
}
106109

aggregates.go

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,49 @@ package buildsqlx
22

33
// Count counts resulting rows based on clause
44
func (r *DB) Count() (cnt int64, err error) {
5-
builder := r.Builder
6-
builder.columns = []string{"COUNT(*)"}
7-
query := builder.buildSelect()
5+
bldr := r.Builder
6+
bldr.columns = []string{"COUNT(*)"}
7+
query := bldr.buildSelect()
88
err = r.Sql().QueryRow(query, prepareValues(r.Builder.whereBindings)...).Scan(&cnt)
99

1010
return
1111
}
1212

1313
// Avg calculates average for specified column
1414
func (r *DB) Avg(column string) (avg float64, err error) {
15-
builder := r.Builder
16-
builder.columns = []string{"AVG(" + column + ")"}
17-
query := builder.buildSelect()
15+
bldr := r.Builder
16+
bldr.columns = []string{"AVG(" + column + ")"}
17+
query := bldr.buildSelect()
1818
err = r.Sql().QueryRow(query, prepareValues(r.Builder.whereBindings)...).Scan(&avg)
1919

2020
return
2121
}
2222

2323
// Min calculates minimum for specified column
2424
func (r *DB) Min(column string) (min float64, err error) {
25-
builder := r.Builder
26-
builder.columns = []string{"MIN(" + column + ")"}
27-
query := builder.buildSelect()
25+
bldr := r.Builder
26+
bldr.columns = []string{"MIN(" + column + ")"}
27+
query := bldr.buildSelect()
2828
err = r.Sql().QueryRow(query, prepareValues(r.Builder.whereBindings)...).Scan(&min)
2929

3030
return
3131
}
3232

3333
// Max calculates maximum for specified column
3434
func (r *DB) Max(column string) (max float64, err error) {
35-
builder := r.Builder
36-
builder.columns = []string{"MAX(" + column + ")"}
37-
query := builder.buildSelect()
35+
bldr := r.Builder
36+
bldr.columns = []string{"MAX(" + column + ")"}
37+
query := bldr.buildSelect()
3838
err = r.Sql().QueryRow(query, prepareValues(r.Builder.whereBindings)...).Scan(&max)
3939

4040
return
4141
}
4242

4343
// Sum calculates sum for specified column
4444
func (r *DB) Sum(column string) (sum float64, err error) {
45-
builder := r.Builder
46-
builder.columns = []string{"SUM(" + column + ")"}
47-
query := builder.buildSelect()
45+
bldr := r.Builder
46+
bldr.columns = []string{"SUM(" + column + ")"}
47+
query := bldr.buildSelect()
4848
err = r.Sql().QueryRow(query, prepareValues(r.Builder.whereBindings)...).Scan(&sum)
4949

5050
return

0 commit comments

Comments
 (0)