From 25450554b4d4e9bc0d20142f7c793b0785ea467e Mon Sep 17 00:00:00 2001 From: Dominik Schmidt Date: Wed, 29 Jul 2026 17:39:23 +0200 Subject: [PATCH] refactor(kql): move parse/validation errors into pkg/kql The KQL parser produced its own validation errors but imported them from the search service's query package. Move them into pkg/kql and let the search backend consume kql.IsValidationError, so the parser stops depending on a service package. --- pkg/kql/cast.go | 5 ++--- pkg/kql/dictionary_test.go | 21 +++++++++---------- .../search/pkg/query => pkg/kql}/error.go | 4 +++- pkg/kql/kql_test.go | 3 +-- pkg/kql/validate.go | 7 +++---- services/search/pkg/bleve/backend.go | 3 ++- 6 files changed, 21 insertions(+), 22 deletions(-) rename {services/search/pkg/query => pkg/kql}/error.go (90%) diff --git a/pkg/kql/cast.go b/pkg/kql/cast.go index c1fb185623..29832d3725 100644 --- a/pkg/kql/cast.go +++ b/pkg/kql/cast.go @@ -6,7 +6,6 @@ import ( "github.com/jinzhu/now" "github.com/opencloud-eu/opencloud/pkg/ast" - "github.com/opencloud-eu/opencloud/services/search/pkg/query" ) func toNode[T ast.Node](in any) (T, error) { @@ -84,7 +83,7 @@ func toTimeRange(in any) (*time.Time, *time.Time, error) { value, err := toString(in) if err != nil { - return &from, &to, &query.UnsupportedTimeRangeError{} + return &from, &to, &UnsupportedTimeRangeError{} } c := &now.Config{ @@ -131,7 +130,7 @@ func toTimeRange(in any) (*time.Time, *time.Time, error) { } if from.IsZero() || to.IsZero() { - return nil, nil, &query.UnsupportedTimeRangeError{} + return nil, nil, &UnsupportedTimeRangeError{} } return &from, &to, nil diff --git a/pkg/kql/dictionary_test.go b/pkg/kql/dictionary_test.go index 81ace7b811..c9ee0692df 100644 --- a/pkg/kql/dictionary_test.go +++ b/pkg/kql/dictionary_test.go @@ -9,7 +9,6 @@ import ( "github.com/opencloud-eu/opencloud/pkg/ast" "github.com/opencloud-eu/opencloud/pkg/ast/test" "github.com/opencloud-eu/opencloud/pkg/kql" - "github.com/opencloud-eu/opencloud/services/search/pkg/query" tAssert "github.com/stretchr/testify/assert" ) @@ -34,13 +33,13 @@ func TestParse_Spec(t *testing.T) { }, { name: `AND`, - error: query.StartsWithBinaryOperatorError{ + error: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolAND}, }, }, { name: `AND cat AND dog`, - error: query.StartsWithBinaryOperatorError{ + error: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolAND}, }, }, @@ -80,13 +79,13 @@ func TestParse_Spec(t *testing.T) { }, { name: `OR`, - error: query.StartsWithBinaryOperatorError{ + error: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolOR}, }, }, { name: `OR cat AND dog`, - error: query.StartsWithBinaryOperatorError{ + error: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolOR}, }, }, @@ -860,37 +859,37 @@ func TestParse_Errors(t *testing.T) { tests := []testCase{ { query: "animal:(mammal:cat mammal:dog reptile:turtle)", - error: query.NamedGroupInvalidNodesError{ + error: kql.NamedGroupInvalidNodesError{ Node: &ast.StringNode{Key: "mammal", Value: "cat"}, }, }, { query: "animal:(cat mammal:dog turtle)", - error: query.NamedGroupInvalidNodesError{ + error: kql.NamedGroupInvalidNodesError{ Node: &ast.StringNode{Key: "mammal", Value: "dog"}, }, }, { query: "animal:(AND cat)", - error: query.StartsWithBinaryOperatorError{ + error: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolAND}, }, }, { query: "animal:(OR cat)", - error: query.StartsWithBinaryOperatorError{ + error: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolOR}, }, }, { query: "(AND cat)", - error: query.StartsWithBinaryOperatorError{ + error: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolAND}, }, }, { query: "(OR cat)", - error: query.StartsWithBinaryOperatorError{ + error: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolOR}, }, }, diff --git a/services/search/pkg/query/error.go b/pkg/kql/error.go similarity index 90% rename from services/search/pkg/query/error.go rename to pkg/kql/error.go index a25148d977..be94e2d34a 100644 --- a/services/search/pkg/query/error.go +++ b/pkg/kql/error.go @@ -1,4 +1,4 @@ -package query +package kql import ( "fmt" @@ -38,6 +38,8 @@ func (e UnsupportedTimeRangeError) Error() string { return fmt.Sprintf("unable to convert '%v' to a time range", e.Value) } +// IsValidationError reports whether err is one of the KQL parse/validation +// errors produced by this package. func IsValidationError(err error) bool { switch err.(type) { case *StartsWithBinaryOperatorError, *NamedGroupInvalidNodesError, *UnsupportedTimeRangeError: diff --git a/pkg/kql/kql_test.go b/pkg/kql/kql_test.go index d3b745ca3f..d90245ccf3 100644 --- a/pkg/kql/kql_test.go +++ b/pkg/kql/kql_test.go @@ -5,7 +5,6 @@ import ( "github.com/opencloud-eu/opencloud/pkg/ast" "github.com/opencloud-eu/opencloud/pkg/kql" - "github.com/opencloud-eu/opencloud/services/search/pkg/query" tAssert "github.com/stretchr/testify/assert" ) @@ -22,7 +21,7 @@ func TestNewAST(t *testing.T) { { name: "error", givenQuery: kql.BoolAND, - expectedError: query.StartsWithBinaryOperatorError{ + expectedError: kql.StartsWithBinaryOperatorError{ Node: &ast.OperatorNode{Value: kql.BoolAND}, }, }, diff --git a/pkg/kql/validate.go b/pkg/kql/validate.go index 56bf681887..1f7e38ccba 100644 --- a/pkg/kql/validate.go +++ b/pkg/kql/validate.go @@ -2,7 +2,6 @@ package kql import ( "github.com/opencloud-eu/opencloud/pkg/ast" - "github.com/opencloud-eu/opencloud/services/search/pkg/query" ) func validateAst(a *ast.Ast) error { @@ -10,7 +9,7 @@ func validateAst(a *ast.Ast) error { case *ast.OperatorNode: switch node.Value { case BoolAND, BoolOR: - return &query.StartsWithBinaryOperatorError{Node: node} + return &StartsWithBinaryOperatorError{Node: node} } } return nil @@ -21,14 +20,14 @@ func validateGroupNode(n *ast.GroupNode) error { case *ast.OperatorNode: switch node.Value { case BoolAND, BoolOR: - return &query.StartsWithBinaryOperatorError{Node: node} + return &StartsWithBinaryOperatorError{Node: node} } } if n.Key != "" { for _, node := range n.Nodes { if ast.NodeKey(node) != "" { - return &query.NamedGroupInvalidNodesError{Node: node} + return &NamedGroupInvalidNodesError{Node: node} } } } diff --git a/services/search/pkg/bleve/backend.go b/services/search/pkg/bleve/backend.go index 673e61de2c..b4088918fe 100644 --- a/services/search/pkg/bleve/backend.go +++ b/services/search/pkg/bleve/backend.go @@ -14,6 +14,7 @@ import ( "github.com/opencloud-eu/reva/v2/pkg/utils" "google.golang.org/protobuf/types/known/timestamppb" + "github.com/opencloud-eu/opencloud/pkg/kql" "github.com/opencloud-eu/opencloud/pkg/log" "github.com/opencloud-eu/opencloud/services/search/pkg/search" @@ -45,7 +46,7 @@ func NewBackend(index bleve.Index, queryCreator searchQuery.Creator[query.Query] func (b *Backend) Search(_ context.Context, sir *searchService.SearchIndexRequest) (*searchService.SearchIndexResponse, error) { createdQuery, err := b.queryCreator.Create(sir.Query) if err != nil { - if searchQuery.IsValidationError(err) { + if kql.IsValidationError(err) { return nil, errtypes.BadRequest(err.Error()) } return nil, err