@@ 1,4 1,5 @@
git.sr.ht/~sircmpwn/git.sr.ht v0.0.0-20200405134845-b8fbf5bf484f h1:SW8+xV65kcga0rHmQbnZkLG36yp286BcbVOdQTVo1m8=
+git.sr.ht/~sircmpwn/git.sr.ht v0.0.0-20200413150414-046cd382d7b7 h1:PYRTIcsHR5W+aPn98OCC73ly528uw5o/4Z3b5Rvc7vA=
git.sr.ht/~sircmpwn/gqlgen v0.0.0-20200412134447-57d7234737d4 h1:J/Sb88htNHzZaN6ZEF8BnRWj3LzYoTrOL4WRhZEEiQE=
git.sr.ht/~sircmpwn/gqlgen v0.0.0-20200412134447-57d7234737d4/go.mod h1:W1cijL2EqAyL1eo1WAJ3ijNVkZM2okpYyCF5TRu1VfI=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
@@ 69,7 69,7 @@ func (r *queryResolver) Me(ctx context.Context) (*model.User, error) {
}
func (r *queryResolver) User(ctx context.Context, username string) (*model.User, error) {
- panic(fmt.Errorf("not implemented"))
+ return loaders.ForContext(ctx).UsersByName.Load(username)
}
func (r *queryResolver) Repositories(ctx context.Context, next *int, filter *model.FilterBy) ([]*model.Repository, error) {
@@ 24,12 24,12 @@ type contextKey struct {
type Loaders struct {
UsersByID UsersByIDLoader
+ UsersByName UsersByNameLoader
RepositoriesByID RepositoriesByIDLoader
}
func fetchUsersByID(ctx context.Context,
db *sql.DB) func (ids []int) ([]*model.User, []error) {
-
return func (ids []int) ([]*model.User, []error) {
var (
err error
@@ 64,9 64,44 @@ func fetchUsersByID(ctx context.Context,
}
}
+func fetchUsersByName(ctx context.Context,
+ db *sql.DB) func (names []string) ([]*model.User, []error) {
+ return func (names []string) ([]*model.User, []error) {
+ var (
+ err error
+ rows *sql.Rows
+ )
+ if rows, err = db.QueryContext(ctx,`
+ SELECT `+(&model.User{}).Columns(ctx, "u")+`
+ FROM "user" u
+ WHERE u.username = ANY($1)`, pq.Array(names)); err != nil {
+ panic(err)
+ }
+ defer rows.Close()
+
+ usersByName := map[string]*model.User{}
+ for rows.Next() {
+ user := model.User{}
+ if err := rows.Scan(user.Fields(ctx)...); err != nil {
+ panic(err)
+ }
+ usersByName[user.Username] = &user
+ }
+ if err = rows.Err(); err != nil {
+ panic(err)
+ }
+
+ users := make([]*model.User, len(names))
+ for i, name := range names {
+ users[i] = usersByName[name]
+ }
+
+ return users, nil
+ }
+}
+
func fetchRepositoriesByID(ctx context.Context,
db *sql.DB) func (ids []int) ([]*model.Repository, []error) {
-
return func (ids []int) ([]*model.Repository, []error) {
var (
err error
@@ 117,6 152,11 @@ func Middleware(db *sql.DB) func(http.Handler) http.Handler {
wait: 1 * time.Millisecond,
fetch: fetchUsersByID(r.Context(), db),
},
+ UsersByName: UsersByNameLoader{
+ maxBatch: 100,
+ wait: 1 * time.Millisecond,
+ fetch: fetchUsersByName(r.Context(), db),
+ },
RepositoriesByID: RepositoriesByIDLoader{
maxBatch: 100,
wait: 1 * time.Millisecond,