Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/store/postgres/audit_record_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ func (r AuditRecordRepository) buildFilteredQuery(rqlQuery *rql.Query) (*goqu.Se
rqlQuery = utils.NewRQLQuery("", utils.DefaultOffset, utils.DefaultLimit, []rql.Filter{}, []rql.Sort{}, []string{})
}

baseStmt := dialect.From(TABLE_AUDITRECORDS).Where(goqu.Ex{"deleted_at": nil})
baseStmt := dialect.From(TABLE_AUDITRECORDS).Prepared(true).Where(goqu.Ex{"deleted_at": nil})

// Apply filters
baseStmt, err := utils.AddRQLFiltersInQuery(baseStmt, rqlQuery, auditRecordRQLFilterSupportedColumns, auditrecord.AuditRecordRQLSchema{})
Expand Down
12 changes: 6 additions & 6 deletions internal/store/postgres/org_billing_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,9 +407,9 @@ func addRQLSortInQuery(query *goqu.SelectDataset, rql *rql.Query) (*goqu.SelectD
func processStringDataType(filter rql.Filter, query *goqu.SelectDataset) *goqu.SelectDataset {
switch filter.Operator {
case OPERATOR_EMPTY:
query = query.Where(goqu.L(fmt.Sprintf("coalesce(%s, '') = ''", filter.Name)))
query = query.Where(goqu.Or(goqu.I(filter.Name).IsNull(), goqu.I(filter.Name).Eq("")))
case OPERATOR_NOT_EMPTY:
query = query.Where(goqu.L(fmt.Sprintf("coalesce(%s, '') != ''", filter.Name)))
query = query.Where(goqu.And(goqu.I(filter.Name).IsNotNull(), goqu.I(filter.Name).Neq("")))
case OPERATOR_IN:
// process the values of in operator as comma separated list
query = query.Where(goqu.Cast(goqu.I(filter.Name), "TEXT").In(strings.Split(filter.Value.(string), ",")))
Expand All @@ -418,14 +418,14 @@ func processStringDataType(filter rql.Filter, query *goqu.SelectDataset) *goqu.S
query = query.Where(goqu.Cast(goqu.I(filter.Name), "TEXT").NotIn(strings.Split(filter.Value.(string), ",")))
case OPERATOR_LIKE:
// some semi string sql types like UUID require casting to text to support like operator
query = query.Where(goqu.L(fmt.Sprintf(`"%s"::TEXT LIKE '%s'`, filter.Name, filter.Value.(string))))
query = query.Where(goqu.Cast(goqu.I(filter.Name), "TEXT").Like(filter.Value.(string)))
case OPERATOR_NOT_LIKE:
// some semi string sql types like UUID require casting to text to support like operator
query = query.Where(goqu.L(fmt.Sprintf(`"%s"::TEXT NOT LIKE '%s'`, filter.Name, filter.Value.(string))))
query = query.Where(goqu.Cast(goqu.I(filter.Name), "TEXT").NotLike(filter.Value.(string)))
case OPERATOR_ILIKE:
query = query.Where(goqu.L(fmt.Sprintf(`"%s"::TEXT ILIKE '%s'`, filter.Name, filter.Value.(string))))
query = query.Where(goqu.Cast(goqu.I(filter.Name), "TEXT").ILike(filter.Value.(string)))
case OPERATOR_NOT_ILIKE:
query = query.Where(goqu.L(fmt.Sprintf(`"%s"::TEXT NOT ILIKE '%s'`, filter.Name, filter.Value.(string))))
query = query.Where(goqu.Cast(goqu.I(filter.Name), "TEXT").NotILike(filter.Value.(string)))
Comment thread
coderabbitai[bot] marked this conversation as resolved.
default:
query = query.Where(goqu.Ex{filter.Name: goqu.Op{filter.Operator: filter.Value.(string)}})
}
Expand Down
4 changes: 2 additions & 2 deletions internal/store/postgres/org_billing_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ func TestPrepareDataQuery(t *testing.T) {
Limit: 20,
Offset: 40,
},
wantSQL: `SELECT "id", "title", "name", "state", "avatar", "updated_at", "created_at", "created_by", "country", "plan_id", "plan_name", "subscription_state", "subscription_cycle_end_at", "plan_interval", "payment_mode" FROM (SELECT "organizations"."id" AS "id", "organizations"."title" AS "title", "organizations"."name" AS "name", "organizations"."avatar" AS "avatar", "organizations"."created_at" AS "created_at", "organizations"."updated_at" AS "updated_at", "organizations"."state" AS "state", organizations.metadata->>'country' AS "country", organizations.metadata->>'poc' AS "created_by", "billing_plans"."id" AS "plan_id", "billing_plans"."name" AS "plan_name", "billing_plans"."interval" AS "plan_interval", "billing_subscriptions"."state" AS "subscription_state", "billing_subscriptions"."trial_ends_at", "billing_subscriptions"."current_period_end_at" AS "subscription_cycle_end_at", "billing_customers"."payment_mode" AS "payment_mode", ROW_NUMBER() OVER (PARTITION BY "organizations"."id" ORDER BY "billing_subscriptions"."created_at" DESC) AS "row_num" FROM "organizations" LEFT JOIN "billing_customers" ON ("organizations"."id" = "billing_customers"."org_id") LEFT JOIN "billing_subscriptions" ON (("billing_subscriptions"."customer_id" = "billing_customers"."id") AND ("billing_subscriptions"."state" != $1)) LEFT JOIN "billing_plans" ON ("billing_plans"."id" = "billing_subscriptions"."plan_id")) AS "ranked_subscriptions" WHERE (("row_num" = $2) AND ("state" = $3) AND (CAST("plan_name" AS TEXT) IN ($4, $5)) AND coalesce(subscription_state, '') != '' AND ((CAST("id" AS TEXT) ILIKE $6) OR (CAST("title" AS TEXT) ILIKE $7) OR (CAST("state" AS TEXT) ILIKE $8) OR (CAST("plan_name" AS TEXT) ILIKE $9) OR (CAST("subscription_state" AS TEXT) ILIKE $10) OR (CAST("plan_interval" AS TEXT) ILIKE $11))) ORDER BY "created_at" DESC, "title" ASC LIMIT $12 OFFSET $13`,
wantParameters: []interface{}{"canceled", int64(1), "active", "free", "premium", "%test%", "%test%", "%test%", "%test%", "%test%", "%test%", int64(20), int64(40)},
wantSQL: `SELECT "id", "title", "name", "state", "avatar", "updated_at", "created_at", "created_by", "country", "plan_id", "plan_name", "subscription_state", "subscription_cycle_end_at", "plan_interval", "payment_mode" FROM (SELECT "organizations"."id" AS "id", "organizations"."title" AS "title", "organizations"."name" AS "name", "organizations"."avatar" AS "avatar", "organizations"."created_at" AS "created_at", "organizations"."updated_at" AS "updated_at", "organizations"."state" AS "state", organizations.metadata->>'country' AS "country", organizations.metadata->>'poc' AS "created_by", "billing_plans"."id" AS "plan_id", "billing_plans"."name" AS "plan_name", "billing_plans"."interval" AS "plan_interval", "billing_subscriptions"."state" AS "subscription_state", "billing_subscriptions"."trial_ends_at", "billing_subscriptions"."current_period_end_at" AS "subscription_cycle_end_at", "billing_customers"."payment_mode" AS "payment_mode", ROW_NUMBER() OVER (PARTITION BY "organizations"."id" ORDER BY "billing_subscriptions"."created_at" DESC) AS "row_num" FROM "organizations" LEFT JOIN "billing_customers" ON ("organizations"."id" = "billing_customers"."org_id") LEFT JOIN "billing_subscriptions" ON (("billing_subscriptions"."customer_id" = "billing_customers"."id") AND ("billing_subscriptions"."state" != $1)) LEFT JOIN "billing_plans" ON ("billing_plans"."id" = "billing_subscriptions"."plan_id")) AS "ranked_subscriptions" WHERE (("row_num" = $2) AND ("state" = $3) AND (CAST("plan_name" AS TEXT) IN ($4, $5)) AND (("subscription_state" IS NOT NULL) AND ("subscription_state" != $6)) AND ((CAST("id" AS TEXT) ILIKE $7) OR (CAST("title" AS TEXT) ILIKE $8) OR (CAST("state" AS TEXT) ILIKE $9) OR (CAST("plan_name" AS TEXT) ILIKE $10) OR (CAST("subscription_state" AS TEXT) ILIKE $11) OR (CAST("plan_interval" AS TEXT) ILIKE $12))) ORDER BY "created_at" DESC, "title" ASC LIMIT $13 OFFSET $14`,
wantParameters: []interface{}{"canceled", int64(1), "active", "free", "premium", "", "%test%", "%test%", "%test%", "%test%", "%test%", "%test%", int64(20), int64(40)},
wantErr: false,
},
{
Expand Down
6 changes: 3 additions & 3 deletions internal/store/postgres/org_projects_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,9 @@ func (r OrgProjectsRepository) applyStringFilter(filter rql.Filter, field string

switch filter.Operator {
case OPERATOR_EMPTY:
condition = goqu.L(fmt.Sprintf("coalesce(%s, '') = ''", field))
condition = goqu.Or(goqu.I(field).IsNull(), goqu.I(field).Eq(""))
case OPERATOR_NOT_EMPTY:
condition = goqu.L(fmt.Sprintf("coalesce(%s, '') != ''", field))
condition = goqu.And(goqu.I(field).IsNotNull(), goqu.I(field).Neq(""))
case OPERATOR_IN, OPERATOR_NOT_IN:
condition = goqu.Ex{field: goqu.Op{filter.Operator: strings.Split(filter.Value.(string), ",")}}
case OPERATOR_LIKE, OPERATOR_NOT_LIKE:
Expand All @@ -216,7 +216,7 @@ func (r OrgProjectsRepository) applyStringFilter(filter rql.Filter, field string
func (r OrgProjectsRepository) applyDatetimeFilter(filter rql.Filter, field string, stmt *goqu.SelectDataset) *goqu.SelectDataset {
condition := goqu.Ex{
field: goqu.Op{
filter.Operator: goqu.L(fmt.Sprintf("timestamp '%s'", filter.Value)),
filter.Operator: goqu.Cast(goqu.V(filter.Value), "TIMESTAMP"),
},
}
return stmt.Where(condition)
Expand Down
4 changes: 2 additions & 2 deletions internal/store/postgres/org_projects_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ func TestOrgProjectsRepository_prepareDataQuery(t *testing.T) {
Limit: 10,
Offset: 0,
},
wantSQL: `SELECT "projects"."id", "projects"."name", "projects"."title", "projects"."state", "projects"."created_at", "projects"."org_id", COUNT(DISTINCT("policies"."principal_id")) AS "member_count", array_agg(DISTINCT users.id) AS "user_ids" FROM "policies" INNER JOIN "projects" ON ("policies"."resource_id" = "projects"."id") INNER JOIN "users" ON ("policies"."principal_id" = "users"."id") WHERE ((("principal_type" = $1) AND ("projects"."org_id" = $2)) AND ("projects"."created_at" > timestamp '2023-11-02T12:10:21.470756Z')) GROUP BY "projects"."id", "projects"."name", "projects"."title", "projects"."state", "projects"."created_at", "projects"."org_id" LIMIT $3`,
wantArgs: []interface{}{"app/user", "org123", int64(10)},
wantSQL: `SELECT "projects"."id", "projects"."name", "projects"."title", "projects"."state", "projects"."created_at", "projects"."org_id", COUNT(DISTINCT("policies"."principal_id")) AS "member_count", array_agg(DISTINCT users.id) AS "user_ids" FROM "policies" INNER JOIN "projects" ON ("policies"."resource_id" = "projects"."id") INNER JOIN "users" ON ("policies"."principal_id" = "users"."id") WHERE ((("principal_type" = $1) AND ("projects"."org_id" = $2)) AND ("projects"."created_at" > CAST($3 AS TIMESTAMP))) GROUP BY "projects"."id", "projects"."name", "projects"."title", "projects"."state", "projects"."created_at", "projects"."org_id" LIMIT $4`,
wantArgs: []interface{}{"app/user", "org123", "2023-11-02T12:10:21.470756Z", int64(10)},
wantErr: false,
},
{
Expand Down
4 changes: 2 additions & 2 deletions internal/store/postgres/org_users_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,9 @@ func (r OrgUsersRepository) buildNonRoleFilterCondition(filter rql.Filter) (goqu

switch filter.Operator {
case "empty":
return goqu.L(fmt.Sprintf("coalesce(%s, '') = ''", columnName)), nil
return goqu.Or(goqu.I(columnName).IsNull(), goqu.I(columnName).Eq("")), nil
case "notempty":
return goqu.L(fmt.Sprintf("coalesce(%s, '') != ''", columnName)), nil
return goqu.And(goqu.I(columnName).IsNotNull(), goqu.I(columnName).Neq("")), nil
case "in", "notin":
return goqu.Ex{columnName: goqu.Op{filter.Operator: strings.Split(filter.Value.(string), ",")}}, nil
case "like":
Expand Down
2 changes: 1 addition & 1 deletion internal/store/postgres/org_users_repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ func TestOrgUsersRepository_BuildNonRoleFilterCondition(t *testing.T) {
Name: "title",
Operator: "empty",
},
wantSQL: `coalesce(users.title, '') = ''`,
wantSQL: `(("users"."title" IS NULL) OR ("users"."title" = ''))`,
},
{
name: "invalid operator",
Expand Down
2 changes: 1 addition & 1 deletion internal/store/postgres/prospect_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func (r ProspectRepository) Get(ctx context.Context, id string) (prospect.Prospe
}

func (r ProspectRepository) List(ctx context.Context, rqlQuery *rql.Query) (prospect.ListProspects, error) {
baseStmt := dialect.From(TABLE_PROSPECTS)
baseStmt := dialect.From(TABLE_PROSPECTS).Prepared(true)

// apply filters
baseStmt, err := utils.AddRQLFiltersInQuery(baseStmt, rqlQuery, rqlFilerSupportedColumns, prospect.Prospect{})
Expand Down
2 changes: 1 addition & 1 deletion internal/store/postgres/userpat_repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ func (r UserPATRepository) buildPATFilteredQuery(userID, orgID string, rqlQuery
rqlQuery = utils.NewRQLQuery("", utils.DefaultOffset, utils.DefaultLimit, []rql.Filter{}, []rql.Sort{}, []string{})
}

baseStmt := dialect.From(TABLE_USER_PATS).Where(
baseStmt := dialect.From(TABLE_USER_PATS).Prepared(true).Where(
goqu.Ex{"user_id": userID},
goqu.Ex{"org_id": orgID},
goqu.Ex{"deleted_at": nil},
Expand Down
15 changes: 8 additions & 7 deletions pkg/utils/rql.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,11 @@ func AddRQLSearchInQuery(query *goqu.SelectDataset, rql *rql.Query, rqlSearchSup

searchExpressions := make([]goqu.Expression, 0)
if rql.Search != "" {
searchPattern := "%" + rql.Search + "%"
for _, col := range rqlSearchSupportedColumns {
searchExpressions = append(searchExpressions, goqu.L(
fmt.Sprintf(`"%s"::TEXT ILIKE '%%%s%%'`, col, rql.Search),
))
searchExpressions = append(searchExpressions,
goqu.Cast(goqu.I(col), "TEXT").ILike(searchPattern),
)
}
}
return query.Where(goqu.Or(searchExpressions...)), nil
Expand Down Expand Up @@ -167,20 +168,20 @@ func AddRQLFiltersInQuery(query *goqu.SelectDataset, rqlInput *rql.Query, rqlFil
func ProcessStringDataType(filter rql.Filter, query *goqu.SelectDataset) *goqu.SelectDataset {
switch filter.Operator {
case OperatorEmpty:
query = query.Where(goqu.L(fmt.Sprintf("coalesce(%s, '') = ''", filter.Name)))
query = query.Where(goqu.Or(goqu.I(filter.Name).IsNull(), goqu.I(filter.Name).Eq("")))
case OperatorNotEmpty:
query = query.Where(goqu.L(fmt.Sprintf("coalesce(%s, '') != ''", filter.Name)))
query = query.Where(goqu.And(goqu.I(filter.Name).IsNotNull(), goqu.I(filter.Name).Neq("")))
case OperatorIn, OperatorNotIn:
// process the values of in and notin operators as comma separated list
query = query.Where(goqu.Ex{
filter.Name: goqu.Op{filter.Operator: strings.Split(filter.Value.(string), ",")},
})
case OperatorLike:
// some semi-string sql types like UUID require casting to text to support like operator
query = query.Where(goqu.L(fmt.Sprintf(`"%s"::TEXT ILIKE '%s'`, filter.Name, filter.Value.(string))))
query = query.Where(goqu.Cast(goqu.I(filter.Name), "TEXT").ILike(filter.Value.(string)))
case OperatorNotLike:
// some semi-string sql types like UUID require casting to text to support like operator
query = query.Where(goqu.L(fmt.Sprintf(`"%s"::TEXT NOT ILIKE '%s'`, filter.Name, filter.Value.(string))))
query = query.Where(goqu.Cast(goqu.I(filter.Name), "TEXT").NotILike(filter.Value.(string)))
Comment thread
coderabbitai[bot] marked this conversation as resolved.
default:
query = query.Where(goqu.Ex{filter.Name: goqu.Op{filter.Operator: filter.Value.(string)}})
}
Expand Down
Loading