mirror of
https://github.com/rancher/steve.git
synced 2025-08-06 17:03:28 +00:00
Move types related to list options and sql queries into their own package.
The problem having these in the informer package is that eventually code in other packages will need to import `informer` only for constants or types, but some members of the informer package may already depend on those. Best to move type definitions into their own simpler package.
This commit is contained in:
parent
392a95f753
commit
35ba548a7a
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"github.com/rancher/steve/pkg/sqlcache/db"
|
"github.com/rancher/steve/pkg/sqlcache/db"
|
||||||
"github.com/rancher/steve/pkg/sqlcache/partition"
|
"github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
"github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
sqlStore "github.com/rancher/steve/pkg/sqlcache/store"
|
sqlStore "github.com/rancher/steve/pkg/sqlcache/store"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
@ -29,7 +30,7 @@ type Informer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ByOptionsLister interface {
|
type ByOptionsLister interface {
|
||||||
ListByOptions(ctx context.Context, lo ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error)
|
ListByOptions(ctx context.Context, lo sqltypes.ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is set to a var so that it can be overridden by test code for mocking purposes
|
// this is set to a var so that it can be overridden by test code for mocking purposes
|
||||||
@ -65,7 +66,7 @@ func NewInformer(ctx context.Context, client dynamic.ResourceInterface, fields [
|
|||||||
// copy of the known state of all objects (in an Indexer).
|
// copy of the known state of all objects (in an Indexer).
|
||||||
// The resync period option here is passed from Informer to Reflector to periodically (re)-push all known
|
// The resync period option here is passed from Informer to Reflector to periodically (re)-push all known
|
||||||
// objects to the DeltaFIFO. That causes the periodic (re-)firing all registered handlers.
|
// objects to the DeltaFIFO. That causes the periodic (re-)firing all registered handlers.
|
||||||
// In this case we are not registering any handlers to this particular informer, so re-syncing is a no-op.
|
// sqltypes.In this case we are not registering any handlers to this particular informer, so re-syncing is a no-op.
|
||||||
// We therefore just disable it right away.
|
// We therefore just disable it right away.
|
||||||
resyncPeriod := time.Duration(0)
|
resyncPeriod := time.Duration(0)
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ func NewInformer(ctx context.Context, client dynamic.ResourceInterface, fields [
|
|||||||
// - the total number of resources (returned list might be a subset depending on pagination options in lo)
|
// - the total number of resources (returned list might be a subset depending on pagination options in lo)
|
||||||
// - a continue token, if there are more pages after the returned one
|
// - a continue token, if there are more pages after the returned one
|
||||||
// - an error instead of all of the above if anything went wrong
|
// - an error instead of all of the above if anything went wrong
|
||||||
func (i *Informer) ListByOptions(ctx context.Context, lo ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error) {
|
func (i *Informer) ListByOptions(ctx context.Context, lo sqltypes.ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error) {
|
||||||
return i.ByOptionsLister.ListByOptions(ctx, lo, partitions, namespace)
|
return i.ByOptionsLister.ListByOptions(ctx, lo, partitions, namespace)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
partition "github.com/rancher/steve/pkg/sqlcache/partition"
|
partition "github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
sqltypes "github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
gomock "go.uber.org/mock/gomock"
|
gomock "go.uber.org/mock/gomock"
|
||||||
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
@ -42,7 +43,7 @@ func (m *MockByOptionsLister) EXPECT() *MockByOptionsListerMockRecorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListByOptions mocks base method.
|
// ListByOptions mocks base method.
|
||||||
func (m *MockByOptionsLister) ListByOptions(arg0 context.Context, arg1 ListOptions, arg2 []partition.Partition, arg3 string) (*unstructured.UnstructuredList, int, string, error) {
|
func (m *MockByOptionsLister) ListByOptions(arg0 context.Context, arg1 sqltypes.ListOptions, arg2 []partition.Partition, arg3 string) (*unstructured.UnstructuredList, int, string, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "ListByOptions", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "ListByOptions", arg0, arg1, arg2, arg3)
|
||||||
ret0, _ := ret[0].(*unstructured.UnstructuredList)
|
ret0, _ := ret[0].(*unstructured.UnstructuredList)
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/rancher/steve/pkg/sqlcache/db"
|
"github.com/rancher/steve/pkg/sqlcache/db"
|
||||||
"github.com/rancher/steve/pkg/sqlcache/partition"
|
"github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
"github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"go.uber.org/mock/gomock"
|
"go.uber.org/mock/gomock"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@ -313,7 +314,7 @@ func TestInformerListByOptions(t *testing.T) {
|
|||||||
informer := &Informer{
|
informer := &Informer{
|
||||||
ByOptionsLister: indexer,
|
ByOptionsLister: indexer,
|
||||||
}
|
}
|
||||||
lo := ListOptions{}
|
lo := sqltypes.ListOptions{}
|
||||||
var partitions []partition.Partition
|
var partitions []partition.Partition
|
||||||
ns := "somens"
|
ns := "somens"
|
||||||
expectedList := &unstructured.UnstructuredList{
|
expectedList := &unstructured.UnstructuredList{
|
||||||
@ -336,7 +337,7 @@ func TestInformerListByOptions(t *testing.T) {
|
|||||||
informer := &Informer{
|
informer := &Informer{
|
||||||
ByOptionsLister: indexer,
|
ByOptionsLister: indexer,
|
||||||
}
|
}
|
||||||
lo := ListOptions{}
|
lo := sqltypes.ListOptions{}
|
||||||
var partitions []partition.Partition
|
var partitions []partition.Partition
|
||||||
ns := "somens"
|
ns := "somens"
|
||||||
indexer.EXPECT().ListByOptions(context.Background(), lo, partitions, ns).Return(nil, 0, "", fmt.Errorf("error"))
|
indexer.EXPECT().ListByOptions(context.Background(), lo, partitions, ns).Return(nil, 0, "", fmt.Errorf("error"))
|
||||||
|
@ -12,6 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/rancher/steve/pkg/sqlcache/db/transaction"
|
"github.com/rancher/steve/pkg/sqlcache/db/transaction"
|
||||||
|
"github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
@ -247,7 +248,7 @@ func (l *ListOptionIndexer) deleteLabels(key string, tx transaction.Client) erro
|
|||||||
// - the total number of resources (returned list might be a subset depending on pagination options in lo)
|
// - the total number of resources (returned list might be a subset depending on pagination options in lo)
|
||||||
// - a continue token, if there are more pages after the returned one
|
// - a continue token, if there are more pages after the returned one
|
||||||
// - an error instead of all of the above if anything went wrong
|
// - an error instead of all of the above if anything went wrong
|
||||||
func (l *ListOptionIndexer) ListByOptions(ctx context.Context, lo ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error) {
|
func (l *ListOptionIndexer) ListByOptions(ctx context.Context, lo sqltypes.ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error) {
|
||||||
queryInfo, err := l.constructQuery(lo, partitions, namespace, db.Sanitize(l.GetName()))
|
queryInfo, err := l.constructQuery(lo, partitions, namespace, db.Sanitize(l.GetName()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, "", err
|
return nil, 0, "", err
|
||||||
@ -266,7 +267,7 @@ type QueryInfo struct {
|
|||||||
offset int
|
offset int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *ListOptionIndexer) constructQuery(lo ListOptions, partitions []partition.Partition, namespace string, dbName string) (*QueryInfo, error) {
|
func (l *ListOptionIndexer) constructQuery(lo sqltypes.ListOptions, partitions []partition.Partition, namespace string, dbName string) (*QueryInfo, error) {
|
||||||
ensureSortLabelsAreSelected(&lo)
|
ensureSortLabelsAreSelected(&lo)
|
||||||
queryInfo := &QueryInfo{}
|
queryInfo := &QueryInfo{}
|
||||||
queryUsesLabels := hasLabelFilter(lo.Filters)
|
queryUsesLabels := hasLabelFilter(lo.Filters)
|
||||||
@ -395,7 +396,7 @@ func (l *ListOptionIndexer) constructQuery(lo ListOptions, partitions []partitio
|
|||||||
orderByClauses := []string{}
|
orderByClauses := []string{}
|
||||||
for i, field := range lo.Sort.Fields {
|
for i, field := range lo.Sort.Fields {
|
||||||
if isLabelsFieldList(field) {
|
if isLabelsFieldList(field) {
|
||||||
clause, sortParam, err := buildSortLabelsClause(field[2], joinTableIndexByLabelName, lo.Sort.Orders[i] == ASC)
|
clause, sortParam, err := buildSortLabelsClause(field[2], joinTableIndexByLabelName, lo.Sort.Orders[i] == sqltypes.ASC)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -407,7 +408,7 @@ func (l *ListOptionIndexer) constructQuery(lo ListOptions, partitions []partitio
|
|||||||
return queryInfo, err
|
return queryInfo, err
|
||||||
}
|
}
|
||||||
direction := "ASC"
|
direction := "ASC"
|
||||||
if lo.Sort.Orders[i] == DESC {
|
if lo.Sort.Orders[i] == sqltypes.DESC {
|
||||||
direction = "DESC"
|
direction = "DESC"
|
||||||
}
|
}
|
||||||
orderByClauses = append(orderByClauses, fmt.Sprintf(`f."%s" %s`, columnName, direction))
|
orderByClauses = append(orderByClauses, fmt.Sprintf(`f."%s" %s`, columnName, direction))
|
||||||
@ -539,7 +540,7 @@ func (l *ListOptionIndexer) validateColumn(column string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// buildORClause creates an SQLite compatible query that ORs conditions built from passed filters
|
// buildORClause creates an SQLite compatible query that ORs conditions built from passed filters
|
||||||
func (l *ListOptionIndexer) buildORClauseFromFilters(orFilters OrFilter, dbName string, joinTableIndexByLabelName map[string]int) (string, []any, error) {
|
func (l *ListOptionIndexer) buildORClauseFromFilters(orFilters sqltypes.OrFilter, dbName string, joinTableIndexByLabelName map[string]int) (string, []any, error) {
|
||||||
var params []any
|
var params []any
|
||||||
clauses := make([]string, 0, len(orFilters.Filters))
|
clauses := make([]string, 0, len(orFilters.Filters))
|
||||||
var newParams []any
|
var newParams []any
|
||||||
@ -594,7 +595,7 @@ func buildSortLabelsClause(labelName string, joinTableIndexByLabelName map[strin
|
|||||||
// There are no thread-safety issues in doing this because the ListOptions object is
|
// There are no thread-safety issues in doing this because the ListOptions object is
|
||||||
// created in Store.ListByPartitions, and that ends up calling ListOptionIndexer.ConstructQuery.
|
// created in Store.ListByPartitions, and that ends up calling ListOptionIndexer.ConstructQuery.
|
||||||
// No other goroutines access this object.
|
// No other goroutines access this object.
|
||||||
func ensureSortLabelsAreSelected(lo *ListOptions) {
|
func ensureSortLabelsAreSelected(lo *sqltypes.ListOptions) {
|
||||||
if len(lo.Sort.Fields) == 0 {
|
if len(lo.Sort.Fields) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -609,13 +610,13 @@ func ensureSortLabelsAreSelected(lo *ListOptions) {
|
|||||||
}
|
}
|
||||||
// If we have sort directives but no filters, add an exists-filter for each label.
|
// If we have sort directives but no filters, add an exists-filter for each label.
|
||||||
if lo.Filters == nil || len(lo.Filters) == 0 {
|
if lo.Filters == nil || len(lo.Filters) == 0 {
|
||||||
lo.Filters = make([]OrFilter, 1)
|
lo.Filters = make([]sqltypes.OrFilter, 1)
|
||||||
lo.Filters[0].Filters = make([]Filter, len(unboundSortLabels))
|
lo.Filters[0].Filters = make([]sqltypes.Filter, len(unboundSortLabels))
|
||||||
i := 0
|
i := 0
|
||||||
for labelName := range unboundSortLabels {
|
for labelName := range unboundSortLabels {
|
||||||
lo.Filters[0].Filters[i] = Filter{
|
lo.Filters[0].Filters[i] = sqltypes.Filter{
|
||||||
Field: []string{"metadata", "labels", labelName},
|
Field: []string{"metadata", "labels", labelName},
|
||||||
Op: Exists,
|
Op: sqltypes.Exists,
|
||||||
}
|
}
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
@ -636,9 +637,9 @@ func ensureSortLabelsAreSelected(lo *ListOptions) {
|
|||||||
for labelName, needsBinding := range copyUnboundSortLabels {
|
for labelName, needsBinding := range copyUnboundSortLabels {
|
||||||
if needsBinding {
|
if needsBinding {
|
||||||
// `orFilters` is a copy of lo.Filters[i], so reference the original.
|
// `orFilters` is a copy of lo.Filters[i], so reference the original.
|
||||||
lo.Filters[i].Filters = append(lo.Filters[i].Filters, Filter{
|
lo.Filters[i].Filters = append(lo.Filters[i].Filters, sqltypes.Filter{
|
||||||
Field: []string{"metadata", "labels", labelName},
|
Field: []string{"metadata", "labels", labelName},
|
||||||
Op: Exists,
|
Op: sqltypes.Exists,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -653,7 +654,7 @@ func ensureSortLabelsAreSelected(lo *ListOptions) {
|
|||||||
// KEY in VALUES
|
// KEY in VALUES
|
||||||
// KEY notin VALUES
|
// KEY notin VALUES
|
||||||
|
|
||||||
func (l *ListOptionIndexer) getFieldFilter(filter Filter) (string, []any, error) {
|
func (l *ListOptionIndexer) getFieldFilter(filter sqltypes.Filter) (string, []any, error) {
|
||||||
opString := ""
|
opString := ""
|
||||||
escapeString := ""
|
escapeString := ""
|
||||||
columnName := toColumnName(filter.Field)
|
columnName := toColumnName(filter.Field)
|
||||||
@ -661,7 +662,7 @@ func (l *ListOptionIndexer) getFieldFilter(filter Filter) (string, []any, error)
|
|||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
switch filter.Op {
|
switch filter.Op {
|
||||||
case Eq:
|
case sqltypes.Eq:
|
||||||
if filter.Partial {
|
if filter.Partial {
|
||||||
opString = "LIKE"
|
opString = "LIKE"
|
||||||
escapeString = escapeBackslashDirective
|
escapeString = escapeBackslashDirective
|
||||||
@ -670,7 +671,7 @@ func (l *ListOptionIndexer) getFieldFilter(filter Filter) (string, []any, error)
|
|||||||
}
|
}
|
||||||
clause := fmt.Sprintf(`f."%s" %s ?%s`, columnName, opString, escapeString)
|
clause := fmt.Sprintf(`f."%s" %s ?%s`, columnName, opString, escapeString)
|
||||||
return clause, []any{formatMatchTarget(filter)}, nil
|
return clause, []any{formatMatchTarget(filter)}, nil
|
||||||
case NotEq:
|
case sqltypes.NotEq:
|
||||||
if filter.Partial {
|
if filter.Partial {
|
||||||
opString = "NOT LIKE"
|
opString = "NOT LIKE"
|
||||||
escapeString = escapeBackslashDirective
|
escapeString = escapeBackslashDirective
|
||||||
@ -680,7 +681,7 @@ func (l *ListOptionIndexer) getFieldFilter(filter Filter) (string, []any, error)
|
|||||||
clause := fmt.Sprintf(`f."%s" %s ?%s`, columnName, opString, escapeString)
|
clause := fmt.Sprintf(`f."%s" %s ?%s`, columnName, opString, escapeString)
|
||||||
return clause, []any{formatMatchTarget(filter)}, nil
|
return clause, []any{formatMatchTarget(filter)}, nil
|
||||||
|
|
||||||
case Lt, Gt:
|
case sqltypes.Lt, sqltypes.Gt:
|
||||||
sym, target, err := prepareComparisonParameters(filter.Op, filter.Matches[0])
|
sym, target, err := prepareComparisonParameters(filter.Op, filter.Matches[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
@ -688,18 +689,18 @@ func (l *ListOptionIndexer) getFieldFilter(filter Filter) (string, []any, error)
|
|||||||
clause := fmt.Sprintf(`f."%s" %s ?`, columnName, sym)
|
clause := fmt.Sprintf(`f."%s" %s ?`, columnName, sym)
|
||||||
return clause, []any{target}, nil
|
return clause, []any{target}, nil
|
||||||
|
|
||||||
case Exists, NotExists:
|
case sqltypes.Exists, sqltypes.NotExists:
|
||||||
return "", nil, errors.New("NULL and NOT NULL tests aren't supported for non-label queries")
|
return "", nil, errors.New("NULL and NOT NULL tests aren't supported for non-label queries")
|
||||||
|
|
||||||
case In:
|
case sqltypes.In:
|
||||||
fallthrough
|
fallthrough
|
||||||
case NotIn:
|
case sqltypes.NotIn:
|
||||||
target := "()"
|
target := "()"
|
||||||
if len(filter.Matches) > 0 {
|
if len(filter.Matches) > 0 {
|
||||||
target = fmt.Sprintf("(?%s)", strings.Repeat(", ?", len(filter.Matches)-1))
|
target = fmt.Sprintf("(?%s)", strings.Repeat(", ?", len(filter.Matches)-1))
|
||||||
}
|
}
|
||||||
opString = "IN"
|
opString = "IN"
|
||||||
if filter.Op == NotIn {
|
if filter.Op == sqltypes.NotIn {
|
||||||
opString = "NOT IN"
|
opString = "NOT IN"
|
||||||
}
|
}
|
||||||
clause := fmt.Sprintf(`f."%s" %s %s`, columnName, opString, target)
|
clause := fmt.Sprintf(`f."%s" %s %s`, columnName, opString, target)
|
||||||
@ -713,13 +714,13 @@ func (l *ListOptionIndexer) getFieldFilter(filter Filter) (string, []any, error)
|
|||||||
return "", nil, fmt.Errorf("unrecognized operator: %s", opString)
|
return "", nil, fmt.Errorf("unrecognized operator: %s", opString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *ListOptionIndexer) getLabelFilter(index int, filter Filter, dbName string) (string, []any, error) {
|
func (l *ListOptionIndexer) getLabelFilter(index int, filter sqltypes.Filter, dbName string) (string, []any, error) {
|
||||||
opString := ""
|
opString := ""
|
||||||
escapeString := ""
|
escapeString := ""
|
||||||
matchFmtToUse := strictMatchFmt
|
matchFmtToUse := strictMatchFmt
|
||||||
labelName := filter.Field[2]
|
labelName := filter.Field[2]
|
||||||
switch filter.Op {
|
switch filter.Op {
|
||||||
case Eq:
|
case sqltypes.Eq:
|
||||||
if filter.Partial {
|
if filter.Partial {
|
||||||
opString = "LIKE"
|
opString = "LIKE"
|
||||||
escapeString = escapeBackslashDirective
|
escapeString = escapeBackslashDirective
|
||||||
@ -730,7 +731,7 @@ func (l *ListOptionIndexer) getLabelFilter(index int, filter Filter, dbName stri
|
|||||||
clause := fmt.Sprintf(`lt%d.label = ? AND lt%d.value %s ?%s`, index, index, opString, escapeString)
|
clause := fmt.Sprintf(`lt%d.label = ? AND lt%d.value %s ?%s`, index, index, opString, escapeString)
|
||||||
return clause, []any{labelName, formatMatchTargetWithFormatter(filter.Matches[0], matchFmtToUse)}, nil
|
return clause, []any{labelName, formatMatchTargetWithFormatter(filter.Matches[0], matchFmtToUse)}, nil
|
||||||
|
|
||||||
case NotEq:
|
case sqltypes.NotEq:
|
||||||
if filter.Partial {
|
if filter.Partial {
|
||||||
opString = "NOT LIKE"
|
opString = "NOT LIKE"
|
||||||
escapeString = escapeBackslashDirective
|
escapeString = escapeBackslashDirective
|
||||||
@ -738,9 +739,9 @@ func (l *ListOptionIndexer) getLabelFilter(index int, filter Filter, dbName stri
|
|||||||
} else {
|
} else {
|
||||||
opString = "!="
|
opString = "!="
|
||||||
}
|
}
|
||||||
subFilter := Filter{
|
subFilter := sqltypes.Filter{
|
||||||
Field: filter.Field,
|
Field: filter.Field,
|
||||||
Op: NotExists,
|
Op: sqltypes.NotExists,
|
||||||
}
|
}
|
||||||
existenceClause, subParams, err := l.getLabelFilter(index, subFilter, dbName)
|
existenceClause, subParams, err := l.getLabelFilter(index, subFilter, dbName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -750,7 +751,7 @@ func (l *ListOptionIndexer) getLabelFilter(index int, filter Filter, dbName stri
|
|||||||
params := append(subParams, labelName, formatMatchTargetWithFormatter(filter.Matches[0], matchFmtToUse))
|
params := append(subParams, labelName, formatMatchTargetWithFormatter(filter.Matches[0], matchFmtToUse))
|
||||||
return clause, params, nil
|
return clause, params, nil
|
||||||
|
|
||||||
case Lt, Gt:
|
case sqltypes.Lt, sqltypes.Gt:
|
||||||
sym, target, err := prepareComparisonParameters(filter.Op, filter.Matches[0])
|
sym, target, err := prepareComparisonParameters(filter.Op, filter.Matches[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
@ -758,18 +759,18 @@ func (l *ListOptionIndexer) getLabelFilter(index int, filter Filter, dbName stri
|
|||||||
clause := fmt.Sprintf(`lt%d.label = ? AND lt%d.value %s ?`, index, index, sym)
|
clause := fmt.Sprintf(`lt%d.label = ? AND lt%d.value %s ?`, index, index, sym)
|
||||||
return clause, []any{labelName, target}, nil
|
return clause, []any{labelName, target}, nil
|
||||||
|
|
||||||
case Exists:
|
case sqltypes.Exists:
|
||||||
clause := fmt.Sprintf(`lt%d.label = ?`, index)
|
clause := fmt.Sprintf(`lt%d.label = ?`, index)
|
||||||
return clause, []any{labelName}, nil
|
return clause, []any{labelName}, nil
|
||||||
|
|
||||||
case NotExists:
|
case sqltypes.NotExists:
|
||||||
clause := fmt.Sprintf(`o.key NOT IN (SELECT o1.key FROM "%s" o1
|
clause := fmt.Sprintf(`o.key NOT IN (SELECT o1.key FROM "%s" o1
|
||||||
JOIN "%s_fields" f1 ON o1.key = f1.key
|
JOIN "%s_fields" f1 ON o1.key = f1.key
|
||||||
LEFT OUTER JOIN "%s_labels" lt%di1 ON o1.key = lt%di1.key
|
LEFT OUTER JOIN "%s_labels" lt%di1 ON o1.key = lt%di1.key
|
||||||
WHERE lt%di1.label = ?)`, dbName, dbName, dbName, index, index, index)
|
WHERE lt%di1.label = ?)`, dbName, dbName, dbName, index, index, index)
|
||||||
return clause, []any{labelName}, nil
|
return clause, []any{labelName}, nil
|
||||||
|
|
||||||
case In:
|
case sqltypes.In:
|
||||||
target := "(?"
|
target := "(?"
|
||||||
if len(filter.Matches) > 0 {
|
if len(filter.Matches) > 0 {
|
||||||
target += strings.Repeat(", ?", len(filter.Matches)-1)
|
target += strings.Repeat(", ?", len(filter.Matches)-1)
|
||||||
@ -783,15 +784,15 @@ func (l *ListOptionIndexer) getLabelFilter(index int, filter Filter, dbName stri
|
|||||||
}
|
}
|
||||||
return clause, matches, nil
|
return clause, matches, nil
|
||||||
|
|
||||||
case NotIn:
|
case sqltypes.NotIn:
|
||||||
target := "(?"
|
target := "(?"
|
||||||
if len(filter.Matches) > 0 {
|
if len(filter.Matches) > 0 {
|
||||||
target += strings.Repeat(", ?", len(filter.Matches)-1)
|
target += strings.Repeat(", ?", len(filter.Matches)-1)
|
||||||
}
|
}
|
||||||
target += ")"
|
target += ")"
|
||||||
subFilter := Filter{
|
subFilter := sqltypes.Filter{
|
||||||
Field: filter.Field,
|
Field: filter.Field,
|
||||||
Op: NotExists,
|
Op: sqltypes.NotExists,
|
||||||
}
|
}
|
||||||
existenceClause, subParams, err := l.getLabelFilter(index, subFilter, dbName)
|
existenceClause, subParams, err := l.getLabelFilter(index, subFilter, dbName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -807,21 +808,21 @@ func (l *ListOptionIndexer) getLabelFilter(index int, filter Filter, dbName stri
|
|||||||
return "", nil, fmt.Errorf("unrecognized operator: %s", opString)
|
return "", nil, fmt.Errorf("unrecognized operator: %s", opString)
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareComparisonParameters(op Op, target string) (string, float64, error) {
|
func prepareComparisonParameters(op sqltypes.Op, target string) (string, float64, error) {
|
||||||
num, err := strconv.ParseFloat(target, 32)
|
num, err := strconv.ParseFloat(target, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", 0, err
|
return "", 0, err
|
||||||
}
|
}
|
||||||
switch op {
|
switch op {
|
||||||
case Lt:
|
case sqltypes.Lt:
|
||||||
return "<", num, nil
|
return "<", num, nil
|
||||||
case Gt:
|
case sqltypes.Gt:
|
||||||
return ">", num, nil
|
return ">", num, nil
|
||||||
}
|
}
|
||||||
return "", 0, fmt.Errorf("unrecognized operator when expecting '<' or '>': '%s'", op)
|
return "", 0, fmt.Errorf("unrecognized operator when expecting '<' or '>': '%s'", op)
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatMatchTarget(filter Filter) string {
|
func formatMatchTarget(filter sqltypes.Filter) string {
|
||||||
format := strictMatchFmt
|
format := strictMatchFmt
|
||||||
if filter.Partial {
|
if filter.Partial {
|
||||||
format = matchFmt
|
format = matchFmt
|
||||||
@ -928,11 +929,11 @@ func extractSubFields(fields string) []string {
|
|||||||
return subfields
|
return subfields
|
||||||
}
|
}
|
||||||
|
|
||||||
func isLabelFilter(f *Filter) bool {
|
func isLabelFilter(f *sqltypes.Filter) bool {
|
||||||
return len(f.Field) >= 2 && f.Field[0] == "metadata" && f.Field[1] == "labels"
|
return len(f.Field) >= 2 && f.Field[0] == "metadata" && f.Field[1] == "labels"
|
||||||
}
|
}
|
||||||
|
|
||||||
func hasLabelFilter(filters []OrFilter) bool {
|
func hasLabelFilter(filters []sqltypes.OrFilter) bool {
|
||||||
for _, outerFilter := range filters {
|
for _, outerFilter := range filters {
|
||||||
for _, filter := range outerFilter.Filters {
|
for _, filter := range outerFilter.Filters {
|
||||||
if isLabelFilter(&filter) {
|
if isLabelFilter(&filter) {
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
@ -255,7 +256,7 @@ func TestNewListOptionIndexer(t *testing.T) {
|
|||||||
func TestListByOptions(t *testing.T) {
|
func TestListByOptions(t *testing.T) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
description string
|
description string
|
||||||
listOptions ListOptions
|
listOptions sqltypes.ListOptions
|
||||||
partitions []partition.Partition
|
partitions []partition.Partition
|
||||||
ns string
|
ns string
|
||||||
expectedCountStmt string
|
expectedCountStmt string
|
||||||
@ -276,7 +277,7 @@ func TestListByOptions(t *testing.T) {
|
|||||||
var tests []testCase
|
var tests []testCase
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions() with no errors returned, should not return an error",
|
description: "ListByOptions() with no errors returned, should not return an error",
|
||||||
listOptions: ListOptions{},
|
listOptions: sqltypes.ListOptions{},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
ns: "",
|
ns: "",
|
||||||
expectedStmt: `SELECT o.object, o.objectnonce, o.dekid FROM "something" o
|
expectedStmt: `SELECT o.object, o.objectnonce, o.dekid FROM "something" o
|
||||||
@ -291,8 +292,8 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions() with an empty filter, should not return an error",
|
description: "ListByOptions() with an empty filter, should not return an error",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Filters: []OrFilter{{[]Filter{}}},
|
Filters: []sqltypes.OrFilter{{[]sqltypes.Filter{}}},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
ns: "",
|
ns: "",
|
||||||
@ -307,7 +308,7 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with ChunkSize set should set limit in prepared sql.Stmt",
|
description: "ListByOptions with ChunkSize set should set limit in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{ChunkSize: 2},
|
listOptions: sqltypes.ListOptions{ChunkSize: 2},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
ns: "",
|
ns: "",
|
||||||
expectedStmt: `SELECT o.object, o.objectnonce, o.dekid FROM "something" o
|
expectedStmt: `SELECT o.object, o.objectnonce, o.dekid FROM "something" o
|
||||||
@ -329,7 +330,7 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with Resume set should set offset in prepared sql.Stmt",
|
description: "ListByOptions with Resume set should set offset in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{Resume: "4"},
|
listOptions: sqltypes.ListOptions{Resume: "4"},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
ns: "",
|
ns: "",
|
||||||
expectedStmt: `SELECT o.object, o.objectnonce, o.dekid FROM "something" o
|
expectedStmt: `SELECT o.object, o.objectnonce, o.dekid FROM "something" o
|
||||||
@ -351,13 +352,13 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with 1 OrFilter set with 1 filter should select where that filter is true in prepared sql.Stmt",
|
description: "ListByOptions with 1 OrFilter set with 1 filter should select where that filter is true in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -380,13 +381,13 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with 1 OrFilter set with 1 filter with Op set top NotEq should select where that filter is not true in prepared sql.Stmt",
|
description: "ListByOptions with 1 OrFilter set with 1 filter with Op set top NotEq should select where that filter is not true in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -409,13 +410,13 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with 1 OrFilter set with 1 filter with Partial set to true should select where that partial match on that filter's value is true in prepared sql.Stmt",
|
description: "ListByOptions with 1 OrFilter set with 1 filter with Partial set to true should select where that partial match on that filter's value is true in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -438,25 +439,25 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with 1 OrFilter set with multiple filters should select where any of those filters are true in prepared sql.Stmt",
|
description: "ListByOptions with 1 OrFilter set with multiple filters should select where any of those filters are true in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"someothervalue"},
|
Matches: []string{"someothervalue"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"somethirdvalue"},
|
Matches: []string{"somethirdvalue"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -479,29 +480,29 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with multiple OrFilters set should select where all OrFilters contain one filter that is true in prepared sql.Stmt",
|
description: "ListByOptions with multiple OrFilters set should select where all OrFilters contain one filter that is true in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"value1"},
|
Matches: []string{"value1"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"status", "someotherfield"},
|
Field: []string{"status", "someotherfield"},
|
||||||
Matches: []string{"value2"},
|
Matches: []string{"value2"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"value3"},
|
Matches: []string{"value3"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -526,13 +527,13 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with labels filter should select the label in the prepared sql.Stmt",
|
description: "ListByOptions with labels filter should select the label in the prepared sql.Stmt",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "guard.cattle.io"},
|
Field: []string{"metadata", "labels", "guard.cattle.io"},
|
||||||
Matches: []string{"lodgepole"},
|
Matches: []string{"lodgepole"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -558,23 +559,23 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with two labels filters should use a self-join",
|
description: "ListByOptions with two labels filters should use a self-join",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "cows"},
|
Field: []string{"metadata", "labels", "cows"},
|
||||||
Matches: []string{"milk"},
|
Matches: []string{"milk"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "horses"},
|
Field: []string{"metadata", "labels", "horses"},
|
||||||
Matches: []string{"saddles"},
|
Matches: []string{"saddles"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -602,23 +603,23 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with a mix of one label and one non-label query can still self-join",
|
description: "ListByOptions with a mix of one label and one non-label query can still self-join",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "cows"},
|
Field: []string{"metadata", "labels", "cows"},
|
||||||
Matches: []string{"butter"},
|
Matches: []string{"butter"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "somefield"},
|
Field: []string{"metadata", "somefield"},
|
||||||
Matches: []string{"wheat"},
|
Matches: []string{"wheat"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -645,10 +646,10 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with only one Sort.Field set should sort on that field only, in ascending order in prepared sql.Stmt",
|
description: "ListByOptions with only one Sort.Field set should sort on that field only, in ascending order in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "somefield"}},
|
Fields: [][]string{{"metadata", "somefield"}},
|
||||||
Orders: []SortOrder{ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -668,10 +669,10 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "sort one field descending",
|
description: "sort one field descending",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "somefield"}},
|
Fields: [][]string{{"metadata", "somefield"}},
|
||||||
Orders: []SortOrder{DESC},
|
Orders: []sqltypes.SortOrder{sqltypes.DESC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -691,10 +692,10 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "sort one unbound label descending",
|
description: "sort one unbound label descending",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "labels", "flip"}},
|
Fields: [][]string{{"metadata", "labels", "flip"}},
|
||||||
Orders: []SortOrder{DESC},
|
Orders: []sqltypes.SortOrder{sqltypes.DESC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -716,10 +717,10 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions sorting on two complex fields should sort on the first field in ascending order first and then sort on the second labels field in ascending order in prepared sql.Stmt",
|
description: "ListByOptions sorting on two complex fields should sort on the first field in ascending order first and then sort on the second labels field in ascending order in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "fields", "3"}, {"metadata", "labels", "stub.io/candy"}},
|
Fields: [][]string{{"metadata", "fields", "3"}, {"metadata", "labels", "stub.io/candy"}},
|
||||||
Orders: []SortOrder{ASC, ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.ASC, sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
extraIndexedFields: []string{"metadata.fields[3]", "metadata.labels[stub.io/candy]"},
|
extraIndexedFields: []string{"metadata.fields[3]", "metadata.labels[stub.io/candy]"},
|
||||||
@ -740,10 +741,10 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions sorting on two fields should sort on the first field in ascending order first and then sort on the second field in ascending order in prepared sql.Stmt",
|
description: "ListByOptions sorting on two fields should sort on the first field in ascending order first and then sort on the second field in ascending order in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}},
|
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}},
|
||||||
Orders: []SortOrder{ASC, ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.ASC, sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -761,10 +762,10 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions sorting on two fields should sort on the first field in descending order first and then sort on the second field in ascending order in prepared sql.Stmt",
|
description: "ListByOptions sorting on two fields should sort on the first field in descending order first and then sort on the second field in ascending order in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}},
|
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}},
|
||||||
Orders: []SortOrder{DESC, ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.DESC, sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -782,10 +783,10 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions sorting when # fields != # sort orders should return an error",
|
description: "ListByOptions sorting when # fields != # sort orders should return an error",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}},
|
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}},
|
||||||
Orders: []SortOrder{DESC, ASC, ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.DESC, sqltypes.ASC, sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -803,8 +804,8 @@ func TestListByOptions(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with Pagination.PageSize set should set limit to PageSize in prepared sql.Stmt",
|
description: "ListByOptions with Pagination.PageSize set should set limit to PageSize in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Pagination: Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
PageSize: 10,
|
PageSize: 10,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -829,8 +830,8 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with Pagination.Page and no PageSize set should not add anything to prepared sql.Stmt",
|
description: "ListByOptions with Pagination.Page and no PageSize set should not add anything to prepared sql.Stmt",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Pagination: Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 2,
|
Page: 2,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -848,8 +849,8 @@ func TestListByOptions(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ListByOptions with Pagination.Page and PageSize set limit to PageSize and offset to PageSize * (Page - 1) in prepared sql.Stmt",
|
description: "ListByOptions with Pagination.Page and PageSize set limit to PageSize and offset to PageSize * (Page - 1) in prepared sql.Stmt",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Pagination: Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
PageSize: 10,
|
PageSize: 10,
|
||||||
Page: 2,
|
Page: 2,
|
||||||
},
|
},
|
||||||
@ -1028,7 +1029,7 @@ func TestListByOptions(t *testing.T) {
|
|||||||
func TestConstructQuery(t *testing.T) {
|
func TestConstructQuery(t *testing.T) {
|
||||||
type testCase struct {
|
type testCase struct {
|
||||||
description string
|
description string
|
||||||
listOptions ListOptions
|
listOptions sqltypes.ListOptions
|
||||||
partitions []partition.Partition
|
partitions []partition.Partition
|
||||||
ns string
|
ns string
|
||||||
expectedCountStmt string
|
expectedCountStmt string
|
||||||
@ -1041,13 +1042,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
var tests []testCase
|
var tests []testCase
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles IN statements",
|
description: "TestConstructQuery: handles IN statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "queryField1"},
|
Field: []string{"metadata", "queryField1"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: In,
|
Op: sqltypes.In,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1066,13 +1067,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles NOT-IN statements",
|
description: "TestConstructQuery: handles NOT-IN statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "queryField1"},
|
Field: []string{"metadata", "queryField1"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: NotIn,
|
Op: sqltypes.NotIn,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1091,12 +1092,12 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles EXISTS statements",
|
description: "TestConstructQuery: handles EXISTS statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "queryField1"},
|
Field: []string{"metadata", "queryField1"},
|
||||||
Op: Exists,
|
Op: sqltypes.Exists,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1108,12 +1109,12 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles NOT-EXISTS statements",
|
description: "TestConstructQuery: handles NOT-EXISTS statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "queryField1"},
|
Field: []string{"metadata", "queryField1"},
|
||||||
Op: NotExists,
|
Op: sqltypes.NotExists,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1125,13 +1126,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles == statements for label statements",
|
description: "TestConstructQuery: handles == statements for label statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelEqualFull"},
|
Field: []string{"metadata", "labels", "labelEqualFull"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1152,13 +1153,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles == statements for label statements, match partial",
|
description: "TestConstructQuery: handles == statements for label statements, match partial",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelEqualPartial"},
|
Field: []string{"metadata", "labels", "labelEqualPartial"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1179,13 +1180,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles != statements for label statements",
|
description: "TestConstructQuery: handles != statements for label statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelNotEqualFull"},
|
Field: []string{"metadata", "labels", "labelNotEqualFull"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1210,13 +1211,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles != statements for label statements, match partial",
|
description: "TestConstructQuery: handles != statements for label statements, match partial",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelNotEqualPartial"},
|
Field: []string{"metadata", "labels", "labelNotEqualPartial"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1241,23 +1242,23 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles multiple != statements for label statements",
|
description: "TestConstructQuery: handles multiple != statements for label statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "notEqual1"},
|
Field: []string{"metadata", "labels", "notEqual1"},
|
||||||
Matches: []string{"value1"},
|
Matches: []string{"value1"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "notEqual2"},
|
Field: []string{"metadata", "labels", "notEqual2"},
|
||||||
Matches: []string{"value2"},
|
Matches: []string{"value2"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1286,13 +1287,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles IN statements for label statements",
|
description: "TestConstructQuery: handles IN statements for label statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelIN"},
|
Field: []string{"metadata", "labels", "labelIN"},
|
||||||
Matches: []string{"somevalue1", "someValue2"},
|
Matches: []string{"somevalue1", "someValue2"},
|
||||||
Op: In,
|
Op: sqltypes.In,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1313,13 +1314,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles NOTIN statements for label statements",
|
description: "TestConstructQuery: handles NOTIN statements for label statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelNOTIN"},
|
Field: []string{"metadata", "labels", "labelNOTIN"},
|
||||||
Matches: []string{"somevalue1", "someValue2"},
|
Matches: []string{"somevalue1", "someValue2"},
|
||||||
Op: NotIn,
|
Op: sqltypes.NotIn,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1343,13 +1344,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles EXISTS statements for label statements",
|
description: "TestConstructQuery: handles EXISTS statements for label statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelEXISTS"},
|
Field: []string{"metadata", "labels", "labelEXISTS"},
|
||||||
Matches: []string{},
|
Matches: []string{},
|
||||||
Op: Exists,
|
Op: sqltypes.Exists,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1370,13 +1371,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles NOTEXISTS statements for label statements",
|
description: "TestConstructQuery: handles NOTEXISTS statements for label statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelNOTEXISTS"},
|
Field: []string{"metadata", "labels", "labelNOTEXISTS"},
|
||||||
Matches: []string{},
|
Matches: []string{},
|
||||||
Op: NotExists,
|
Op: sqltypes.NotExists,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1399,13 +1400,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles LessThan statements",
|
description: "TestConstructQuery: handles LessThan statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "numericThing"},
|
Field: []string{"metadata", "labels", "numericThing"},
|
||||||
Matches: []string{"5"},
|
Matches: []string{"5"},
|
||||||
Op: Lt,
|
Op: sqltypes.Lt,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1425,13 +1426,13 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles GreaterThan statements",
|
description: "TestConstructQuery: handles GreaterThan statements",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "numericThing"},
|
Field: []string{"metadata", "labels", "numericThing"},
|
||||||
Matches: []string{"35"},
|
Matches: []string{"35"},
|
||||||
Op: Gt,
|
Op: sqltypes.Gt,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1451,19 +1452,19 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "multiple filters with a positive label test and a negative non-label test still outer-join",
|
description: "multiple filters with a positive label test and a negative non-label test still outer-join",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "junta"},
|
Field: []string{"metadata", "labels", "junta"},
|
||||||
Matches: []string{"esther"},
|
Matches: []string{"esther"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "queryField1"},
|
Field: []string{"metadata", "queryField1"},
|
||||||
Matches: []string{"golgi"},
|
Matches: []string{"golgi"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1484,33 +1485,33 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
})
|
})
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "multiple filters and or-filters with a positive label test and a negative non-label test still outer-join and have correct AND/ORs",
|
description: "multiple filters and or-filters with a positive label test and a negative non-label test still outer-join and have correct AND/ORs",
|
||||||
listOptions: ListOptions{Filters: []OrFilter{
|
listOptions: sqltypes.ListOptions{Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "nectar"},
|
Field: []string{"metadata", "labels", "nectar"},
|
||||||
Matches: []string{"stash"},
|
Matches: []string{"stash"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "queryField1"},
|
Field: []string{"metadata", "queryField1"},
|
||||||
Matches: []string{"landlady"},
|
Matches: []string{"landlady"},
|
||||||
Op: NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Filters: []Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "lawn"},
|
Field: []string{"metadata", "labels", "lawn"},
|
||||||
Matches: []string{"reba", "coil"},
|
Matches: []string{"reba", "coil"},
|
||||||
Op: In,
|
Op: sqltypes.In,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "queryField1"},
|
Field: []string{"metadata", "queryField1"},
|
||||||
Op: Gt,
|
Op: sqltypes.Gt,
|
||||||
Matches: []string{"2"},
|
Matches: []string{"2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1534,22 +1535,22 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: handles == statements for label statements, match partial, sort on metadata.queryField1",
|
description: "TestConstructQuery: handles == statements for label statements, match partial, sort on metadata.queryField1",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Filters: []OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "labelEqualPartial"},
|
Field: []string{"metadata", "labels", "labelEqualPartial"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "queryField1"}},
|
Fields: [][]string{{"metadata", "queryField1"}},
|
||||||
Orders: []SortOrder{ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -1567,10 +1568,10 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ConstructQuery: sorting when # fields < # sort orders should return an error",
|
description: "ConstructQuery: sorting when # fields < # sort orders should return an error",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}},
|
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}},
|
||||||
Orders: []SortOrder{DESC, ASC, ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.DESC, sqltypes.ASC, sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -1582,10 +1583,10 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: sort on label statements with no query",
|
description: "TestConstructQuery: sort on label statements with no query",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "labels", "this"}},
|
Fields: [][]string{{"metadata", "labels", "this"}},
|
||||||
Orders: []SortOrder{ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -1603,26 +1604,26 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "TestConstructQuery: sort and query on both labels and non-labels without overlap",
|
description: "TestConstructQuery: sort and query on both labels and non-labels without overlap",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Filters: []OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
[]Filter{
|
[]sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "queryField1"},
|
Field: []string{"metadata", "queryField1"},
|
||||||
Matches: []string{"toys"},
|
Matches: []string{"toys"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "jamb"},
|
Field: []string{"metadata", "labels", "jamb"},
|
||||||
Matches: []string{"juice"},
|
Matches: []string{"juice"},
|
||||||
Op: Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "labels", "this"}, {"status", "queryField2"}},
|
Fields: [][]string{{"metadata", "labels", "this"}, {"status", "queryField2"}},
|
||||||
Orders: []SortOrder{ASC, DESC},
|
Orders: []sqltypes.SortOrder{sqltypes.ASC, sqltypes.DESC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
@ -1641,10 +1642,10 @@ func TestConstructQuery(t *testing.T) {
|
|||||||
|
|
||||||
tests = append(tests, testCase{
|
tests = append(tests, testCase{
|
||||||
description: "ConstructQuery: sorting when # fields > # sort orders should return an error",
|
description: "ConstructQuery: sorting when # fields > # sort orders should return an error",
|
||||||
listOptions: ListOptions{
|
listOptions: sqltypes.ListOptions{
|
||||||
Sort: Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}, {"metadata", "labels", "a1"}, {"metadata", "labels", "a2"}},
|
Fields: [][]string{{"metadata", "somefield"}, {"status", "someotherfield"}, {"metadata", "labels", "a1"}, {"metadata", "labels", "a2"}},
|
||||||
Orders: []SortOrder{DESC, ASC, ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.DESC, sqltypes.ASC, sqltypes.ASC},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
partitions: []partition.Partition{},
|
partitions: []partition.Partition{},
|
||||||
|
@ -18,9 +18,9 @@ import (
|
|||||||
"k8s.io/client-go/tools/cache"
|
"k8s.io/client-go/tools/cache"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
"sigs.k8s.io/controller-runtime/pkg/envtest"
|
||||||
|
|
||||||
"github.com/rancher/steve/pkg/sqlcache/informer"
|
|
||||||
"github.com/rancher/steve/pkg/sqlcache/informer/factory"
|
"github.com/rancher/steve/pkg/sqlcache/informer/factory"
|
||||||
"github.com/rancher/steve/pkg/sqlcache/partition"
|
"github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
"github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
const testNamespace = "sql-test"
|
const testNamespace = "sql-test"
|
||||||
@ -107,8 +107,8 @@ func (i *IntegrationSuite) TestSQLCacheFilters() {
|
|||||||
err = i.waitForCacheReady(configMapNames, testNamespace, cache)
|
err = i.waitForCacheReady(configMapNames, testNamespace, cache)
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
|
||||||
orFiltersForFilters := func(filters ...informer.Filter) []informer.OrFilter {
|
orFiltersForFilters := func(filters ...sqltypes.Filter) []sqltypes.OrFilter {
|
||||||
return []informer.OrFilter{
|
return []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: filters,
|
Filters: filters,
|
||||||
},
|
},
|
||||||
@ -116,85 +116,85 @@ func (i *IntegrationSuite) TestSQLCacheFilters() {
|
|||||||
}
|
}
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
filters []informer.OrFilter
|
filters []sqltypes.OrFilter
|
||||||
wantNames []string
|
wantNames []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "matches filter",
|
name: "matches filter",
|
||||||
filters: orFiltersForFilters(informer.Filter{
|
filters: orFiltersForFilters(sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
}),
|
}),
|
||||||
wantNames: []string{"matches-filter"},
|
wantNames: []string{"matches-filter"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "partial matches filter",
|
name: "partial matches filter",
|
||||||
filters: orFiltersForFilters(informer.Filter{
|
filters: orFiltersForFilters(sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
}),
|
}),
|
||||||
wantNames: []string{"matches-filter", "partial-matches"},
|
wantNames: []string{"matches-filter", "partial-matches"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no matches for filter with underscore as it is interpreted literally",
|
name: "no matches for filter with underscore as it is interpreted literally",
|
||||||
filters: orFiltersForFilters(informer.Filter{
|
filters: orFiltersForFilters(sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalu_"},
|
Matches: []string{"somevalu_"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
}),
|
}),
|
||||||
wantNames: nil,
|
wantNames: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no matches for filter with percent sign as it is interpreted literally",
|
name: "no matches for filter with percent sign as it is interpreted literally",
|
||||||
filters: orFiltersForFilters(informer.Filter{
|
filters: orFiltersForFilters(sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalu%"},
|
Matches: []string{"somevalu%"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
}),
|
}),
|
||||||
wantNames: nil,
|
wantNames: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "match with special characters",
|
name: "match with special characters",
|
||||||
filters: orFiltersForFilters(informer.Filter{
|
filters: orFiltersForFilters(sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"c%%l_value"},
|
Matches: []string{"c%%l_value"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
}),
|
}),
|
||||||
wantNames: []string{"special-character-matches"},
|
wantNames: []string{"special-character-matches"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "match with literal backslash character",
|
name: "match with literal backslash character",
|
||||||
filters: orFiltersForFilters(informer.Filter{
|
filters: orFiltersForFilters(sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{`my\windows\path`},
|
Matches: []string{`my\windows\path`},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
}),
|
}),
|
||||||
wantNames: []string{"backslash-character-matches"},
|
wantNames: []string{"backslash-character-matches"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "not eq filter",
|
name: "not eq filter",
|
||||||
filters: orFiltersForFilters(informer.Filter{
|
filters: orFiltersForFilters(sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: informer.NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
}),
|
}),
|
||||||
wantNames: []string{"partial-matches", "not-matches-filter", "missing", "special-character-matches", "backslash-character-matches"},
|
wantNames: []string{"partial-matches", "not-matches-filter", "missing", "special-character-matches", "backslash-character-matches"},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "partial not eq filter",
|
name: "partial not eq filter",
|
||||||
filters: orFiltersForFilters(informer.Filter{
|
filters: orFiltersForFilters(sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: informer.NotEq,
|
Op: sqltypes.NotEq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
}),
|
}),
|
||||||
wantNames: []string{"not-matches-filter", "missing", "special-character-matches", "backslash-character-matches"},
|
wantNames: []string{"not-matches-filter", "missing", "special-character-matches", "backslash-character-matches"},
|
||||||
@ -202,16 +202,16 @@ func (i *IntegrationSuite) TestSQLCacheFilters() {
|
|||||||
{
|
{
|
||||||
name: "multiple or filters match",
|
name: "multiple or filters match",
|
||||||
filters: orFiltersForFilters(
|
filters: orFiltersForFilters(
|
||||||
informer.Filter{
|
sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
informer.Filter{
|
sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"notequal"},
|
Matches: []string{"notequal"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -220,16 +220,16 @@ func (i *IntegrationSuite) TestSQLCacheFilters() {
|
|||||||
{
|
{
|
||||||
name: "or filters on different fields",
|
name: "or filters on different fields",
|
||||||
filters: orFiltersForFilters(
|
filters: orFiltersForFilters(
|
||||||
informer.Filter{
|
sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
informer.Filter{
|
sqltypes.Filter{
|
||||||
Field: []string{`metadata`, `name`},
|
Field: []string{`metadata`, `name`},
|
||||||
Matches: []string{"missing"},
|
Matches: []string{"missing"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -237,23 +237,23 @@ func (i *IntegrationSuite) TestSQLCacheFilters() {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "and filters, both must match",
|
name: "and filters, both must match",
|
||||||
filters: []informer.OrFilter{
|
filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"somevalue"},
|
Matches: []string{"somevalue"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{`metadata`, `name`},
|
Field: []string{`metadata`, `name`},
|
||||||
Matches: []string{"matches-filter"},
|
Matches: []string{"matches-filter"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -264,10 +264,10 @@ func (i *IntegrationSuite) TestSQLCacheFilters() {
|
|||||||
{
|
{
|
||||||
name: "no matches",
|
name: "no matches",
|
||||||
filters: orFiltersForFilters(
|
filters: orFiltersForFilters(
|
||||||
informer.Filter{
|
sqltypes.Filter{
|
||||||
Field: []string{"metadata", "annotations", "somekey"},
|
Field: []string{"metadata", "annotations", "somekey"},
|
||||||
Matches: []string{"valueNotRepresented"},
|
Matches: []string{"valueNotRepresented"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@ -278,7 +278,7 @@ func (i *IntegrationSuite) TestSQLCacheFilters() {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
test := test
|
test := test
|
||||||
i.Run(test.name, func() {
|
i.Run(test.name, func() {
|
||||||
options := informer.ListOptions{
|
options := sqltypes.ListOptions{
|
||||||
Filters: test.filters,
|
Filters: test.filters,
|
||||||
}
|
}
|
||||||
partitions := []partition.Partition{defaultPartition}
|
partitions := []partition.Partition{defaultPartition}
|
||||||
@ -334,7 +334,7 @@ func (i *IntegrationSuite) waitForCacheReady(readyResourceNames []string, namesp
|
|||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
return wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
|
return wait.PollUntilContextCancel(ctx, time.Millisecond*100, true, func(ctx context.Context) (done bool, err error) {
|
||||||
var options informer.ListOptions
|
var options sqltypes.ListOptions
|
||||||
partitions := []partition.Partition{defaultPartition}
|
partitions := []partition.Partition{defaultPartition}
|
||||||
cacheCtx, cacheCancel := context.WithTimeout(ctx, time.Second*5)
|
cacheCtx, cacheCancel := context.WithTimeout(ctx, time.Second*5)
|
||||||
defer cacheCancel()
|
defer cacheCancel()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package informer
|
package sqltypes
|
||||||
|
|
||||||
type Op string
|
type Op string
|
||||||
|
|
||||||
@ -35,8 +35,8 @@ type ListOptions struct {
|
|||||||
// Filter represents a field to filter by.
|
// Filter represents a field to filter by.
|
||||||
// A subfield in an object is represented in a request query using . notation, e.g. 'metadata.name'.
|
// A subfield in an object is represented in a request query using . notation, e.g. 'metadata.name'.
|
||||||
// The subfield is internally represented as a slice, e.g. [metadata, name].
|
// The subfield is internally represented as a slice, e.g. [metadata, name].
|
||||||
// Complex subfields need to be expressed with square brackets, as in `metadata.labels[zombo.com/moose]`,
|
// Complex subfields need to be expressed with square brackets, as in `metadata.labels[example.com/moose]`,
|
||||||
// but are mapped to the string slice ["metadata", "labels", "zombo.com/moose"]
|
// but are mapped to the string slice ["metadata", "labels", "example.com/moose"]
|
||||||
//
|
//
|
||||||
// If more than one value is given for the `Match` field, we do an "IN (<values>)" test
|
// If more than one value is given for the `Match` field, we do an "IN (<values>)" test
|
||||||
type Filter struct {
|
type Filter struct {
|
||||||
@ -61,8 +61,18 @@ type Sort struct {
|
|||||||
Orders []SortOrder
|
Orders []SortOrder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SortList struct {
|
||||||
|
SortDirectives []Sort
|
||||||
|
}
|
||||||
|
|
||||||
// Pagination represents how to return paginated results.
|
// Pagination represents how to return paginated results.
|
||||||
type Pagination struct {
|
type Pagination struct {
|
||||||
PageSize int
|
PageSize int
|
||||||
Page int
|
Page int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewSortList() *SortList {
|
||||||
|
return &SortList{
|
||||||
|
SortDirectives: []Sort{},
|
||||||
|
}
|
||||||
|
}
|
@ -10,8 +10,8 @@ import (
|
|||||||
|
|
||||||
"github.com/rancher/apiserver/pkg/apierror"
|
"github.com/rancher/apiserver/pkg/apierror"
|
||||||
"github.com/rancher/apiserver/pkg/types"
|
"github.com/rancher/apiserver/pkg/types"
|
||||||
"github.com/rancher/steve/pkg/sqlcache/informer"
|
|
||||||
"github.com/rancher/steve/pkg/sqlcache/partition"
|
"github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
"github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
"github.com/rancher/steve/pkg/stores/queryhelper"
|
"github.com/rancher/steve/pkg/stores/queryhelper"
|
||||||
"github.com/rancher/steve/pkg/stores/sqlpartition/queryparser"
|
"github.com/rancher/steve/pkg/stores/sqlpartition/queryparser"
|
||||||
"github.com/rancher/steve/pkg/stores/sqlpartition/selection"
|
"github.com/rancher/steve/pkg/stores/sqlpartition/selection"
|
||||||
@ -36,27 +36,27 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var endsWithBracket = regexp.MustCompile(`^(.+)\[(.+)]$`)
|
var endsWithBracket = regexp.MustCompile(`^(.+)\[(.+)]$`)
|
||||||
var mapK8sOpToRancherOp = map[selection.Operator]informer.Op{
|
var mapK8sOpToRancherOp = map[selection.Operator]sqltypes.Op{
|
||||||
selection.Equals: informer.Eq,
|
selection.Equals: sqltypes.Eq,
|
||||||
selection.DoubleEquals: informer.Eq,
|
selection.DoubleEquals: sqltypes.Eq,
|
||||||
selection.PartialEquals: informer.Eq,
|
selection.PartialEquals: sqltypes.Eq,
|
||||||
selection.NotEquals: informer.NotEq,
|
selection.NotEquals: sqltypes.NotEq,
|
||||||
selection.NotPartialEquals: informer.NotEq,
|
selection.NotPartialEquals: sqltypes.NotEq,
|
||||||
selection.In: informer.In,
|
selection.In: sqltypes.In,
|
||||||
selection.NotIn: informer.NotIn,
|
selection.NotIn: sqltypes.NotIn,
|
||||||
selection.Exists: informer.Exists,
|
selection.Exists: sqltypes.Exists,
|
||||||
selection.DoesNotExist: informer.NotExists,
|
selection.DoesNotExist: sqltypes.NotExists,
|
||||||
selection.LessThan: informer.Lt,
|
selection.LessThan: sqltypes.Lt,
|
||||||
selection.GreaterThan: informer.Gt,
|
selection.GreaterThan: sqltypes.Gt,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListOptions represents the query parameters that may be included in a list request.
|
// ListOptions represents the query parameters that may be included in a list request.
|
||||||
type ListOptions struct {
|
type ListOptions struct {
|
||||||
ChunkSize int
|
ChunkSize int
|
||||||
Resume string
|
Resume string
|
||||||
Filters []informer.OrFilter
|
Filters []sqltypes.OrFilter
|
||||||
Sort informer.Sort
|
Sort sqltypes.Sort
|
||||||
Pagination informer.Pagination
|
Pagination sqltypes.Pagination
|
||||||
}
|
}
|
||||||
|
|
||||||
type Cache interface {
|
type Cache interface {
|
||||||
@ -66,10 +66,10 @@ type Cache interface {
|
|||||||
// - the total number of resources (returned list might be a subset depending on pagination options in lo)
|
// - the total number of resources (returned list might be a subset depending on pagination options in lo)
|
||||||
// - a continue token, if there are more pages after the returned one
|
// - a continue token, if there are more pages after the returned one
|
||||||
// - an error instead of all of the above if anything went wrong
|
// - an error instead of all of the above if anything went wrong
|
||||||
ListByOptions(ctx context.Context, lo informer.ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error)
|
ListByOptions(ctx context.Context, lo sqltypes.ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func k8sOpToRancherOp(k8sOp selection.Operator) (informer.Op, bool, error) {
|
func k8sOpToRancherOp(k8sOp selection.Operator) (sqltypes.Op, bool, error) {
|
||||||
v, ok := mapK8sOpToRancherOp[k8sOp]
|
v, ok := mapK8sOpToRancherOp[k8sOp]
|
||||||
if ok {
|
if ok {
|
||||||
return v, k8sOp == selection.PartialEquals || k8sOp == selection.NotPartialEquals, nil
|
return v, k8sOp == selection.PartialEquals || k8sOp == selection.NotPartialEquals, nil
|
||||||
@ -77,11 +77,11 @@ func k8sOpToRancherOp(k8sOp selection.Operator) (informer.Op, bool, error) {
|
|||||||
return "", false, fmt.Errorf("unknown k8sOp: %s", k8sOp)
|
return "", false, fmt.Errorf("unknown k8sOp: %s", k8sOp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func k8sRequirementToOrFilter(requirement queryparser.Requirement) (informer.Filter, error) {
|
func k8sRequirementToOrFilter(requirement queryparser.Requirement) (sqltypes.Filter, error) {
|
||||||
values := requirement.Values()
|
values := requirement.Values()
|
||||||
queryFields := splitQuery(requirement.Key())
|
queryFields := splitQuery(requirement.Key())
|
||||||
op, usePartialMatch, err := k8sOpToRancherOp(requirement.Operator())
|
op, usePartialMatch, err := k8sOpToRancherOp(requirement.Operator())
|
||||||
return informer.Filter{
|
return sqltypes.Filter{
|
||||||
Field: queryFields,
|
Field: queryFields,
|
||||||
Matches: values,
|
Matches: values,
|
||||||
Op: op,
|
Op: op,
|
||||||
@ -90,8 +90,8 @@ func k8sRequirementToOrFilter(requirement queryparser.Requirement) (informer.Fil
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ParseQuery parses the query params of a request and returns a ListOptions.
|
// ParseQuery parses the query params of a request and returns a ListOptions.
|
||||||
func ParseQuery(apiOp *types.APIRequest, namespaceCache Cache) (informer.ListOptions, error) {
|
func ParseQuery(apiOp *types.APIRequest, namespaceCache Cache) (sqltypes.ListOptions, error) {
|
||||||
opts := informer.ListOptions{}
|
opts := sqltypes.ListOptions{}
|
||||||
|
|
||||||
opts.ChunkSize = getLimit(apiOp)
|
opts.ChunkSize = getLimit(apiOp)
|
||||||
|
|
||||||
@ -100,13 +100,13 @@ func ParseQuery(apiOp *types.APIRequest, namespaceCache Cache) (informer.ListOpt
|
|||||||
opts.Resume = cont
|
opts.Resume = cont
|
||||||
|
|
||||||
filterParams := q[filterParam]
|
filterParams := q[filterParam]
|
||||||
filterOpts := []informer.OrFilter{}
|
filterOpts := []sqltypes.OrFilter{}
|
||||||
for _, filters := range filterParams {
|
for _, filters := range filterParams {
|
||||||
requirements, err := queryparser.ParseToRequirements(filters)
|
requirements, err := queryparser.ParseToRequirements(filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return informer.ListOptions{}, err
|
return sqltypes.ListOptions{}, err
|
||||||
}
|
}
|
||||||
orFilter := informer.OrFilter{}
|
orFilter := sqltypes.OrFilter{}
|
||||||
for _, requirement := range requirements {
|
for _, requirement := range requirements {
|
||||||
filter, err := k8sRequirementToOrFilter(requirement)
|
filter, err := k8sRequirementToOrFilter(requirement)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -118,16 +118,16 @@ func ParseQuery(apiOp *types.APIRequest, namespaceCache Cache) (informer.ListOpt
|
|||||||
}
|
}
|
||||||
opts.Filters = filterOpts
|
opts.Filters = filterOpts
|
||||||
|
|
||||||
sortOpts := informer.Sort{}
|
sortOpts := sqltypes.Sort{}
|
||||||
sortKeys := q.Get(sortParam)
|
sortKeys := q.Get(sortParam)
|
||||||
if sortKeys != "" {
|
if sortKeys != "" {
|
||||||
sortParts := strings.Split(sortKeys, ",")
|
sortParts := strings.Split(sortKeys, ",")
|
||||||
for _, sortPart := range sortParts {
|
for _, sortPart := range sortParts {
|
||||||
field := sortPart
|
field := sortPart
|
||||||
if len(field) > 0 {
|
if len(field) > 0 {
|
||||||
sortOrder := informer.ASC
|
sortOrder := sqltypes.ASC
|
||||||
if field[0] == '-' {
|
if field[0] == '-' {
|
||||||
sortOrder = informer.DESC
|
sortOrder = sqltypes.DESC
|
||||||
field = field[1:]
|
field = field[1:]
|
||||||
}
|
}
|
||||||
if len(field) > 0 {
|
if len(field) > 0 {
|
||||||
@ -140,7 +140,7 @@ func ParseQuery(apiOp *types.APIRequest, namespaceCache Cache) (informer.ListOpt
|
|||||||
opts.Sort = sortOpts
|
opts.Sort = sortOpts
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
pagination := informer.Pagination{}
|
pagination := sqltypes.Pagination{}
|
||||||
pagination.PageSize, err = strconv.Atoi(q.Get(pageSizeParam))
|
pagination.PageSize, err = strconv.Atoi(q.Get(pageSizeParam))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pagination.PageSize = 0
|
pagination.PageSize = 0
|
||||||
@ -151,12 +151,12 @@ func ParseQuery(apiOp *types.APIRequest, namespaceCache Cache) (informer.ListOpt
|
|||||||
}
|
}
|
||||||
opts.Pagination = pagination
|
opts.Pagination = pagination
|
||||||
|
|
||||||
op := informer.Eq
|
op := sqltypes.Eq
|
||||||
projectsOrNamespaces := q.Get(projectsOrNamespacesVar)
|
projectsOrNamespaces := q.Get(projectsOrNamespacesVar)
|
||||||
if projectsOrNamespaces == "" {
|
if projectsOrNamespaces == "" {
|
||||||
projectsOrNamespaces = q.Get(projectsOrNamespacesVar + notOp)
|
projectsOrNamespaces = q.Get(projectsOrNamespacesVar + notOp)
|
||||||
if projectsOrNamespaces != "" {
|
if projectsOrNamespaces != "" {
|
||||||
op = informer.NotEq
|
op = sqltypes.NotEq
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if projectsOrNamespaces != "" {
|
if projectsOrNamespaces != "" {
|
||||||
@ -167,12 +167,12 @@ func ParseQuery(apiOp *types.APIRequest, namespaceCache Cache) (informer.ListOpt
|
|||||||
if projOrNSFilters == nil {
|
if projOrNSFilters == nil {
|
||||||
return opts, apierror.NewAPIError(validation.NotFound, fmt.Sprintf("could not find any namespaces named [%s] or namespaces belonging to project named [%s]", projectsOrNamespaces, projectsOrNamespaces))
|
return opts, apierror.NewAPIError(validation.NotFound, fmt.Sprintf("could not find any namespaces named [%s] or namespaces belonging to project named [%s]", projectsOrNamespaces, projectsOrNamespaces))
|
||||||
}
|
}
|
||||||
if op == informer.NotEq {
|
if op == sqltypes.NotEq {
|
||||||
for _, filter := range projOrNSFilters {
|
for _, filter := range projOrNSFilters {
|
||||||
opts.Filters = append(opts.Filters, informer.OrFilter{Filters: []informer.Filter{filter}})
|
opts.Filters = append(opts.Filters, sqltypes.OrFilter{Filters: []sqltypes.Filter{filter}})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
opts.Filters = append(opts.Filters, informer.OrFilter{Filters: projOrNSFilters})
|
opts.Filters = append(opts.Filters, sqltypes.OrFilter{Filters: projOrNSFilters})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,22 +205,22 @@ func splitQuery(query string) []string {
|
|||||||
return strings.Split(query, ".")
|
return strings.Split(query, ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseNamespaceOrProjectFilters(ctx context.Context, projOrNS string, op informer.Op, namespaceInformer Cache) ([]informer.Filter, error) {
|
func parseNamespaceOrProjectFilters(ctx context.Context, projOrNS string, op sqltypes.Op, namespaceInformer Cache) ([]sqltypes.Filter, error) {
|
||||||
var filters []informer.Filter
|
var filters []sqltypes.Filter
|
||||||
for _, pn := range strings.Split(projOrNS, ",") {
|
for _, pn := range strings.Split(projOrNS, ",") {
|
||||||
uList, _, _, err := namespaceInformer.ListByOptions(ctx, informer.ListOptions{
|
uList, _, _, err := namespaceInformer.ListByOptions(ctx, sqltypes.ListOptions{
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "name"},
|
Field: []string{"metadata", "name"},
|
||||||
Matches: []string{pn},
|
Matches: []string{pn},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "field.cattle.io/projectId"},
|
Field: []string{"metadata", "labels", "field.cattle.io/projectId"},
|
||||||
Matches: []string{pn},
|
Matches: []string{pn},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -230,7 +230,7 @@ func parseNamespaceOrProjectFilters(ctx context.Context, projOrNS string, op inf
|
|||||||
return filters, err
|
return filters, err
|
||||||
}
|
}
|
||||||
for _, item := range uList.Items {
|
for _, item := range uList.Items {
|
||||||
filters = append(filters, informer.Filter{
|
filters = append(filters, sqltypes.Filter{
|
||||||
Field: []string{"metadata", "namespace"},
|
Field: []string{"metadata", "namespace"},
|
||||||
Matches: []string{item.GetName()},
|
Matches: []string{item.GetName()},
|
||||||
Op: op,
|
Op: op,
|
||||||
|
@ -8,8 +8,8 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/rancher/apiserver/pkg/types"
|
"github.com/rancher/apiserver/pkg/types"
|
||||||
"github.com/rancher/steve/pkg/sqlcache/informer"
|
|
||||||
"github.com/rancher/steve/pkg/sqlcache/partition"
|
"github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
"github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"go.uber.org/mock/gomock"
|
"go.uber.org/mock/gomock"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
@ -23,7 +23,7 @@ func TestParseQuery(t *testing.T) {
|
|||||||
setupNSCache func() Cache
|
setupNSCache func() Cache
|
||||||
nsc Cache
|
nsc Cache
|
||||||
req *types.APIRequest
|
req *types.APIRequest
|
||||||
expectedLO informer.ListOptions
|
expectedLO sqltypes.ListOptions
|
||||||
errExpected bool
|
errExpected bool
|
||||||
errorText string
|
errorText string
|
||||||
}
|
}
|
||||||
@ -35,10 +35,10 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: ""},
|
URL: &url.URL{RawQuery: ""},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -51,21 +51,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "projectsornamespaces=somethin"},
|
URL: &url.URL{RawQuery: "projectsornamespaces=somethin"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "namespace"},
|
Field: []string{"metadata", "namespace"},
|
||||||
Matches: []string{"ns1"},
|
Matches: []string{"ns1"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -82,19 +82,19 @@ func TestParseQuery(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
nsc := NewMockCache(gomock.NewController(t))
|
nsc := NewMockCache(gomock.NewController(t))
|
||||||
nsc.EXPECT().ListByOptions(context.Background(), informer.ListOptions{
|
nsc.EXPECT().ListByOptions(context.Background(), sqltypes.ListOptions{
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "name"},
|
Field: []string{"metadata", "name"},
|
||||||
Matches: []string{"somethin"},
|
Matches: []string{"somethin"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "field.cattle.io/projectId"},
|
Field: []string{"metadata", "labels", "field.cattle.io/projectId"},
|
||||||
Matches: []string{"somethin"},
|
Matches: []string{"somethin"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -111,40 +111,40 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "projectsornamespaces=somethin"},
|
URL: &url.URL{RawQuery: "projectsornamespaces=somethin"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "namespace"},
|
Field: []string{"metadata", "namespace"},
|
||||||
Matches: []string{"ns1"},
|
Matches: []string{"ns1"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
errExpected: true,
|
errExpected: true,
|
||||||
setupNSCache: func() Cache {
|
setupNSCache: func() Cache {
|
||||||
nsi := NewMockCache(gomock.NewController(t))
|
nsi := NewMockCache(gomock.NewController(t))
|
||||||
nsi.EXPECT().ListByOptions(context.Background(), informer.ListOptions{
|
nsi.EXPECT().ListByOptions(context.Background(), sqltypes.ListOptions{
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "name"},
|
Field: []string{"metadata", "name"},
|
||||||
Matches: []string{"somethin"},
|
Matches: []string{"somethin"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "field.cattle.io/projectId"},
|
Field: []string{"metadata", "labels", "field.cattle.io/projectId"},
|
||||||
Matches: []string{"somethin"},
|
Matches: []string{"somethin"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -161,21 +161,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "projectsornamespaces=somethin"},
|
URL: &url.URL{RawQuery: "projectsornamespaces=somethin"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "namespace"},
|
Field: []string{"metadata", "namespace"},
|
||||||
Matches: []string{"ns1"},
|
Matches: []string{"ns1"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -185,19 +185,19 @@ func TestParseQuery(t *testing.T) {
|
|||||||
Items: []unstructured.Unstructured{},
|
Items: []unstructured.Unstructured{},
|
||||||
}
|
}
|
||||||
nsi := NewMockCache(gomock.NewController(t))
|
nsi := NewMockCache(gomock.NewController(t))
|
||||||
nsi.EXPECT().ListByOptions(context.Background(), informer.ListOptions{
|
nsi.EXPECT().ListByOptions(context.Background(), sqltypes.ListOptions{
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "name"},
|
Field: []string{"metadata", "name"},
|
||||||
Matches: []string{"somethin"},
|
Matches: []string{"somethin"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "field.cattle.io/projectId"},
|
Field: []string{"metadata", "labels", "field.cattle.io/projectId"},
|
||||||
Matches: []string{"somethin"},
|
Matches: []string{"somethin"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -213,21 +213,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a~c"},
|
URL: &url.URL{RawQuery: "filter=a~c"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a"},
|
Field: []string{"a"},
|
||||||
Matches: []string{"c"},
|
Matches: []string{"c"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -239,21 +239,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a=c"},
|
URL: &url.URL{RawQuery: "filter=a=c"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a"},
|
Field: []string{"a"},
|
||||||
Matches: []string{"c"},
|
Matches: []string{"c"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -274,21 +274,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=metadata.labels[grover.example.com/fish]~heads"},
|
URL: &url.URL{RawQuery: "filter=metadata.labels[grover.example.com/fish]~heads"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "grover.example.com/fish"},
|
Field: []string{"metadata", "labels", "grover.example.com/fish"},
|
||||||
Matches: []string{"heads"},
|
Matches: []string{"heads"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -300,21 +300,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=metadata.annotations[chumley.example.com/fish]=seals"},
|
URL: &url.URL{RawQuery: "filter=metadata.annotations[chumley.example.com/fish]=seals"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "annotations", "chumley.example.com/fish"},
|
Field: []string{"metadata", "annotations", "chumley.example.com/fish"},
|
||||||
Matches: []string{"seals"},
|
Matches: []string{"seals"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -326,20 +326,20 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=metadata.fields[3]<5"},
|
URL: &url.URL{RawQuery: "filter=metadata.fields[3]<5"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "fields", "3"},
|
Field: []string{"metadata", "fields", "3"},
|
||||||
Matches: []string{"5"},
|
Matches: []string{"5"},
|
||||||
Op: informer.Lt,
|
Op: sqltypes.Lt,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -351,21 +351,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=metadata.labels[grover.example.com/fish]~heads"},
|
URL: &url.URL{RawQuery: "filter=metadata.labels[grover.example.com/fish]~heads"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "grover.example.com/fish"},
|
Field: []string{"metadata", "labels", "grover.example.com/fish"},
|
||||||
Matches: []string{"heads"},
|
Matches: []string{"heads"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -377,31 +377,31 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a=c&filter=b=d"},
|
URL: &url.URL{RawQuery: "filter=a=c&filter=b=d"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a"},
|
Field: []string{"a"},
|
||||||
Matches: []string{"c"},
|
Matches: []string{"c"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"b"},
|
Field: []string{"b"},
|
||||||
Matches: []string{"d"},
|
Matches: []string{"d"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -413,31 +413,31 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a=c&filter=b=d"},
|
URL: &url.URL{RawQuery: "filter=a=c&filter=b=d"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a"},
|
Field: []string{"a"},
|
||||||
Matches: []string{"c"},
|
Matches: []string{"c"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"b"},
|
Field: []string{"b"},
|
||||||
Matches: []string{"d"},
|
Matches: []string{"d"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -449,27 +449,27 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=beer=pabst,metadata.labels[beer2.io/ale] ~schlitz"},
|
URL: &url.URL{RawQuery: "filter=beer=pabst,metadata.labels[beer2.io/ale] ~schlitz"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"beer"},
|
Field: []string{"beer"},
|
||||||
Matches: []string{"pabst"},
|
Matches: []string{"pabst"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "beer2.io/ale"},
|
Field: []string{"metadata", "labels", "beer2.io/ale"},
|
||||||
Matches: []string{"schlitz"},
|
Matches: []string{"schlitz"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -481,27 +481,27 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=beer=natty-bo,metadata.labels.beer3~rainier"},
|
URL: &url.URL{RawQuery: "filter=beer=natty-bo,metadata.labels.beer3~rainier"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"beer"},
|
Field: []string{"beer"},
|
||||||
Matches: []string{"natty-bo"},
|
Matches: []string{"natty-bo"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "beer3"},
|
Field: []string{"metadata", "labels", "beer3"},
|
||||||
Matches: []string{"rainier"},
|
Matches: []string{"rainier"},
|
||||||
Op: informer.Eq,
|
Op: sqltypes.Eq,
|
||||||
Partial: true,
|
Partial: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -513,27 +513,27 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a1In in (x1),a2In IN (x2)"},
|
URL: &url.URL{RawQuery: "filter=a1In in (x1),a2In IN (x2)"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a1In"},
|
Field: []string{"a1In"},
|
||||||
Matches: []string{"x1"},
|
Matches: []string{"x1"},
|
||||||
Op: informer.In,
|
Op: sqltypes.In,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"a2In"},
|
Field: []string{"a2In"},
|
||||||
Matches: []string{"x2"},
|
Matches: []string{"x2"},
|
||||||
Op: informer.In,
|
Op: sqltypes.In,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -545,21 +545,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a2In in (x2a, x2b)"},
|
URL: &url.URL{RawQuery: "filter=a2In in (x2a, x2b)"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a2In"},
|
Field: []string{"a2In"},
|
||||||
Matches: []string{"x2a", "x2b"},
|
Matches: []string{"x2a", "x2b"},
|
||||||
Op: informer.In,
|
Op: sqltypes.In,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -571,27 +571,27 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a1NotIn notin (x1),a2NotIn NOTIN (x2)"},
|
URL: &url.URL{RawQuery: "filter=a1NotIn notin (x1),a2NotIn NOTIN (x2)"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a1NotIn"},
|
Field: []string{"a1NotIn"},
|
||||||
Matches: []string{"x1"},
|
Matches: []string{"x1"},
|
||||||
Op: informer.NotIn,
|
Op: sqltypes.NotIn,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"a2NotIn"},
|
Field: []string{"a2NotIn"},
|
||||||
Matches: []string{"x2"},
|
Matches: []string{"x2"},
|
||||||
Op: informer.NotIn,
|
Op: sqltypes.NotIn,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -603,21 +603,21 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a3NotIn in (x3a, x3b)"},
|
URL: &url.URL{RawQuery: "filter=a3NotIn in (x3a, x3b)"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a3NotIn"},
|
Field: []string{"a3NotIn"},
|
||||||
Matches: []string{"x3a", "x3b"},
|
Matches: []string{"x3a", "x3b"},
|
||||||
Op: informer.In,
|
Op: sqltypes.In,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -629,27 +629,27 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a4In iN (x4a),a4NotIn nOtIn (x4b)"},
|
URL: &url.URL{RawQuery: "filter=a4In iN (x4a),a4NotIn nOtIn (x4b)"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a4In"},
|
Field: []string{"a4In"},
|
||||||
Matches: []string{"x4a"},
|
Matches: []string{"x4a"},
|
||||||
Op: informer.In,
|
Op: sqltypes.In,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"a4NotIn"},
|
Field: []string{"a4NotIn"},
|
||||||
Matches: []string{"x4b"},
|
Matches: []string{"x4b"},
|
||||||
Op: informer.NotIn,
|
Op: sqltypes.NotIn,
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -671,33 +671,33 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=metadata.labels.a5In1,!metadata.labels.a5In2, ! metadata.labels.a5In3"},
|
URL: &url.URL{RawQuery: "filter=metadata.labels.a5In1,!metadata.labels.a5In2, ! metadata.labels.a5In3"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "a5In1"},
|
Field: []string{"metadata", "labels", "a5In1"},
|
||||||
Op: informer.Exists,
|
Op: sqltypes.Exists,
|
||||||
Matches: []string{},
|
Matches: []string{},
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "a5In2"},
|
Field: []string{"metadata", "labels", "a5In2"},
|
||||||
Op: informer.NotExists,
|
Op: sqltypes.NotExists,
|
||||||
Matches: []string{},
|
Matches: []string{},
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"metadata", "labels", "a5In3"},
|
Field: []string{"metadata", "labels", "a5In3"},
|
||||||
Op: informer.NotExists,
|
Op: sqltypes.NotExists,
|
||||||
Matches: []string{},
|
Matches: []string{},
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -709,27 +709,27 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "filter=a<1,b>2"},
|
URL: &url.URL{RawQuery: "filter=a<1,b>2"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: []informer.OrFilter{
|
Filters: []sqltypes.OrFilter{
|
||||||
{
|
{
|
||||||
Filters: []informer.Filter{
|
Filters: []sqltypes.Filter{
|
||||||
{
|
{
|
||||||
Field: []string{"a"},
|
Field: []string{"a"},
|
||||||
Op: informer.Lt,
|
Op: sqltypes.Lt,
|
||||||
Matches: []string{"1"},
|
Matches: []string{"1"},
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Field: []string{"b"},
|
Field: []string{"b"},
|
||||||
Op: informer.Gt,
|
Op: sqltypes.Gt,
|
||||||
Matches: []string{"2"},
|
Matches: []string{"2"},
|
||||||
Partial: false,
|
Partial: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -742,15 +742,15 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "sort=metadata.name"},
|
URL: &url.URL{RawQuery: "sort=metadata.name"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Sort: informer.Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{
|
Fields: [][]string{
|
||||||
{"metadata", "name"}},
|
{"metadata", "name"}},
|
||||||
Orders: []informer.SortOrder{informer.ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.ASC},
|
||||||
},
|
},
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -763,14 +763,14 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "sort=-metadata.name"},
|
URL: &url.URL{RawQuery: "sort=-metadata.name"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Sort: informer.Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "name"}},
|
Fields: [][]string{{"metadata", "name"}},
|
||||||
Orders: []informer.SortOrder{informer.DESC},
|
Orders: []sqltypes.SortOrder{sqltypes.DESC},
|
||||||
},
|
},
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -783,20 +783,20 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "sort=-metadata.name,spec.something"},
|
URL: &url.URL{RawQuery: "sort=-metadata.name,spec.something"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Sort: informer.Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{
|
Fields: [][]string{
|
||||||
{"metadata", "name"},
|
{"metadata", "name"},
|
||||||
{"spec", "something"},
|
{"spec", "something"},
|
||||||
},
|
},
|
||||||
Orders: []informer.SortOrder{
|
Orders: []sqltypes.SortOrder{
|
||||||
informer.DESC,
|
sqltypes.DESC,
|
||||||
informer.ASC,
|
sqltypes.ASC,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -809,17 +809,17 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "sort=-metadata.labels[beef.cattle.io/snort],metadata.labels.steer,metadata.labels[bossie.cattle.io/moo],spec.something"},
|
URL: &url.URL{RawQuery: "sort=-metadata.labels[beef.cattle.io/snort],metadata.labels.steer,metadata.labels[bossie.cattle.io/moo],spec.something"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Sort: informer.Sort{
|
Sort: sqltypes.Sort{
|
||||||
Fields: [][]string{{"metadata", "labels", "beef.cattle.io/snort"},
|
Fields: [][]string{{"metadata", "labels", "beef.cattle.io/snort"},
|
||||||
{"metadata", "labels", "steer"},
|
{"metadata", "labels", "steer"},
|
||||||
{"metadata", "labels", "bossie.cattle.io/moo"},
|
{"metadata", "labels", "bossie.cattle.io/moo"},
|
||||||
{"spec", "something"}},
|
{"spec", "something"}},
|
||||||
Orders: []informer.SortOrder{informer.DESC, informer.ASC, informer.ASC, informer.ASC},
|
Orders: []sqltypes.SortOrder{sqltypes.DESC, sqltypes.ASC, sqltypes.ASC, sqltypes.ASC},
|
||||||
},
|
},
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -835,11 +835,11 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "continue=5"},
|
URL: &url.URL{RawQuery: "continue=5"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Resume: "5",
|
Resume: "5",
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -852,11 +852,11 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "continue=5"},
|
URL: &url.URL{RawQuery: "continue=5"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Resume: "5",
|
Resume: "5",
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -869,10 +869,10 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "limit=3"},
|
URL: &url.URL{RawQuery: "limit=3"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: 3,
|
ChunkSize: 3,
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -885,10 +885,10 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "page=3"},
|
URL: &url.URL{RawQuery: "page=3"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
Page: 3,
|
Page: 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -901,10 +901,10 @@ func TestParseQuery(t *testing.T) {
|
|||||||
URL: &url.URL{RawQuery: "pagesize=20"},
|
URL: &url.URL{RawQuery: "pagesize=20"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expectedLO: informer.ListOptions{
|
expectedLO: sqltypes.ListOptions{
|
||||||
ChunkSize: defaultLimit,
|
ChunkSize: defaultLimit,
|
||||||
Filters: make([]informer.OrFilter, 0),
|
Filters: make([]sqltypes.OrFilter, 0),
|
||||||
Pagination: informer.Pagination{
|
Pagination: sqltypes.Pagination{
|
||||||
PageSize: 20,
|
PageSize: 20,
|
||||||
Page: 1,
|
Page: 1,
|
||||||
},
|
},
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
context "context"
|
context "context"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
informer "github.com/rancher/steve/pkg/sqlcache/informer"
|
|
||||||
partition "github.com/rancher/steve/pkg/sqlcache/partition"
|
partition "github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
sqltypes "github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
gomock "go.uber.org/mock/gomock"
|
gomock "go.uber.org/mock/gomock"
|
||||||
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
@ -43,7 +43,7 @@ func (m *MockCache) EXPECT() *MockCacheMockRecorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListByOptions mocks base method.
|
// ListByOptions mocks base method.
|
||||||
func (m *MockCache) ListByOptions(arg0 context.Context, arg1 informer.ListOptions, arg2 []partition.Partition, arg3 string) (*unstructured.UnstructuredList, int, string, error) {
|
func (m *MockCache) ListByOptions(arg0 context.Context, arg1 sqltypes.ListOptions, arg2 []partition.Partition, arg3 string) (*unstructured.UnstructuredList, int, string, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "ListByOptions", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "ListByOptions", arg0, arg1, arg2, arg3)
|
||||||
ret0, _ := ret[0].(*unstructured.UnstructuredList)
|
ret0, _ := ret[0].(*unstructured.UnstructuredList)
|
||||||
|
@ -14,9 +14,9 @@ import (
|
|||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
types "github.com/rancher/apiserver/pkg/types"
|
types "github.com/rancher/apiserver/pkg/types"
|
||||||
informer "github.com/rancher/steve/pkg/sqlcache/informer"
|
|
||||||
factory "github.com/rancher/steve/pkg/sqlcache/informer/factory"
|
factory "github.com/rancher/steve/pkg/sqlcache/informer/factory"
|
||||||
partition "github.com/rancher/steve/pkg/sqlcache/partition"
|
partition "github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
sqltypes "github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
summary "github.com/rancher/wrangler/v3/pkg/summary"
|
summary "github.com/rancher/wrangler/v3/pkg/summary"
|
||||||
gomock "go.uber.org/mock/gomock"
|
gomock "go.uber.org/mock/gomock"
|
||||||
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
@ -51,7 +51,7 @@ func (m *MockCache) EXPECT() *MockCacheMockRecorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListByOptions mocks base method.
|
// ListByOptions mocks base method.
|
||||||
func (m *MockCache) ListByOptions(arg0 context.Context, arg1 informer.ListOptions, arg2 []partition.Partition, arg3 string) (*unstructured.UnstructuredList, int, string, error) {
|
func (m *MockCache) ListByOptions(arg0 context.Context, arg1 sqltypes.ListOptions, arg2 []partition.Partition, arg3 string) (*unstructured.UnstructuredList, int, string, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "ListByOptions", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "ListByOptions", arg0, arg1, arg2, arg3)
|
||||||
ret0, _ := ret[0].(*unstructured.UnstructuredList)
|
ret0, _ := ret[0].(*unstructured.UnstructuredList)
|
||||||
|
@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/rancher/steve/pkg/sqlcache/informer"
|
"github.com/rancher/steve/pkg/sqlcache/informer"
|
||||||
"github.com/rancher/steve/pkg/sqlcache/informer/factory"
|
"github.com/rancher/steve/pkg/sqlcache/informer/factory"
|
||||||
"github.com/rancher/steve/pkg/sqlcache/partition"
|
"github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
"github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
"github.com/rancher/wrangler/v3/pkg/data"
|
"github.com/rancher/wrangler/v3/pkg/data"
|
||||||
"github.com/rancher/wrangler/v3/pkg/schemas"
|
"github.com/rancher/wrangler/v3/pkg/schemas"
|
||||||
"github.com/rancher/wrangler/v3/pkg/schemas/validation"
|
"github.com/rancher/wrangler/v3/pkg/schemas/validation"
|
||||||
@ -216,7 +217,7 @@ type Cache interface {
|
|||||||
// - the total number of resources (returned list might be a subset depending on pagination options in lo)
|
// - the total number of resources (returned list might be a subset depending on pagination options in lo)
|
||||||
// - a continue token, if there are more pages after the returned one
|
// - a continue token, if there are more pages after the returned one
|
||||||
// - an error instead of all of the above if anything went wrong
|
// - an error instead of all of the above if anything went wrong
|
||||||
ListByOptions(ctx context.Context, lo informer.ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error)
|
ListByOptions(ctx context.Context, lo sqltypes.ListOptions, partitions []partition.Partition, namespace string) (*unstructured.UnstructuredList, int, string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WarningBuffer holds warnings that may be returned from the kubernetes api
|
// WarningBuffer holds warnings that may be returned from the kubernetes api
|
||||||
|
@ -13,8 +13,8 @@ import (
|
|||||||
context "context"
|
context "context"
|
||||||
reflect "reflect"
|
reflect "reflect"
|
||||||
|
|
||||||
informer "github.com/rancher/steve/pkg/sqlcache/informer"
|
|
||||||
partition "github.com/rancher/steve/pkg/sqlcache/partition"
|
partition "github.com/rancher/steve/pkg/sqlcache/partition"
|
||||||
|
sqltypes "github.com/rancher/steve/pkg/sqlcache/sqltypes"
|
||||||
gomock "go.uber.org/mock/gomock"
|
gomock "go.uber.org/mock/gomock"
|
||||||
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
unstructured "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
)
|
)
|
||||||
@ -43,7 +43,7 @@ func (m *MockByOptionsLister) EXPECT() *MockByOptionsListerMockRecorder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ListByOptions mocks base method.
|
// ListByOptions mocks base method.
|
||||||
func (m *MockByOptionsLister) ListByOptions(arg0 context.Context, arg1 informer.ListOptions, arg2 []partition.Partition, arg3 string) (*unstructured.UnstructuredList, int, string, error) {
|
func (m *MockByOptionsLister) ListByOptions(arg0 context.Context, arg1 sqltypes.ListOptions, arg2 []partition.Partition, arg3 string) (*unstructured.UnstructuredList, int, string, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "ListByOptions", arg0, arg1, arg2, arg3)
|
ret := m.ctrl.Call(m, "ListByOptions", arg0, arg1, arg2, arg3)
|
||||||
ret0, _ := ret[0].(*unstructured.UnstructuredList)
|
ret0, _ := ret[0].(*unstructured.UnstructuredList)
|
||||||
|
Loading…
Reference in New Issue
Block a user