Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change Pluck/PluckMap to return slice/map of structs #105

Merged
merged 1 commit into from
Oct 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ library [![Tweet](http://jpillora.com/github-twitter-button/img/tweet.png)](http
* [Create table](#user-content-create-table)
* [Add / Modify / Drop columns](#user-content-add--modify--drop-columns)
* [Chunking Results](#user-content-chunking-results)
* [Pluck / PluckMap](#user-content-pluck--pluckmap)

## Installation

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

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

## Pluck / PluckMap

If you would like to get values of a particular column(s) of a struct and place them into slice - use `Pluck` method:
```go
dataStruct := &DataStructUser{}
res, err := db.Table(UsersTable).Pluck(dataStruct)
for k, v := range res {
val := v.(DataStructUser)
fmt.Println(val.Name) // f.e.: Alex Shmidt
}

// or use a PluckMap method to aggregate key/value pairs to a map
res, err := db.Table(UsersTable).PluckMap(dataStruct, "name", "points")
for k, m := range res {
for key, value := range m {
keyVal := key.(string)
valueVal := value.(DataStructUser)
// rest of the code ...
}
}
```

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.

Supporters gratitude:
Expand Down
35 changes: 19 additions & 16 deletions advanced.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,35 @@ func (r *DB) Find(src any, id uint64) error {
return r.Where("id", "=", id).First(src)
}

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

val = make([]interface{}, len(res))
for k, m := range res {
val[k] = m[column]
}

return
return res, nil
}

// PluckMap getting values of a particular key/value columns and place them into map
func (r *DB) PluckMap(colKey, colValue string) (val []map[interface{}]interface{}, err error) {
res, err := r.Get()
// values of the returning map is a structure passed as src and filled with data from DB
func (r *DB) PluckMap(src any, colKey, colValue string) (val []map[any]any, err error) {
resource := reflect.ValueOf(src).Elem()
if err = validateFields(resource, src, []string{colKey, colValue}); err != nil {
return nil, err
}

res, err := r.eachToStructRows(src, r.Builder.offset, r.Builder.limit)
if err != nil {
return nil, err
}

val = make([]map[interface{}]interface{}, len(res))
val = make([]map[any]any, len(res))
for k, m := range res {
val[k] = make(map[interface{}]interface{})
val[k][m[colKey]] = m[colValue]
val[k] = make(map[any]any)

fieldKeyData := getFieldValue(m, colKey)
val[k][fieldKeyData] = reflect.ValueOf(m).Interface()
}

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

// increments or decrements depending on sign
func (r *DB) incrDecr(column, sign string, on uint64) (int64, error) {
builder := r.Builder
if builder.table == "" {
bldr := r.Builder
if bldr.table == "" {
return 0, errTableCallBeforeOp
}

Expand Down
30 changes: 15 additions & 15 deletions aggregates.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,49 @@ package buildsqlx

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

return
}

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

return
}

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

return
}

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

return
}

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

return
Expand Down
Loading
Loading