M api/graph/generated.go => api/graph/generated.go +18 -2
@@ 19763,7 19763,7 @@ func (ec *executionContext) unmarshalInputGetLinkShortInput(ctx context.Context,
asMap[k] = v
}
- fieldsInOrder := [...]string{"orgSlug", "limit", "after", "before", "tag"}
+ fieldsInOrder := [...]string{"orgSlug", "limit", "after", "before", "tag", "excludeTag"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ 19810,6 19810,14 @@ func (ec *executionContext) unmarshalInputGetLinkShortInput(ctx context.Context,
if err != nil {
return it, err
}
+ case "excludeTag":
+ var err error
+
+ ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("excludeTag"))
+ it.ExcludeTag, err = ec.unmarshalOString2áš–string(ctx, v)
+ if err != nil {
+ return it, err
+ }
}
}
@@ 19883,7 19891,7 @@ func (ec *executionContext) unmarshalInputGetListingInput(ctx context.Context, o
asMap[k] = v
}
- fieldsInOrder := [...]string{"orgSlug", "limit", "after", "before", "tag"}
+ fieldsInOrder := [...]string{"orgSlug", "limit", "after", "before", "tag", "excludeTag"}
for _, k := range fieldsInOrder {
v, ok := asMap[k]
if !ok {
@@ 19930,6 19938,14 @@ func (ec *executionContext) unmarshalInputGetListingInput(ctx context.Context, o
if err != nil {
return it, err
}
+ case "excludeTag":
+ var err error
+
+ ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("excludeTag"))
+ it.ExcludeTag, err = ec.unmarshalOString2áš–string(ctx, v)
+ if err != nil {
+ return it, err
+ }
}
}
M api/graph/model/models_gen.go => api/graph/model/models_gen.go +12 -10
@@ 158,11 158,12 @@ type GetLinkInput struct {
}
type GetLinkShortInput struct {
- OrgSlug string `json:"orgSlug"`
- Limit *int `json:"limit,omitempty"`
- After *Cursor `json:"after,omitempty"`
- Before *Cursor `json:"before,omitempty"`
- Tag *string `json:"tag,omitempty"`
+ OrgSlug string `json:"orgSlug"`
+ Limit *int `json:"limit,omitempty"`
+ After *Cursor `json:"after,omitempty"`
+ Before *Cursor `json:"before,omitempty"`
+ Tag *string `json:"tag,omitempty"`
+ ExcludeTag *string `json:"excludeTag,omitempty"`
}
type GetListingDetailInput struct {
@@ 174,11 175,12 @@ type GetListingDetailInput struct {
}
type GetListingInput struct {
- OrgSlug string `json:"orgSlug"`
- Limit *int `json:"limit,omitempty"`
- After *Cursor `json:"after,omitempty"`
- Before *Cursor `json:"before,omitempty"`
- Tag *string `json:"tag,omitempty"`
+ OrgSlug string `json:"orgSlug"`
+ Limit *int `json:"limit,omitempty"`
+ After *Cursor `json:"after,omitempty"`
+ Before *Cursor `json:"before,omitempty"`
+ Tag *string `json:"tag,omitempty"`
+ ExcludeTag *string `json:"excludeTag,omitempty"`
}
type GetPaymentInput struct {
M api/graph/schema.graphqls => api/graph/schema.graphqls +2 -0
@@ 454,6 454,7 @@ input GetLinkShortInput {
after: Cursor
before: Cursor
tag: String
+ excludeTag: String
}
input GetListingInput {
@@ 462,6 463,7 @@ input GetListingInput {
after: Cursor
before: Cursor
tag: String
+ excludeTag: String
}
input GetListingDetailInput {
M api/graph/schema.resolvers.go => api/graph/schema.resolvers.go +26 -17
@@ 4754,7 4754,8 @@ func (r *queryResolver) GetOrgLinks(ctx context.Context, input *model.GetLinkInp
excludeTagList = strings.Split(*input.ExcludeTag, ",")
}
// Filter based on tags
- subQText, subQVal, err := links.GetTagSubQuery(tagList, excludeTagList)
+ f := links.NewTagQuery("tag_links", "org_link_id")
+ subQText, subQVal, err := f.GetSubQuery(tagList, excludeTagList)
if err != nil {
return nil, err
}
@@ 5066,20 5067,24 @@ func (r *queryResolver) GetLinkShorts(ctx context.Context, input *model.GetLinkS
return nil, nil
}
- if input.Tag != nil && *input.Tag != "" {
- subQ := sq.Select("tl.link_short_id").
- From("tag_link_shorts tl").
- LeftJoin("tags t ON t.id = tl.tag_id").
- Where("t.slug = ?", *input.Tag)
+ if (input.Tag != nil && *input.Tag != "") || (input.ExcludeTag != nil && *input.ExcludeTag != "") {
+ var tagList = make([]string, 0)
+ if input.Tag != nil && *input.Tag != "" {
+ tagList = strings.Split(*input.Tag, ",")
+ }
- subQText, _, err := subQ.ToSql()
+ var excludeTagList = make([]string, 0)
+ if input.ExcludeTag != nil && *input.ExcludeTag != "" {
+ excludeTagList = strings.Split(*input.ExcludeTag, ",")
+ }
+ f := links.NewTagQuery("tag_link_shorts", "link_short_id")
+ subQText, subQVal, err := f.GetSubQuery(tagList, excludeTagList)
if err != nil {
return nil, err
}
-
linkOpts.Filter = sq.And{
linkOpts.Filter,
- sq.Expr("l.id IN ("+subQText+")", *input.Tag),
+ sq.Expr("l.id IN ("+subQText+")", subQVal...),
}
}
@@ 5258,20 5263,24 @@ func (r *queryResolver) GetListings(ctx context.Context, input *model.GetListing
return nil, nil
}
- if input.Tag != nil && *input.Tag != "" {
- subQ := sq.Select("tl.listing_id").
- From("tag_listings tl").
- LeftJoin("tags t ON t.id = tl.tag_id").
- Where("t.slug = ?", *input.Tag)
+ if (input.Tag != nil && *input.Tag != "") || (input.ExcludeTag != nil && *input.ExcludeTag != "") {
+ var tagList = make([]string, 0)
+ if input.Tag != nil && *input.Tag != "" {
+ tagList = strings.Split(*input.Tag, ",")
+ }
- subQText, _, err := subQ.ToSql()
+ var excludeTagList = make([]string, 0)
+ if input.ExcludeTag != nil && *input.ExcludeTag != "" {
+ excludeTagList = strings.Split(*input.ExcludeTag, ",")
+ }
+ f := links.NewTagQuery("tag_listings", "listing_id")
+ subQText, subQVal, err := f.GetSubQuery(tagList, excludeTagList)
if err != nil {
return nil, err
}
-
listingOpts.Filter = sq.And{
listingOpts.Filter,
- sq.Expr("l.id IN ("+subQText+")", *input.Tag),
+ sq.Expr("l.id IN ("+subQText+")", subQVal...),
}
}
M helpers.go => helpers.go +19 -7
@@ 709,7 709,19 @@ func CreateNoteURL(domain string) (string, string) {
return noteURL.String(), noteHash
}
-func GetTagSubQuery(tags, excludeTags []string) (string, []interface{}, error) {
+type TagQuery struct {
+ table string
+ column string
+}
+
+func NewTagQuery(t, c string) *TagQuery {
+ return &TagQuery{
+ table: t,
+ column: c,
+ }
+}
+
+func (t TagQuery) GetSubQuery(tags, excludeTags []string) (string, []interface{}, error) {
subQOpts := &database.FilterOptions{
Filter: sq.And{},
}
@@ 728,8 740,8 @@ func GetTagSubQuery(tags, excludeTags []string) (string, []interface{}, error) {
// that have a relation to an excluded target tag
// no matter if that org_link_id has any relation
// to one of the previous tags (included)
- excludeSubQ := sq.Select("tl.org_link_id").
- From("tag_links tl").
+ excludeSubQ := sq.Select(fmt.Sprintf("tl.%s", t.column)).
+ From(fmt.Sprintf("%s tl", t.table)).
LeftJoin("tags t ON t.id = tl.tag_id").
Where(sq.Eq{"t.slug": excludeTags})
excludeSubQText, excludeSubQVal, err := excludeSubQ.ToSql()
@@ 739,12 751,12 @@ func GetTagSubQuery(tags, excludeTags []string) (string, []interface{}, error) {
subQOpts.Filter = sq.And{
subQOpts.Filter,
- sq.Expr("tl.org_link_id NOT IN ("+excludeSubQText+")", excludeSubQVal...),
+ sq.Expr(fmt.Sprintf("tl.%s NOT IN (%s)", t.column, excludeSubQText), excludeSubQVal...),
}
}
- subQ := sq.Select("tl.org_link_id").
- From("tag_links tl").
+ subQ := sq.Select(fmt.Sprintf("tl.%s", t.column)).
+ From(fmt.Sprintf("%s tl", t.table)).
LeftJoin("tags t ON t.id = tl.tag_id").
Where(subQOpts.Filter)
@@ 755,7 767,7 @@ func GetTagSubQuery(tags, excludeTags []string) (string, []interface{}, error) {
// include ONLY the org_link_id that have ALL
// target tags
subQ = subQ.
- GroupBy("tl.org_link_id").
+ GroupBy(fmt.Sprintf("tl.%s", t.column)).
Having(sq.Eq{"COUNT(DISTINCT tag_id)": len(tags)})
}