~netlandish/links-dev

links: api: getTags was missing the tag count. It's been added. v1 APPLIED

Peter Sanchez: 1
 api: getTags was missing the tag count. It's been added.

 2 files changed, 89 insertions(+), 9 deletions(-)
Export patchset (mbox)
How do I use this?

Copy & paste the following snippet into your terminal to import this patchset into git:

curl -s https://lists.code.netlandish.com/~netlandish/links-dev/patches/222/mbox | git am -3
Learn more about email & git

[PATCH links] api: getTags was missing the tag count. It's been added. Export this patch

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
Applied.

To git@git.code.netlandish.com:~netlandish/links
   1bc342d..e4a7eb8  master -> master