Changelog-fixed: getTags was not including tag count. Now it is.
Changelog-updated: api version bumped to 0.11.2
---
api/graph/schema.resolvers.go | 32 ++++++++++++-----
models/tag.go | 66 +++++++++++++++++++++++++++++++++++
2 files changed, 89 insertions(+), 9 deletions(-)
diff --git a/api/graph/schema.resolvers.go b/api/graph/schema.resolvers.go
index 55e5c5a..f4990c3 100644
--- a/api/graph/schema.resolvers.go
+++ b/api/graph/schema.resolvers.go
@@ -5127,7 +5127,7 @@ func (r *queryResolver) Version(ctx context.Context) (*model.Version, error) {
return &model.Version{
Major: 0,
Minor: 11,
- Patch: 1,
+ Patch: 2,
DeprecationDate: nil,
}, nil
}
@@ -5854,22 +5854,36 @@ func (r *queryResolver) GetTags(ctx context.Context, input model.GetTagsInput) (
fq = sq.Eq{"ll.org_id": org.ID}
}
} else {
- // No service specified. Give tags for all services
- fq = sq.Or{
- sq.Eq{"ol.org_id": org.ID},
- sq.Eq{"ll.org_id": org.ID},
- sq.Eq{"s.org_id": org.ID},
- }
+ fq = sq.Expr(`(
+ EXISTS (SELECT 1 FROM tag_links _tl JOIN org_links _ol ON _ol.id = _tl.org_link_id WHERE _tl.tag_id = t.id AND _ol.org_id = ?)
+ OR EXISTS (SELECT 1 FROM tag_link_shorts _ts JOIN link_shorts _s ON _s.id = _ts.link_short_id WHERE _ts.tag_id = t.id AND _s.org_id = ?)
+ OR EXISTS (SELECT 1 FROM tag_listings _tll JOIN listings _ll ON _ll.id = _tll.listing_id WHERE _tll.tag_id = t.id AND _ll.org_id = ?)
+ )`, org.ID, org.ID, org.ID)
}
opts := &database.FilterOptions{
Filter: fq,
Limit: 250,
- OrderBy: "name ASC",
+ OrderBy: "t.id ASC",
}
// Set pagination limit to 250 for tag pagination
ctx = PaginationContext(ctx, 250)
+
+ if input.Limit == nil {
+ defaultLimit := 250
+ input.Limit = &defaultLimit
+ }
+
+ getTagsFn := func(ctx context.Context, opts *database.FilterOptions) ([]*models.Tag, error) {
+ var svc *string
+ if input.Service != nil {
+ s := string(*input.Service)
+ svc = &s
+ }
+ return models.GetTagsWithCount(ctx, opts, svc, org.ID)
+ }
+
tags, pageInfo, err := QueryModel(
ctx,
opts,
@@ -5878,7 +5892,7 @@ func (r *queryResolver) GetTags(ctx context.Context, input model.GetTagsInput) (
input.Limit,
input.Before,
input.After,
- models.GetTags,
+ getTagsFn,
func(tag *models.Tag) int {
return tag.ID
},
diff --git a/models/tag.go b/models/tag.go
index c9cbcfa..4eb502b 100644
--- a/models/tag.go
+++ b/models/tag.go
@@ -67,6 +67,72 @@ func TagRelationOrderString(v TagCloudOrdering) string {
return "LOWER(t.name) ASC"
}
+// GetTagsWithCount returns tags with usage counts.
+func GetTagsWithCount(ctx context.Context, opts *database.FilterOptions, service *string, orgID int) ([]*Tag, error) {
+ if opts == nil {
+ opts = &database.FilterOptions{}
+ }
+ tz := timezone.ForContext(ctx)
+ tags := make([]*Tag, 0)
+ if err := database.WithTx(ctx, database.TxOptionsRO, func(tx *sql.Tx) error {
+ q := opts.GetBuilder(nil)
+ q = q.Columns("t.id", "t.name", "t.slug", "t.created_on").
+ From("tags t")
+
+ if service != nil {
+ switch *service {
+ case DomainServiceLinks:
+ q = q.Join("tag_links tl ON tl.tag_id = t.id").
+ Join("org_links ol ON ol.id = tl.org_link_id").
+ Column("count(*) as tag_count")
+ case DomainServiceShort:
+ q = q.Join("tag_link_shorts ts ON ts.tag_id = t.id").
+ Join("link_shorts s ON ts.link_short_id = s.id").
+ Column("count(*) as tag_count")
+ case DomainServiceList:
+ q = q.Join("tag_listings tll ON tll.tag_id = t.id").
+ Join("listings ll ON tll.listing_id = ll.id").
+ Column("count(*) as tag_count")
+ }
+ q = q.GroupBy("t.id", "t.name", "t.slug", "t.created_on")
+ } else {
+ q = q.Column(`(
+ (SELECT COUNT(*) FROM tag_links _tl JOIN org_links _ol ON _ol.id = _tl.org_link_id WHERE _tl.tag_id = t.id AND _ol.org_id = ?) +
+ (SELECT COUNT(*) FROM tag_link_shorts _ts JOIN link_shorts _s ON _s.id = _ts.link_short_id WHERE _ts.tag_id = t.id AND _s.org_id = ?) +
+ (SELECT COUNT(*) FROM tag_listings _tll JOIN listings _ll ON _ll.id = _tll.listing_id WHERE _tll.tag_id = t.id AND _ll.org_id = ?)
+ ) as tag_count`, orgID, orgID, orgID)
+ }
+
+ rows, err := q.
+ PlaceholderFormat(database.GetPlaceholderFormat()).
+ RunWith(tx).
+ QueryContext(ctx)
+ if err != nil {
+ if err == sql.ErrNoRows {
+ return nil
+ }
+ return err
+ }
+ defer rows.Close()
+
+ for rows.Next() {
+ var t Tag
+ if err = rows.Scan(&t.ID, &t.Name, &t.Slug, &t.CreatedOn, &t.Count); err != nil {
+ return err
+ }
+ err = t.ToLocalTZ(tz)
+ if err != nil {
+ return err
+ }
+ tags = append(tags, &t)
+ }
+ return nil
+ }); err != nil {
+ return nil, err
+ }
+ return tags, nil
+}
+
// GetTags ...
func GetTags(ctx context.Context, opts *database.FilterOptions) ([]*Tag, error) {
if opts == nil {
--
2.52.0