From a28f52924470dc783a8404d19c8bbc4cb4a3ca3c Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Tue, 12 May 2020 10:33:19 -0400 Subject: [PATCH] DRY up repository queries a bit --- api/graph/model/cursor.go | 11 ++---- api/graph/model/repository.go | 53 +++++++++++++++++++++------ api/graph/schema.resolvers.go | 68 ++--------------------------------- 3 files changed, 48 insertions(+), 84 deletions(-) diff --git a/api/graph/model/cursor.go b/api/graph/model/cursor.go index 69b8f54..7039125 100644 --- a/api/graph/model/cursor.go +++ b/api/graph/model/cursor.go @@ -12,7 +12,6 @@ import ( type Cursor struct { Count int `json:"count"` Next string `json:"next"` - OrderBy string `json:"order_by"` Search string `json:"search"` } @@ -53,18 +52,14 @@ func derefOrInt(i *int, d int) int { func NewCursor(filter *Filter) *Cursor { if filter != nil { return &Cursor{ - Next: "", - - Count: derefOrInt(filter.Count, 25), - // TODO: - OrderBy: "", - Search: "", + Next: "", + Count: derefOrInt(filter.Count, 25), + Search: "", // TODO } } return &Cursor{ Count: 25, Next: "", - OrderBy: "", Search: "", } } diff --git a/api/graph/model/repository.go b/api/graph/model/repository.go index 86a8247..7a059e6 100644 --- a/api/graph/model/repository.go +++ b/api/graph/model/repository.go @@ -2,6 +2,7 @@ package model import ( "context" + "database/sql" "time" "strconv" @@ -64,7 +65,8 @@ func (r *Repository) Select(ctx context.Context) []string { "upstreamUrl": "upstream_uri", }), database.WithAlias(r.alias, "path"), - database.WithAlias(r.alias, "owner_id")) + database.WithAlias(r.alias, "owner_id"), + database.WithAlias(r.alias, "updated")) } func (r *Repository) As(alias string) *Repository { @@ -82,20 +84,51 @@ func (r *Repository) Fields(ctx context.Context) []interface{} { "visibility": &r.Visibility, "upstream_url": &r.UpstreamURL, }) - return append(fields, &r.Path, &r.OwnerID) + return append(fields, &r.Path, &r.OwnerID, &r.Updated) } -func (r *Repository) ApplyCursor(q sq.SelectBuilder, c *Cursor) sq.SelectBuilder { - if c.Next != "" { - id, _ := strconv.Atoi(c.Next) - q = q.Where(r.alias + `.id <= ?`, id) +func (r *Repository) QueryWithCursor(ctx context.Context, + db *sql.DB, q sq.SelectBuilder, cur *Cursor) ([]*Repository, *Cursor) { + var ( + err error + rows *sql.Rows + ) + + if cur.Next != "" { + ts, _ := strconv.ParseInt(cur.Next, 10, 64) + updated := time.Unix(ts, 0) + q = q.Where(database.WithAlias(r.alias, "updated") + "<= ?", updated) + } + q = q. + OrderBy(database.WithAlias(r.alias, "updated") + " DESC"). + Limit(uint64(cur.Count + 1)) + + if rows, err = q.RunWith(db).QueryContext(ctx); err != nil { + panic(err) } - if c.OrderBy != "" { - q = q.OrderBy(c.OrderBy) + defer rows.Close() + + var repos []*Repository + for rows.Next() { + var repo Repository + if err := rows.Scan(repo.Fields(ctx)...); err != nil { + panic(err) + } + repos = append(repos, &repo) + } + + if len(repos) > cur.Count { + cur = &Cursor{ + Count: cur.Count, + Next: strconv.FormatInt(repos[len(repos)-1].Updated.Unix(), 10), + Search: cur.Search, + } + repos = repos[:cur.Count] } else { - q = q.OrderBy(r.alias + `.id DESC`) + cur = nil } - return q.Limit(uint64(c.Count + 1)) + + return repos, cur } func (r *Repository) DefaultSearch(query sq.SelectBuilder, diff --git a/api/graph/schema.resolvers.go b/api/graph/schema.resolvers.go index 4a1cc96..c812eb1 100644 --- a/api/graph/schema.resolvers.go +++ b/api/graph/schema.resolvers.go @@ -5,10 +5,8 @@ package graph import ( "context" - "database/sql" "fmt" "sort" - "strconv" "strings" "git.sr.ht/~sircmpwn/git.sr.ht/api/auth" @@ -76,11 +74,6 @@ func (r *queryResolver) User(ctx context.Context, username string) (*model.User, } func (r *queryResolver) Repositories(ctx context.Context, cursor *model.Cursor, filter *model.Filter) (*model.RepositoryCursor, error) { - var ( - err error - rows *sql.Rows - ) - if cursor == nil { cursor = model.NewCursor(filter) } @@ -90,34 +83,8 @@ func (r *queryResolver) Repositories(ctx context.Context, cursor *model.Cursor, Select(ctx, repo). From(`repository repo`). Where(`repo.owner_id = ?`, auth.ForContext(ctx).ID) - query = repo.ApplyCursor(query, cursor) - - if rows, err = query.RunWith(r.DB).QueryContext(ctx); err != nil { - panic(err) - } - defer rows.Close() - - var repos []*model.Repository - for rows.Next() { - var repo model.Repository - if err := rows.Scan(repo.Fields(ctx)...); err != nil { - panic(err) - } - repos = append(repos, &repo) - } - - if len(repos) > cursor.Count { - cursor = &model.Cursor{ - Count: cursor.Count, - Next: strconv.Itoa(repos[len(repos)-1].ID), - OrderBy: `id DESC`, - Search: "", - } - repos = repos[:cursor.Count] - } else { - cursor = nil - } + repos, cursor := repo.QueryWithCursor(ctx, r.DB, query, cursor) return &model.RepositoryCursor{repos, cursor}, nil } @@ -173,11 +140,6 @@ func (r *treeResolver) Entries(ctx context.Context, obj *model.Tree, cursor *mod } func (r *userResolver) Repositories(ctx context.Context, obj *model.User, cursor *model.Cursor, filter *model.Filter) (*model.RepositoryCursor, error) { - var ( - err error - rows *sql.Rows - ) - if cursor == nil { cursor = model.NewCursor(filter) } @@ -187,34 +149,8 @@ func (r *userResolver) Repositories(ctx context.Context, obj *model.User, cursor Select(ctx, repo). From(`repository repo`). Where(`repo.owner_id = ?`, obj.ID) - query = repo.ApplyCursor(query, cursor) - - if rows, err = query.RunWith(r.DB).QueryContext(ctx); err != nil { - panic(err) - } - defer rows.Close() - - var repos []*model.Repository - for rows.Next() { - var repo model.Repository - if err := rows.Scan(repo.Fields(ctx)...); err != nil { - panic(err) - } - repos = append(repos, &repo) - } - - if len(repos) > cursor.Count { - cursor = &model.Cursor{ - Count: cursor.Count, - Next: strconv.Itoa(repos[len(repos)-1].ID), - OrderBy: `id DESC`, - Search: "", - } - repos = repos[:cursor.Count] - } else { - cursor = nil - } + repos, cursor := repo.QueryWithCursor(ctx, r.DB, query, cursor) return &model.RepositoryCursor{repos, cursor}, nil } -- 2.38.4