fix(eventstore): sub queries (#1805)

* sub queries

* fix: tests

* add builder to tests

* new search query

* rename searchquerybuilder to builder

* remove comment from code

* test with multiple queries

* add filters test

* fix(contibute): listing

* add validate module

* fix: search queries

* remove unused event type in query

* ignore query if error in marshal

* go mod tidy

* update privacy policy query

* update queries

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Silvan
2021-07-06 13:55:57 +02:00
committed by GitHub
parent 0e472a347f
commit 5349d96ce4
85 changed files with 1258 additions and 686 deletions

View File

@@ -9,7 +9,6 @@ import (
"strings"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
z_errors "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/repository"
"github.com/lib/pq"
@@ -26,14 +25,13 @@ type querier interface {
orderByEventSequence(desc bool) string
}
type rowScan func(scan, interface{}) error
type scan func(dest ...interface{}) error
func query(ctx context.Context, criteria querier, searchQuery *repository.SearchQuery, dest interface{}) error {
query, rowScanner := prepareColumns(criteria, searchQuery.Columns)
where, values := prepareCondition(criteria, searchQuery.Filters)
if where == "" || query == "" {
return caos_errs.ThrowInvalidArgument(nil, "SQL-rWeBw", "invalid query factory")
return z_errors.ThrowInvalidArgument(nil, "SQL-rWeBw", "invalid query factory")
}
query += where
@@ -51,7 +49,7 @@ func query(ctx context.Context, criteria querier, searchQuery *repository.Search
rows, err := criteria.db().QueryContext(ctx, query, values...)
if err != nil {
logging.Log("SQL-HP3Uk").WithError(err).Info("query failed")
return caos_errs.ThrowInternal(err, "SQL-IJuyR", "unable to filter events")
return z_errors.ThrowInternal(err, "SQL-IJuyR", "unable to filter events")
}
defer rows.Close()
@@ -125,31 +123,37 @@ func eventsScanner(scanner scan, dest interface{}) (err error) {
return nil
}
func prepareCondition(criteria querier, filters []*repository.Filter) (clause string, values []interface{}) {
values = make([]interface{}, len(filters))
clauses := make([]string, len(filters))
func prepareCondition(criteria querier, filters [][]*repository.Filter) (clause string, values []interface{}) {
values = make([]interface{}, 0, len(filters))
if len(filters) == 0 {
return clause, values
}
for i, filter := range filters {
value := filter.Value
switch value.(type) {
case []bool, []float64, []int64, []string, []repository.AggregateType, []repository.EventType, *[]bool, *[]float64, *[]int64, *[]string, *[]repository.AggregateType, *[]repository.EventType:
value = pq.Array(value)
case map[string]interface{}:
var err error
value, err = json.Marshal(value)
logging.Log("SQL-BSsNy").OnError(err).Warn("unable to marshal search value")
}
clauses[i] = getCondition(criteria, filter)
if clauses[i] == "" {
return "", nil
clauses := make([]string, len(filters))
for idx, filter := range filters {
subClauses := make([]string, 0, len(filter))
for _, f := range filter {
value := f.Value
switch value.(type) {
case []bool, []float64, []int64, []string, []repository.AggregateType, []repository.EventType, *[]bool, *[]float64, *[]int64, *[]string, *[]repository.AggregateType, *[]repository.EventType:
value = pq.Array(value)
case map[string]interface{}:
var err error
value, err = json.Marshal(value)
logging.Log("SQL-BSsNy").OnError(err).Warn("unable to marshal search value")
continue
}
subClauses = append(subClauses, getCondition(criteria, f))
if subClauses[len(subClauses)-1] == "" {
return "", nil
}
values = append(values, value)
}
values[i] = value
clauses[idx] = "( " + strings.Join(subClauses, " AND ") + " )"
}
return " WHERE " + strings.Join(clauses, " AND "), values
return " WHERE " + strings.Join(clauses, " OR "), values
}
func getCondition(cond querier, filter *repository.Filter) (condition string) {