Skip to content

[proposal] :map key=somefield query annotation #2353

Open

Description

@Jille

What do you want to change?

I frequently find myself converting the results from a query to a map, keyed by one of the fields. The code looks like this:

m := map[string]gendb.User{}
users, err := gendb.QueryUsers(ctx)
for _, u := range users {
  m[u.Username] = u
}

I've been holding off on this feature request hoping that generics would cleanly solve this, but solutions with generics aren't as pretty as I'd hoped. (Using a Map plus a lambda to return a field.)

Given that sqlc has all the information needed for this, it would be a neat convenience if sqlc could generate this boilerplate for me :)

I'm willing to send a PR if approved.

What database engines need to be changed?

No response

What programming language backends need to be changed?

Go

Activity

  1. added
    enhancementNew feature or request
    triageNew issues that hasn't been reviewed
    on Jun 21, 2023
  2. added and removed
    triageNew issues that hasn't been reviewed
    on Jun 21, 2023
  3. nussjustin commented on Sep 6, 2023

    @nussjustin

    What about also adding an option to allow multiple values per key? So instead of map[string]gendb.User one could get a map[string][]gendb.User

    While not as common as the case with one value per key, I still sometimes find myself implementing this.

  4. rpstw commented on Sep 13, 2023

    @rpstw

    Another way of solving the problem:

    1. generate a unexported method listXX
    -- name: listXX :many
    select * from xx
    func (q *Queries) listXX(ctx context.Context) ([]SomeStruct, error)
    1. manually write a exported one
    func (q *Queries) ListXX(ctx context.Context) (map[string]SomeStruct, error) {
       s, _ := q.listXX(ctx)
       m := make(map[string]SomeStruct)
      for _, u := range s {
       m[u.SomeColumn] = u
     }
    
    return m, nil
    }

    Pros:

    1. less abstraction
    2. being able to do many housekeeping stuff if needed, e.g, return a map[int]SomeStruct instead of map[string]SomeStruct because another packages wants a string column instead of a int one

    Cons:

    1. not that easy to find this way
    2. some people might prefer the convenience solution as Jille said
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions