mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-05 22:52:46 +00:00
refactor: eventstore v2
This commit is contained in:
parent
46a68c15bf
commit
71fd4bf9f9
@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Event is the representation of a state change
|
||||||
type Event interface {
|
type Event interface {
|
||||||
//CheckPrevious ensures the event order if true
|
//CheckPrevious ensures the event order if true
|
||||||
// if false the previous sequence is not checked on push
|
// if false the previous sequence is not checked on push
|
||||||
@ -61,7 +62,7 @@ type aggregater interface {
|
|||||||
//PreviouseSequence should return the sequence of the latest event of this aggregate
|
//PreviouseSequence should return the sequence of the latest event of this aggregate
|
||||||
// stored in the eventstore
|
// stored in the eventstore
|
||||||
// it's set to the first event of this push transaction,
|
// it's set to the first event of this push transaction,
|
||||||
// later events consume the sequence of the previously pushed event
|
// later events consume the sequence of the previously pushed event of the aggregate
|
||||||
PreviousSequence() uint64
|
PreviousSequence() uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ func (es *Eventstore) aggregatesToEvents(aggregates []aggregater) ([]*repository
|
|||||||
//FilterEvents filters the stored events based on the searchQuery
|
//FilterEvents filters the stored events based on the searchQuery
|
||||||
// and maps the events to the defined event structs
|
// and maps the events to the defined event structs
|
||||||
func (es *Eventstore) FilterEvents(ctx context.Context, queryFactory *SearchQueryFactory) ([]Event, error) {
|
func (es *Eventstore) FilterEvents(ctx context.Context, queryFactory *SearchQueryFactory) ([]Event, error) {
|
||||||
query, err := queryFactory.Build()
|
query, err := queryFactory.build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -166,7 +167,7 @@ func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQu
|
|||||||
|
|
||||||
//LatestSequence filters the latest sequence for the given search query
|
//LatestSequence filters the latest sequence for the given search query
|
||||||
func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryFactory) (uint64, error) {
|
func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryFactory) (uint64, error) {
|
||||||
query, err := queryFactory.Build()
|
query, err := queryFactory.build()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package repository
|
package repository
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -60,8 +59,6 @@ type Event struct {
|
|||||||
// an aggregate can only be managed by one organisation
|
// an aggregate can only be managed by one organisation
|
||||||
// use the ID of the org
|
// use the ID of the org
|
||||||
ResourceOwner string
|
ResourceOwner string
|
||||||
|
|
||||||
stmt *sql.Stmt
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//EventType is the description of the change
|
//EventType is the description of the change
|
||||||
|
@ -4,7 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Repository pushes and filters events
|
||||||
type Repository interface {
|
type Repository interface {
|
||||||
|
//Health checks if the connection to the storage is available
|
||||||
Health(ctx context.Context) error
|
Health(ctx context.Context) error
|
||||||
// PushEvents adds all events of the given aggregates to the eventstreams of the aggregates.
|
// PushEvents adds all events of the given aggregates to the eventstreams of the aggregates.
|
||||||
// This call is transaction save. The transaction will be rolled back if one event fails
|
// This call is transaction save. The transaction will be rolled back if one event fails
|
||||||
|
@ -2,6 +2,7 @@ package repository
|
|||||||
|
|
||||||
import "github.com/caos/zitadel/internal/errors"
|
import "github.com/caos/zitadel/internal/errors"
|
||||||
|
|
||||||
|
//SearchQuery defines the which and how data are queried
|
||||||
type SearchQuery struct {
|
type SearchQuery struct {
|
||||||
Columns Columns
|
Columns Columns
|
||||||
Limit uint64
|
Limit uint64
|
||||||
@ -9,40 +10,68 @@ type SearchQuery struct {
|
|||||||
Filters []*Filter
|
Filters []*Filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Columns defines which fields of the event are needed for the query
|
||||||
type Columns int32
|
type Columns int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Columns_Event = iota
|
//ColumnsEvent represents all fields of an event
|
||||||
Columns_Max_Sequence
|
ColumnsEvent = iota + 1
|
||||||
//insert new columns-types above this ColumnsCount because count is needed for validation
|
//ColumnsMaxSequence represents the latest sequence of the filtered events
|
||||||
ColumnsCount
|
ColumnsMaxSequence
|
||||||
|
|
||||||
|
columnsCount
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (c Columns) Validate() error {
|
||||||
|
if c <= 0 || c >= columnsCount {
|
||||||
|
return errors.ThrowPreconditionFailed(nil, "REPOS-x8R35", "column out of range")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//Filter represents all fields needed to compare a field of an event with a value
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
Field Field
|
Field Field
|
||||||
Value interface{}
|
Value interface{}
|
||||||
Operation Operation
|
Operation Operation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Operation defines how fields are compared
|
||||||
type Operation int32
|
type Operation int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Operation_Equals Operation = 1 + iota
|
// OperationEquals compares two values for equality
|
||||||
Operation_Greater
|
OperationEquals Operation = iota + 1
|
||||||
Operation_Less
|
// OperationGreater compares if the given values is greater than the stored one
|
||||||
Operation_In
|
OperationGreater
|
||||||
|
// OperationLess compares if the given values is less than the stored one
|
||||||
|
OperationLess
|
||||||
|
//OperationIn checks if a stored value matches one of the passed value list
|
||||||
|
OperationIn
|
||||||
|
|
||||||
|
operationCount
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//Field is the representation of a field from the event
|
||||||
type Field int32
|
type Field int32
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Field_AggregateType Field = 1 + iota
|
//FieldAggregateType represents the aggregate type field
|
||||||
Field_AggregateID
|
FieldAggregateType Field = iota + 1
|
||||||
Field_LatestSequence
|
//FieldAggregateID represents the aggregate id field
|
||||||
Field_ResourceOwner
|
FieldAggregateID
|
||||||
Field_EditorService
|
//FieldSequence represents the sequence field
|
||||||
Field_EditorUser
|
FieldSequence
|
||||||
Field_EventType
|
//FieldResourceOwner represents the resource owner field
|
||||||
|
FieldResourceOwner
|
||||||
|
//FieldEditorService represents the editor service field
|
||||||
|
FieldEditorService
|
||||||
|
//FieldEditorUser represents the editor user field
|
||||||
|
FieldEditorUser
|
||||||
|
//FieldEventType represents the event type field
|
||||||
|
FieldEventType
|
||||||
|
|
||||||
|
fieldCount
|
||||||
)
|
)
|
||||||
|
|
||||||
//NewFilter is used in tests. Use searchQuery.*Filter() instead
|
//NewFilter is used in tests. Use searchQuery.*Filter() instead
|
||||||
@ -54,27 +83,18 @@ func NewFilter(field Field, value interface{}, operation Operation) *Filter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func (f *Filter) Field() Field {
|
//Validate checks if the fields of the filter have valid values
|
||||||
// return f.field
|
|
||||||
// }
|
|
||||||
// func (f *Filter) Operation() Operation {
|
|
||||||
// return f.operation
|
|
||||||
// }
|
|
||||||
// func (f *Filter) Value() interface{} {
|
|
||||||
// return f.value
|
|
||||||
// }
|
|
||||||
|
|
||||||
func (f *Filter) Validate() error {
|
func (f *Filter) Validate() error {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return errors.ThrowPreconditionFailed(nil, "REPO-z6KcG", "filter is nil")
|
return errors.ThrowPreconditionFailed(nil, "REPO-z6KcG", "filter is nil")
|
||||||
}
|
}
|
||||||
if f.Field <= 0 {
|
if f.Field <= 0 || f.Field >= fieldCount {
|
||||||
return errors.ThrowPreconditionFailed(nil, "REPO-zw62U", "field not definded")
|
return errors.ThrowPreconditionFailed(nil, "REPO-zw62U", "field not definded")
|
||||||
}
|
}
|
||||||
if f.Value == nil {
|
if f.Value == nil {
|
||||||
return errors.ThrowPreconditionFailed(nil, "REPO-GJ9ct", "no value definded")
|
return errors.ThrowPreconditionFailed(nil, "REPO-GJ9ct", "no value definded")
|
||||||
}
|
}
|
||||||
if f.Operation <= 0 {
|
if f.Operation <= 0 || f.Operation >= operationCount {
|
||||||
return errors.ThrowPreconditionFailed(nil, "REPO-RrQTy", "operation not definded")
|
return errors.ThrowPreconditionFailed(nil, "REPO-RrQTy", "operation not definded")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -19,11 +19,11 @@ func TestNewFilter(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "aggregateID equals",
|
name: "aggregateID equals",
|
||||||
args: args{
|
args: args{
|
||||||
field: Field_AggregateID,
|
field: FieldAggregateID,
|
||||||
value: "hodor",
|
value: "hodor",
|
||||||
operation: Operation_Equals,
|
operation: OperationEquals,
|
||||||
},
|
},
|
||||||
want: &Filter{Field: Field_AggregateID, Operation: Operation_Equals, Value: "hodor"},
|
want: &Filter{Field: FieldAggregateID, Operation: OperationEquals, Value: "hodor"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -50,8 +50,8 @@ func TestFilter_Validate(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "correct filter",
|
name: "correct filter",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
field: Field_LatestSequence,
|
field: FieldSequence,
|
||||||
operation: Operation_Greater,
|
operation: OperationGreater,
|
||||||
value: uint64(235),
|
value: uint64(235),
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
@ -64,7 +64,7 @@ func TestFilter_Validate(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no field error",
|
name: "no field error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
operation: Operation_Greater,
|
operation: OperationGreater,
|
||||||
value: uint64(235),
|
value: uint64(235),
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
@ -72,15 +72,15 @@ func TestFilter_Validate(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no value error",
|
name: "no value error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
field: Field_LatestSequence,
|
field: FieldSequence,
|
||||||
operation: Operation_Greater,
|
operation: OperationGreater,
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no operation error",
|
name: "no operation error",
|
||||||
fields: fields{
|
fields: fields{
|
||||||
field: Field_LatestSequence,
|
field: FieldSequence,
|
||||||
value: uint64(235),
|
value: uint64(235),
|
||||||
},
|
},
|
||||||
wantErr: true,
|
wantErr: true,
|
||||||
@ -102,3 +102,43 @@ func TestFilter_Validate(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestColumns_Validate(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
columns Columns
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "correct filter",
|
||||||
|
fields: fields{
|
||||||
|
columns: ColumnsEvent,
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "columns too low",
|
||||||
|
fields: fields{
|
||||||
|
columns: 0,
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "columns too high",
|
||||||
|
fields: fields{
|
||||||
|
columns: columnsCount,
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if err := tt.fields.columns.Validate(); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Columns.Validate() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -222,19 +222,19 @@ func (db *CRDB) maxSequenceQuery() string {
|
|||||||
|
|
||||||
func (db *CRDB) columnName(col repository.Field) string {
|
func (db *CRDB) columnName(col repository.Field) string {
|
||||||
switch col {
|
switch col {
|
||||||
case repository.Field_AggregateID:
|
case repository.FieldAggregateID:
|
||||||
return "aggregate_id"
|
return "aggregate_id"
|
||||||
case repository.Field_AggregateType:
|
case repository.FieldAggregateType:
|
||||||
return "aggregate_type"
|
return "aggregate_type"
|
||||||
case repository.Field_LatestSequence:
|
case repository.FieldSequence:
|
||||||
return "event_sequence"
|
return "event_sequence"
|
||||||
case repository.Field_ResourceOwner:
|
case repository.FieldResourceOwner:
|
||||||
return "resource_owner"
|
return "resource_owner"
|
||||||
case repository.Field_EditorService:
|
case repository.FieldEditorService:
|
||||||
return "editor_service"
|
return "editor_service"
|
||||||
case repository.Field_EditorUser:
|
case repository.FieldEditorUser:
|
||||||
return "editor_user"
|
return "editor_user"
|
||||||
case repository.Field_EventType:
|
case repository.FieldEventType:
|
||||||
return "event_type"
|
return "event_type"
|
||||||
default:
|
default:
|
||||||
return ""
|
return ""
|
||||||
@ -242,7 +242,7 @@ func (db *CRDB) columnName(col repository.Field) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (db *CRDB) conditionFormat(operation repository.Operation) string {
|
func (db *CRDB) conditionFormat(operation repository.Operation) string {
|
||||||
if operation == repository.Operation_In {
|
if operation == repository.OperationIn {
|
||||||
return "%s %s ANY(?)"
|
return "%s %s ANY(?)"
|
||||||
}
|
}
|
||||||
return "%s %s ?"
|
return "%s %s ?"
|
||||||
@ -250,11 +250,11 @@ func (db *CRDB) conditionFormat(operation repository.Operation) string {
|
|||||||
|
|
||||||
func (db *CRDB) operation(operation repository.Operation) string {
|
func (db *CRDB) operation(operation repository.Operation) string {
|
||||||
switch operation {
|
switch operation {
|
||||||
case repository.Operation_Equals, repository.Operation_In:
|
case repository.OperationEquals, repository.OperationIn:
|
||||||
return "="
|
return "="
|
||||||
case repository.Operation_Greater:
|
case repository.OperationGreater:
|
||||||
return ">"
|
return ">"
|
||||||
case repository.Operation_Less:
|
case repository.OperationLess:
|
||||||
return "<"
|
return "<"
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
|
@ -81,7 +81,7 @@ func TestCRDB_operation(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "greater",
|
name: "greater",
|
||||||
args: args{
|
args: args{
|
||||||
operation: repository.Operation_Greater,
|
operation: repository.OperationGreater,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
op: ">",
|
op: ">",
|
||||||
@ -90,7 +90,7 @@ func TestCRDB_operation(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "less",
|
name: "less",
|
||||||
args: args{
|
args: args{
|
||||||
operation: repository.Operation_Less,
|
operation: repository.OperationLess,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
op: "<",
|
op: "<",
|
||||||
@ -99,7 +99,7 @@ func TestCRDB_operation(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "equals",
|
name: "equals",
|
||||||
args: args{
|
args: args{
|
||||||
operation: repository.Operation_Equals,
|
operation: repository.OperationEquals,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
op: "=",
|
op: "=",
|
||||||
@ -108,7 +108,7 @@ func TestCRDB_operation(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "in",
|
name: "in",
|
||||||
args: args{
|
args: args{
|
||||||
operation: repository.Operation_In,
|
operation: repository.OperationIn,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
op: "=",
|
op: "=",
|
||||||
@ -140,7 +140,7 @@ func TestCRDB_conditionFormat(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "default",
|
name: "default",
|
||||||
args: args{
|
args: args{
|
||||||
operation: repository.Operation_Equals,
|
operation: repository.OperationEquals,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
format: "%s %s ?",
|
format: "%s %s ?",
|
||||||
@ -149,7 +149,7 @@ func TestCRDB_conditionFormat(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "in",
|
name: "in",
|
||||||
args: args{
|
args: args{
|
||||||
operation: repository.Operation_In,
|
operation: repository.OperationIn,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
format: "%s %s ANY(?)",
|
format: "%s %s ANY(?)",
|
||||||
@ -190,7 +190,7 @@ func TestCRDB_columnName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "aggregate id",
|
name: "aggregate id",
|
||||||
args: args{
|
args: args{
|
||||||
field: repository.Field_AggregateID,
|
field: repository.FieldAggregateID,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
name: "aggregate_id",
|
name: "aggregate_id",
|
||||||
@ -199,7 +199,7 @@ func TestCRDB_columnName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "aggregate type",
|
name: "aggregate type",
|
||||||
args: args{
|
args: args{
|
||||||
field: repository.Field_AggregateType,
|
field: repository.FieldAggregateType,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
name: "aggregate_type",
|
name: "aggregate_type",
|
||||||
@ -208,7 +208,7 @@ func TestCRDB_columnName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "editor service",
|
name: "editor service",
|
||||||
args: args{
|
args: args{
|
||||||
field: repository.Field_EditorService,
|
field: repository.FieldEditorService,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
name: "editor_service",
|
name: "editor_service",
|
||||||
@ -217,7 +217,7 @@ func TestCRDB_columnName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "editor user",
|
name: "editor user",
|
||||||
args: args{
|
args: args{
|
||||||
field: repository.Field_EditorUser,
|
field: repository.FieldEditorUser,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
name: "editor_user",
|
name: "editor_user",
|
||||||
@ -226,7 +226,7 @@ func TestCRDB_columnName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "event type",
|
name: "event type",
|
||||||
args: args{
|
args: args{
|
||||||
field: repository.Field_EventType,
|
field: repository.FieldEventType,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
name: "event_type",
|
name: "event_type",
|
||||||
@ -235,7 +235,7 @@ func TestCRDB_columnName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "latest sequence",
|
name: "latest sequence",
|
||||||
args: args{
|
args: args{
|
||||||
field: repository.Field_LatestSequence,
|
field: repository.FieldSequence,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
name: "event_sequence",
|
name: "event_sequence",
|
||||||
@ -244,7 +244,7 @@ func TestCRDB_columnName(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "resource owner",
|
name: "resource owner",
|
||||||
args: args{
|
args: args{
|
||||||
field: repository.Field_ResourceOwner,
|
field: repository.FieldResourceOwner,
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
name: "resource_owner",
|
name: "resource_owner",
|
||||||
|
@ -169,11 +169,11 @@ func TestInsert(t *testing.T) {
|
|||||||
}
|
}
|
||||||
fmt.Println("====================")
|
fmt.Println("====================")
|
||||||
filtededEvents, err := crdb.Filter(context.Background(), &repository.SearchQuery{
|
filtededEvents, err := crdb.Filter(context.Background(), &repository.SearchQuery{
|
||||||
Columns: repository.Columns_Event,
|
Columns: repository.ColumnsEvent,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
{
|
{
|
||||||
Field: repository.Field_AggregateType,
|
Field: repository.FieldAggregateType,
|
||||||
Operation: repository.Operation_Equals,
|
Operation: repository.OperationEquals,
|
||||||
Value: repository.AggregateType("agg.type"),
|
Value: repository.AggregateType("agg.type"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/lib/pq"
|
"github.com/lib/pq"
|
||||||
)
|
)
|
||||||
|
|
||||||
type criteriaer interface {
|
type querier interface {
|
||||||
columnName(repository.Field) string
|
columnName(repository.Field) string
|
||||||
operation(repository.Operation) string
|
operation(repository.Operation) string
|
||||||
conditionFormat(repository.Operation) string
|
conditionFormat(repository.Operation) string
|
||||||
@ -24,7 +24,7 @@ type criteriaer interface {
|
|||||||
type rowScan func(scan, interface{}) error
|
type rowScan func(scan, interface{}) error
|
||||||
type scan func(dest ...interface{}) error
|
type scan func(dest ...interface{}) error
|
||||||
|
|
||||||
func buildQuery(criteria criteriaer, searchQuery *repository.SearchQuery) (query string, values []interface{}, rowScanner rowScan) {
|
func buildQuery(criteria querier, searchQuery *repository.SearchQuery) (query string, values []interface{}, rowScanner rowScan) {
|
||||||
query, rowScanner = prepareColumns(criteria, searchQuery.Columns)
|
query, rowScanner = prepareColumns(criteria, searchQuery.Columns)
|
||||||
where, values := prepareCondition(criteria, searchQuery.Filters)
|
where, values := prepareCondition(criteria, searchQuery.Filters)
|
||||||
if where == "" || query == "" {
|
if where == "" || query == "" {
|
||||||
@ -32,7 +32,7 @@ func buildQuery(criteria criteriaer, searchQuery *repository.SearchQuery) (query
|
|||||||
}
|
}
|
||||||
query += where
|
query += where
|
||||||
|
|
||||||
if searchQuery.Columns != repository.Columns_Max_Sequence {
|
if searchQuery.Columns != repository.ColumnsMaxSequence {
|
||||||
query += " ORDER BY event_sequence"
|
query += " ORDER BY event_sequence"
|
||||||
if searchQuery.Desc {
|
if searchQuery.Desc {
|
||||||
query += " DESC"
|
query += " DESC"
|
||||||
@ -49,11 +49,11 @@ func buildQuery(criteria criteriaer, searchQuery *repository.SearchQuery) (query
|
|||||||
return query, values, rowScanner
|
return query, values, rowScanner
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareColumns(criteria criteriaer, columns repository.Columns) (string, func(s scan, dest interface{}) error) {
|
func prepareColumns(criteria querier, columns repository.Columns) (string, func(s scan, dest interface{}) error) {
|
||||||
switch columns {
|
switch columns {
|
||||||
case repository.Columns_Max_Sequence:
|
case repository.ColumnsMaxSequence:
|
||||||
return criteria.maxSequenceQuery(), maxSequenceScanner
|
return criteria.maxSequenceQuery(), maxSequenceScanner
|
||||||
case repository.Columns_Event:
|
case repository.ColumnsEvent:
|
||||||
return criteria.eventQuery(), eventsScanner
|
return criteria.eventQuery(), eventsScanner
|
||||||
default:
|
default:
|
||||||
return "", nil
|
return "", nil
|
||||||
@ -110,7 +110,7 @@ func eventsScanner(scanner scan, dest interface{}) (err error) {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareCondition(criteria criteriaer, filters []*repository.Filter) (clause string, values []interface{}) {
|
func prepareCondition(criteria querier, filters []*repository.Filter) (clause string, values []interface{}) {
|
||||||
values = make([]interface{}, len(filters))
|
values = make([]interface{}, len(filters))
|
||||||
clauses := make([]string, len(filters))
|
clauses := make([]string, len(filters))
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ func prepareCondition(criteria criteriaer, filters []*repository.Filter) (clause
|
|||||||
return " WHERE " + strings.Join(clauses, " AND "), values
|
return " WHERE " + strings.Join(clauses, " AND "), values
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCondition(cond criteriaer, filter *repository.Filter) (condition string) {
|
func getCondition(cond querier, filter *repository.Filter) (condition string) {
|
||||||
field := cond.columnName(filter.Field)
|
field := cond.columnName(filter.Field)
|
||||||
operation := cond.operation(filter.Operation)
|
operation := cond.operation(filter.Operation)
|
||||||
if field == "" || operation == "" {
|
if field == "" || operation == "" {
|
||||||
|
@ -22,32 +22,32 @@ func Test_getCondition(t *testing.T) {
|
|||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "equals",
|
name: "equals",
|
||||||
args: args{filter: repository.NewFilter(repository.Field_AggregateID, "", repository.Operation_Equals)},
|
args: args{filter: repository.NewFilter(repository.FieldAggregateID, "", repository.OperationEquals)},
|
||||||
want: "aggregate_id = ?",
|
want: "aggregate_id = ?",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "greater",
|
name: "greater",
|
||||||
args: args{filter: repository.NewFilter(repository.Field_LatestSequence, 0, repository.Operation_Greater)},
|
args: args{filter: repository.NewFilter(repository.FieldSequence, 0, repository.OperationGreater)},
|
||||||
want: "event_sequence > ?",
|
want: "event_sequence > ?",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "less",
|
name: "less",
|
||||||
args: args{filter: repository.NewFilter(repository.Field_LatestSequence, 5000, repository.Operation_Less)},
|
args: args{filter: repository.NewFilter(repository.FieldSequence, 5000, repository.OperationLess)},
|
||||||
want: "event_sequence < ?",
|
want: "event_sequence < ?",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "in list",
|
name: "in list",
|
||||||
args: args{filter: repository.NewFilter(repository.Field_AggregateType, []repository.AggregateType{"movies", "actors"}, repository.Operation_In)},
|
args: args{filter: repository.NewFilter(repository.FieldAggregateType, []repository.AggregateType{"movies", "actors"}, repository.OperationIn)},
|
||||||
want: "aggregate_type = ANY(?)",
|
want: "aggregate_type = ANY(?)",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid operation",
|
name: "invalid operation",
|
||||||
args: args{filter: repository.NewFilter(repository.Field_AggregateType, []repository.AggregateType{"movies", "actors"}, repository.Operation(-1))},
|
args: args{filter: repository.NewFilter(repository.FieldAggregateType, []repository.AggregateType{"movies", "actors"}, repository.Operation(-1))},
|
||||||
want: "",
|
want: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid field",
|
name: "invalid field",
|
||||||
args: args{filter: repository.NewFilter(repository.Field(-1), []repository.AggregateType{"movies", "actors"}, repository.Operation_Equals)},
|
args: args{filter: repository.NewFilter(repository.Field(-1), []repository.AggregateType{"movies", "actors"}, repository.OperationEquals)},
|
||||||
want: "",
|
want: "",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -97,7 +97,7 @@ func Test_prepareColumns(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "max column",
|
name: "max column",
|
||||||
args: args{
|
args: args{
|
||||||
columns: repository.Columns_Max_Sequence,
|
columns: repository.ColumnsMaxSequence,
|
||||||
dest: new(Sequence),
|
dest: new(Sequence),
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -111,7 +111,7 @@ func Test_prepareColumns(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "max sequence wrong dest type",
|
name: "max sequence wrong dest type",
|
||||||
args: args{
|
args: args{
|
||||||
columns: repository.Columns_Max_Sequence,
|
columns: repository.ColumnsMaxSequence,
|
||||||
dest: new(uint64),
|
dest: new(uint64),
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -122,7 +122,7 @@ func Test_prepareColumns(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "events",
|
name: "events",
|
||||||
args: args{
|
args: args{
|
||||||
columns: repository.Columns_Event,
|
columns: repository.ColumnsEvent,
|
||||||
dest: &[]*repository.Event{},
|
dest: &[]*repository.Event{},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -138,7 +138,7 @@ func Test_prepareColumns(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "events wrong dest type",
|
name: "events wrong dest type",
|
||||||
args: args{
|
args: args{
|
||||||
columns: repository.Columns_Event,
|
columns: repository.ColumnsEvent,
|
||||||
dest: []*repository.Event{},
|
dest: []*repository.Event{},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -149,7 +149,7 @@ func Test_prepareColumns(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "event query error",
|
name: "event query error",
|
||||||
args: args{
|
args: args{
|
||||||
columns: repository.Columns_Event,
|
columns: repository.ColumnsEvent,
|
||||||
dest: &[]*repository.Event{},
|
dest: &[]*repository.Event{},
|
||||||
dbErr: sql.ErrConnDone,
|
dbErr: sql.ErrConnDone,
|
||||||
},
|
},
|
||||||
@ -240,7 +240,7 @@ func Test_prepareCondition(t *testing.T) {
|
|||||||
name: "invalid condition",
|
name: "invalid condition",
|
||||||
args: args{
|
args: args{
|
||||||
filters: []*repository.Filter{
|
filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateID, "wrong", repository.Operation(-1)),
|
repository.NewFilter(repository.FieldAggregateID, "wrong", repository.Operation(-1)),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -252,7 +252,7 @@ func Test_prepareCondition(t *testing.T) {
|
|||||||
name: "array as condition value",
|
name: "array as condition value",
|
||||||
args: args{
|
args: args{
|
||||||
filters: []*repository.Filter{
|
filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, []repository.AggregateType{"user", "org"}, repository.Operation_In),
|
repository.NewFilter(repository.FieldAggregateType, []repository.AggregateType{"user", "org"}, repository.OperationIn),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -264,9 +264,9 @@ func Test_prepareCondition(t *testing.T) {
|
|||||||
name: "multiple filters",
|
name: "multiple filters",
|
||||||
args: args{
|
args: args{
|
||||||
filters: []*repository.Filter{
|
filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, []repository.AggregateType{"user", "org"}, repository.Operation_In),
|
repository.NewFilter(repository.FieldAggregateType, []repository.AggregateType{"user", "org"}, repository.OperationIn),
|
||||||
repository.NewFilter(repository.Field_AggregateID, "1234", repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateID, "1234", repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_EventType, []repository.EventType{"user.created", "org.created"}, repository.Operation_In),
|
repository.NewFilter(repository.FieldEventType, []repository.EventType{"user.created", "org.created"}, repository.OperationIn),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -314,13 +314,13 @@ func Test_buildQuery(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
// NewSearchQueryFactory("user").OrderDesc()
|
// NewSearchQueryFactory("user").OrderDesc()
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: repository.Columns_Event,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: true,
|
Desc: true,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
{
|
{
|
||||||
Field: repository.Field_AggregateType,
|
Field: repository.FieldAggregateType,
|
||||||
Value: repository.AggregateType("user"),
|
Value: repository.AggregateType("user"),
|
||||||
Operation: repository.Operation_Equals,
|
Operation: repository.OperationEquals,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -335,14 +335,14 @@ func Test_buildQuery(t *testing.T) {
|
|||||||
name: "with limit",
|
name: "with limit",
|
||||||
args: args{
|
args: args{
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: repository.Columns_Event,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 5,
|
Limit: 5,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
{
|
{
|
||||||
Field: repository.Field_AggregateType,
|
Field: repository.FieldAggregateType,
|
||||||
Value: repository.AggregateType("user"),
|
Value: repository.AggregateType("user"),
|
||||||
Operation: repository.Operation_Equals,
|
Operation: repository.OperationEquals,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -357,14 +357,14 @@ func Test_buildQuery(t *testing.T) {
|
|||||||
name: "with limit and order by desc",
|
name: "with limit and order by desc",
|
||||||
args: args{
|
args: args{
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: repository.Columns_Event,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: true,
|
Desc: true,
|
||||||
Limit: 5,
|
Limit: 5,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
{
|
{
|
||||||
Field: repository.Field_AggregateType,
|
Field: repository.FieldAggregateType,
|
||||||
Value: repository.AggregateType("user"),
|
Value: repository.AggregateType("user"),
|
||||||
Operation: repository.Operation_Equals,
|
Operation: repository.OperationEquals,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -392,7 +392,7 @@ func Test_buildQuery(t *testing.T) {
|
|||||||
name: "invalid condition",
|
name: "invalid condition",
|
||||||
args: args{
|
args: args{
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: repository.Columns_Event,
|
Columns: repository.ColumnsEvent,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
{},
|
{},
|
||||||
},
|
},
|
||||||
|
@ -8,8 +8,10 @@ import (
|
|||||||
|
|
||||||
var versionRegexp = regexp.MustCompile(`^v[0-9]+(\.[0-9]+){0,2}$`)
|
var versionRegexp = regexp.MustCompile(`^v[0-9]+(\.[0-9]+){0,2}$`)
|
||||||
|
|
||||||
|
//Version represents the semver of an aggregate
|
||||||
type Version string
|
type Version string
|
||||||
|
|
||||||
|
//Validate checks if the v is semver
|
||||||
func (v Version) Validate() error {
|
func (v Version) Validate() error {
|
||||||
if !versionRegexp.MatchString(string(v)) {
|
if !versionRegexp.MatchString(string(v)) {
|
||||||
return errors.ThrowPreconditionFailed(nil, "MODEL-luDuS", "version is not semver")
|
return errors.ThrowPreconditionFailed(nil, "MODEL-luDuS", "version is not semver")
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
"github.com/caos/zitadel/internal/eventstore/v2/repository"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
//SearchQueryFactory represents the builder for your filter
|
||||||
|
// if invalid data are set the filter will fail
|
||||||
type SearchQueryFactory struct {
|
type SearchQueryFactory struct {
|
||||||
columns repository.Columns
|
columns repository.Columns
|
||||||
limit uint64
|
limit uint64
|
||||||
@ -16,18 +18,27 @@ type SearchQueryFactory struct {
|
|||||||
resourceOwner string
|
resourceOwner string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Columns defines which fields of the event are needed for the query
|
||||||
type Columns repository.Columns
|
type Columns repository.Columns
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Columns_Event Columns = repository.Columns_Event
|
//ColumnsEvent represents all fields of an event
|
||||||
Columns_Max_Sequence Columns = repository.Columns_Max_Sequence
|
ColumnsEvent Columns = repository.ColumnsEvent
|
||||||
|
// ColumnsMaxSequence represents the latest sequence of the filtered events
|
||||||
|
ColumnsMaxSequence Columns = repository.ColumnsMaxSequence
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// AggregateType is the object name
|
||||||
type AggregateType repository.AggregateType
|
type AggregateType repository.AggregateType
|
||||||
|
|
||||||
|
// EventType is the description of the change
|
||||||
type EventType repository.EventType
|
type EventType repository.EventType
|
||||||
|
|
||||||
func NewSearchQueryFactory(aggregateTypes ...AggregateType) *SearchQueryFactory {
|
// NewSearchQueryFactory creates a new factory for event filters
|
||||||
|
// aggregateTypes must contain at least one aggregate type
|
||||||
|
func NewSearchQueryFactory(columns Columns, aggregateTypes ...AggregateType) *SearchQueryFactory {
|
||||||
return &SearchQueryFactory{
|
return &SearchQueryFactory{
|
||||||
|
columns: repository.Columns(columns),
|
||||||
aggregateTypes: aggregateTypes,
|
aggregateTypes: aggregateTypes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,10 +83,10 @@ func (factory *SearchQueryFactory) OrderAsc() *SearchQueryFactory {
|
|||||||
return factory
|
return factory
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory *SearchQueryFactory) Build() (*repository.SearchQuery, error) {
|
func (factory *SearchQueryFactory) build() (*repository.SearchQuery, error) {
|
||||||
if factory == nil ||
|
if factory == nil ||
|
||||||
len(factory.aggregateTypes) < 1 ||
|
len(factory.aggregateTypes) < 1 ||
|
||||||
(factory.columns < 0 || factory.columns >= repository.ColumnsCount) {
|
factory.columns.Validate() != nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "MODEL-tGAD3", "factory invalid")
|
return nil, errors.ThrowPreconditionFailed(nil, "MODEL-tGAD3", "factory invalid")
|
||||||
}
|
}
|
||||||
filters := []*repository.Filter{
|
filters := []*repository.Filter{
|
||||||
@ -89,6 +100,9 @@ func (factory *SearchQueryFactory) Build() (*repository.SearchQuery, error) {
|
|||||||
factory.resourceOwnerFilter,
|
factory.resourceOwnerFilter,
|
||||||
} {
|
} {
|
||||||
if filter := f(); filter != nil {
|
if filter := f(); filter != nil {
|
||||||
|
if err := filter.Validate(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
filters = append(filters, filter)
|
filters = append(filters, filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -106,9 +120,9 @@ func (factory *SearchQueryFactory) aggregateIDFilter() *repository.Filter {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(factory.aggregateIDs) == 1 {
|
if len(factory.aggregateIDs) == 1 {
|
||||||
return repository.NewFilter(repository.Field_AggregateID, factory.aggregateIDs[0], repository.Operation_Equals)
|
return repository.NewFilter(repository.FieldAggregateID, factory.aggregateIDs[0], repository.OperationEquals)
|
||||||
}
|
}
|
||||||
return repository.NewFilter(repository.Field_AggregateID, factory.aggregateIDs, repository.Operation_In)
|
return repository.NewFilter(repository.FieldAggregateID, factory.aggregateIDs, repository.OperationIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory *SearchQueryFactory) eventTypeFilter() *repository.Filter {
|
func (factory *SearchQueryFactory) eventTypeFilter() *repository.Filter {
|
||||||
@ -116,32 +130,32 @@ func (factory *SearchQueryFactory) eventTypeFilter() *repository.Filter {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(factory.eventTypes) == 1 {
|
if len(factory.eventTypes) == 1 {
|
||||||
return repository.NewFilter(repository.Field_EventType, factory.eventTypes[0], repository.Operation_Equals)
|
return repository.NewFilter(repository.FieldEventType, factory.eventTypes[0], repository.OperationEquals)
|
||||||
}
|
}
|
||||||
return repository.NewFilter(repository.Field_EventType, factory.eventTypes, repository.Operation_In)
|
return repository.NewFilter(repository.FieldEventType, factory.eventTypes, repository.OperationIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory *SearchQueryFactory) aggregateTypeFilter() *repository.Filter {
|
func (factory *SearchQueryFactory) aggregateTypeFilter() *repository.Filter {
|
||||||
if len(factory.aggregateTypes) == 1 {
|
if len(factory.aggregateTypes) == 1 {
|
||||||
return repository.NewFilter(repository.Field_AggregateType, factory.aggregateTypes[0], repository.Operation_Equals)
|
return repository.NewFilter(repository.FieldAggregateType, factory.aggregateTypes[0], repository.OperationEquals)
|
||||||
}
|
}
|
||||||
return repository.NewFilter(repository.Field_AggregateType, factory.aggregateTypes, repository.Operation_In)
|
return repository.NewFilter(repository.FieldAggregateType, factory.aggregateTypes, repository.OperationIn)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory *SearchQueryFactory) eventSequenceFilter() *repository.Filter {
|
func (factory *SearchQueryFactory) eventSequenceFilter() *repository.Filter {
|
||||||
if factory.eventSequence == 0 {
|
if factory.eventSequence == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
sortOrder := repository.Operation_Greater
|
sortOrder := repository.OperationGreater
|
||||||
if factory.desc {
|
if factory.desc {
|
||||||
sortOrder = repository.Operation_Less
|
sortOrder = repository.OperationLess
|
||||||
}
|
}
|
||||||
return repository.NewFilter(repository.Field_LatestSequence, factory.eventSequence, sortOrder)
|
return repository.NewFilter(repository.FieldSequence, factory.eventSequence, sortOrder)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (factory *SearchQueryFactory) resourceOwnerFilter() *repository.Filter {
|
func (factory *SearchQueryFactory) resourceOwnerFilter() *repository.Filter {
|
||||||
if factory.resourceOwner == "" {
|
if factory.resourceOwner == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return repository.NewFilter(repository.Field_ResourceOwner, factory.resourceOwner, repository.Operation_Equals)
|
return repository.NewFilter(repository.FieldResourceOwner, factory.resourceOwner, repository.OperationEquals)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package eventstore
|
package eventstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
@ -63,6 +64,7 @@ func testSetSortOrder(asc bool) func(factory *SearchQueryFactory) *SearchQueryFa
|
|||||||
|
|
||||||
func TestSearchQueryFactorySetters(t *testing.T) {
|
func TestSearchQueryFactorySetters(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
|
columns Columns
|
||||||
aggregateTypes []AggregateType
|
aggregateTypes []AggregateType
|
||||||
setters []func(*SearchQueryFactory) *SearchQueryFactory
|
setters []func(*SearchQueryFactory) *SearchQueryFactory
|
||||||
}
|
}
|
||||||
@ -74,19 +76,21 @@ func TestSearchQueryFactorySetters(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "New factory",
|
name: "New factory",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user", "org"},
|
aggregateTypes: []AggregateType{"user", "org"},
|
||||||
},
|
},
|
||||||
res: &SearchQueryFactory{
|
res: &SearchQueryFactory{
|
||||||
|
columns: repository.Columns(ColumnsEvent),
|
||||||
aggregateTypes: []AggregateType{"user", "org"},
|
aggregateTypes: []AggregateType{"user", "org"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "set columns",
|
name: "set columns",
|
||||||
args: args{
|
args: args{
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{testSetColumns(repository.Columns_Max_Sequence)},
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{testSetColumns(repository.ColumnsMaxSequence)},
|
||||||
},
|
},
|
||||||
res: &SearchQueryFactory{
|
res: &SearchQueryFactory{
|
||||||
columns: repository.Columns_Max_Sequence,
|
columns: repository.ColumnsMaxSequence,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -149,7 +153,7 @@ func TestSearchQueryFactorySetters(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
factory := NewSearchQueryFactory(tt.args.aggregateTypes...)
|
factory := NewSearchQueryFactory(tt.args.columns, tt.args.aggregateTypes...)
|
||||||
for _, setter := range tt.args.setters {
|
for _, setter := range tt.args.setters {
|
||||||
factory = setter(factory)
|
factory = setter(factory)
|
||||||
}
|
}
|
||||||
@ -162,6 +166,7 @@ func TestSearchQueryFactorySetters(t *testing.T) {
|
|||||||
|
|
||||||
func TestSearchQueryFactoryBuild(t *testing.T) {
|
func TestSearchQueryFactoryBuild(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
|
columns Columns
|
||||||
aggregateTypes []AggregateType
|
aggregateTypes []AggregateType
|
||||||
setters []func(*SearchQueryFactory) *SearchQueryFactory
|
setters []func(*SearchQueryFactory) *SearchQueryFactory
|
||||||
}
|
}
|
||||||
@ -177,6 +182,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "no aggregate types",
|
name: "no aggregate types",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{},
|
aggregateTypes: []AggregateType{},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{},
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{},
|
||||||
},
|
},
|
||||||
@ -188,6 +194,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "invalid column (too low)",
|
name: "invalid column (too low)",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetColumns(Columns(-1)),
|
testSetColumns(Columns(-1)),
|
||||||
@ -200,9 +207,10 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "invalid column (too high)",
|
name: "invalid column (too high)",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetColumns(repository.ColumnsCount),
|
testSetColumns(math.MaxInt32),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
@ -212,17 +220,18 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type",
|
name: "filter aggregate type",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{},
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 0,
|
Limit: 0,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -230,17 +239,18 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate types",
|
name: "filter aggregate types",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user", "org"},
|
aggregateTypes: []AggregateType{"user", "org"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{},
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 0,
|
Limit: 0,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, []AggregateType{"user", "org"}, repository.Operation_In),
|
repository.NewFilter(repository.FieldAggregateType, []AggregateType{"user", "org"}, repository.OperationIn),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -248,6 +258,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type, limit, desc",
|
name: "filter aggregate type, limit, desc",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetLimit(5),
|
testSetLimit(5),
|
||||||
@ -258,12 +269,12 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: true,
|
Desc: true,
|
||||||
Limit: 5,
|
Limit: 5,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_LatestSequence, uint64(100), repository.Operation_Less),
|
repository.NewFilter(repository.FieldSequence, uint64(100), repository.OperationLess),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -271,6 +282,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type, limit, asc",
|
name: "filter aggregate type, limit, asc",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetLimit(5),
|
testSetLimit(5),
|
||||||
@ -281,12 +293,12 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 5,
|
Limit: 5,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_LatestSequence, uint64(100), repository.Operation_Greater),
|
repository.NewFilter(repository.FieldSequence, uint64(100), repository.OperationGreater),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -294,23 +306,24 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type, limit, desc, max event sequence cols",
|
name: "filter aggregate type, limit, desc, max event sequence cols",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetLimit(5),
|
testSetLimit(5),
|
||||||
testSetSortOrder(false),
|
testSetSortOrder(false),
|
||||||
testSetSequence(100),
|
testSetSequence(100),
|
||||||
testSetColumns(repository.Columns_Max_Sequence),
|
testSetColumns(repository.ColumnsMaxSequence),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: repository.Columns_Max_Sequence,
|
Columns: repository.ColumnsMaxSequence,
|
||||||
Desc: true,
|
Desc: true,
|
||||||
Limit: 5,
|
Limit: 5,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_LatestSequence, uint64(100), repository.Operation_Less),
|
repository.NewFilter(repository.FieldSequence, uint64(100), repository.OperationLess),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -318,6 +331,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type and aggregate id",
|
name: "filter aggregate type and aggregate id",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetAggregateIDs("1234"),
|
testSetAggregateIDs("1234"),
|
||||||
@ -326,12 +340,12 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 0,
|
Limit: 0,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_AggregateID, "1234", repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateID, "1234", repository.OperationEquals),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -339,6 +353,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type and aggregate ids",
|
name: "filter aggregate type and aggregate ids",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetAggregateIDs("1234", "0815"),
|
testSetAggregateIDs("1234", "0815"),
|
||||||
@ -347,12 +362,12 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 0,
|
Limit: 0,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_AggregateID, []string{"1234", "0815"}, repository.Operation_In),
|
repository.NewFilter(repository.FieldAggregateID, []string{"1234", "0815"}, repository.OperationIn),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -360,6 +375,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type and sequence greater",
|
name: "filter aggregate type and sequence greater",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetSequence(8),
|
testSetSequence(8),
|
||||||
@ -368,12 +384,12 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 0,
|
Limit: 0,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_LatestSequence, uint64(8), repository.Operation_Greater),
|
repository.NewFilter(repository.FieldSequence, uint64(8), repository.OperationGreater),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -381,6 +397,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type and event type",
|
name: "filter aggregate type and event type",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetEventTypes("user.created"),
|
testSetEventTypes("user.created"),
|
||||||
@ -389,12 +406,12 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 0,
|
Limit: 0,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_EventType, EventType("user.created"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldEventType, EventType("user.created"), repository.OperationEquals),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -402,6 +419,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type and event types",
|
name: "filter aggregate type and event types",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetEventTypes("user.created", "user.changed"),
|
testSetEventTypes("user.created", "user.changed"),
|
||||||
@ -410,12 +428,12 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 0,
|
Limit: 0,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_EventType, []EventType{"user.created", "user.changed"}, repository.Operation_In),
|
repository.NewFilter(repository.FieldEventType, []EventType{"user.created", "user.changed"}, repository.OperationIn),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -423,6 +441,7 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "filter aggregate type resource owner",
|
name: "filter aggregate type resource owner",
|
||||||
args: args{
|
args: args{
|
||||||
|
columns: ColumnsEvent,
|
||||||
aggregateTypes: []AggregateType{"user"},
|
aggregateTypes: []AggregateType{"user"},
|
||||||
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
setters: []func(*SearchQueryFactory) *SearchQueryFactory{
|
||||||
testSetResourceOwner("hodor"),
|
testSetResourceOwner("hodor"),
|
||||||
@ -431,12 +450,12 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
res: res{
|
res: res{
|
||||||
isErr: nil,
|
isErr: nil,
|
||||||
query: &repository.SearchQuery{
|
query: &repository.SearchQuery{
|
||||||
Columns: 0,
|
Columns: repository.ColumnsEvent,
|
||||||
Desc: false,
|
Desc: false,
|
||||||
Limit: 0,
|
Limit: 0,
|
||||||
Filters: []*repository.Filter{
|
Filters: []*repository.Filter{
|
||||||
repository.NewFilter(repository.Field_AggregateType, AggregateType("user"), repository.Operation_Equals),
|
repository.NewFilter(repository.FieldAggregateType, AggregateType("user"), repository.OperationEquals),
|
||||||
repository.NewFilter(repository.Field_ResourceOwner, "hodor", repository.Operation_Equals),
|
repository.NewFilter(repository.FieldResourceOwner, "hodor", repository.OperationEquals),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -444,11 +463,11 @@ func TestSearchQueryFactoryBuild(t *testing.T) {
|
|||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
factory := NewSearchQueryFactory(tt.args.aggregateTypes...)
|
factory := NewSearchQueryFactory(tt.args.columns, tt.args.aggregateTypes...)
|
||||||
for _, f := range tt.args.setters {
|
for _, f := range tt.args.setters {
|
||||||
factory = f(factory)
|
factory = f(factory)
|
||||||
}
|
}
|
||||||
query, err := factory.Build()
|
query, err := factory.build()
|
||||||
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
if tt.res.isErr != nil && !tt.res.isErr(err) {
|
||||||
t.Errorf("wrong error: %v", err)
|
t.Errorf("wrong error: %v", err)
|
||||||
return
|
return
|
||||||
|
Loading…
x
Reference in New Issue
Block a user