diff --git a/connector-definition/configuration.yaml b/connector-definition/configuration.yaml index e287b31..a9301d9 100644 --- a/connector-definition/configuration.yaml +++ b/connector-definition/configuration.yaml @@ -22,3 +22,5 @@ concurrency: mutation: 1 runtime: maxDownloadSizeMBs: 20 +generator: + promptqlCompatible: false diff --git a/connector/collection/bucket.go b/connector/collection/bucket.go new file mode 100644 index 0000000..ca559f4 --- /dev/null +++ b/connector/collection/bucket.go @@ -0,0 +1,117 @@ +package collection + +import ( + "context" + + "github.com/hasura/ndc-sdk-go/schema" + "github.com/hasura/ndc-sdk-go/utils" + "github.com/hasura/ndc-storage/connector/storage" + "github.com/hasura/ndc-storage/connector/storage/common" +) + +// CollectionBucketExecutor evaluates and executes a storage bucket collection query. +type CollectionBucketExecutor struct { + Storage *storage.Manager + Request *schema.QueryRequest + Arguments map[string]any + Variables map[string]any + Concurrency int +} + +// Execute executes the query request to get list of storage buckets. +func (coe *CollectionBucketExecutor) Execute(ctx context.Context) (*schema.RowSet, error) { + if coe.Request.Query.Offset != nil && *coe.Request.Query.Offset < 0 { + return nil, schema.UnprocessableContentError("offset must be positive", nil) + } + + if coe.Request.Query.Limit != nil && *coe.Request.Query.Limit <= 0 { + return &schema.RowSet{ + Aggregates: schema.RowSetAggregates{}, + Rows: []map[string]any{}, + }, nil + } + + request, err := EvalBucketPredicate(nil, "", coe.Request.Query.Predicate, coe.Variables) + if err != nil { + return nil, schema.UnprocessableContentError(err.Error(), nil) + } + + if !request.IsValid { + // early returns zero rows + // the evaluated query always returns empty values + return &schema.RowSet{ + Aggregates: schema.RowSetAggregates{}, + Rows: []map[string]any{}, + }, nil + } + + request.evalQuerySelectionFields(coe.Request.Query.Fields) + + predicate := request.BucketPredicate.CheckPostPredicate + if !request.BucketPredicate.HasPostPredicate() { + predicate = nil + } + + options := &common.ListStorageBucketsOptions{ + Prefix: request.BucketPredicate.GetPrefix(), + Include: common.BucketIncludeOptions{ + Tags: request.Include.Tags, + Versioning: request.Include.Versions, + Lifecycle: request.Include.Lifecycle, + Encryption: request.Include.Encryption, + ObjectLock: request.IncludeObjectLock, + }, + NumThreads: coe.Concurrency, + } + + if after, err := utils.GetNullableString(coe.Arguments, argumentAfter); err != nil { + return nil, schema.UnprocessableContentError(err.Error(), nil) + } else if after != nil && *after != "" { + options.StartAfter = *after + } + + var offset, limit int + if coe.Request.Query.Offset != nil { + offset = *coe.Request.Query.Offset + } + + if coe.Request.Query.Limit != nil { + limit = *coe.Request.Query.Limit + maxResults := offset + limit + + options.MaxResults = &maxResults + } + + response, err := coe.Storage.ListBuckets(ctx, request.ClientID, options, predicate) + if err != nil { + return nil, err + } + + buckets := response.Buckets + + if offset > 0 { + if len(buckets) <= offset { + return &schema.RowSet{ + Aggregates: schema.RowSetAggregates{}, + Rows: []map[string]any{}, + }, nil + } + + buckets = buckets[offset:] + } + + rawResults := make([]map[string]any, len(buckets)) + for i, object := range buckets { + rawResults[i] = object.ToMap() + } + + result, err := utils.EvalObjectsWithColumnSelection(coe.Request.Query.Fields, rawResults) + if err != nil { + return nil, err + } + + return &schema.RowSet{ + Aggregates: schema.RowSetAggregates{}, + Rows: result, + }, nil +} diff --git a/connector/collection/object.go b/connector/collection/object.go new file mode 100644 index 0000000..df26876 --- /dev/null +++ b/connector/collection/object.go @@ -0,0 +1,116 @@ +package collection + +import ( + "context" + + "github.com/hasura/ndc-sdk-go/schema" + "github.com/hasura/ndc-sdk-go/utils" + "github.com/hasura/ndc-storage/connector/storage" + "github.com/hasura/ndc-storage/connector/storage/common" +) + +// CollectionObjectExecutor evaluates and executes a storage object collection query +type CollectionObjectExecutor struct { + Storage *storage.Manager + Request *schema.QueryRequest + Arguments map[string]any + Variables map[string]any + Concurrency int +} + +// Execute executes the query request to get list of storage objects. +func (coe *CollectionObjectExecutor) Execute(ctx context.Context) (*schema.RowSet, error) { + if coe.Request.Query.Offset != nil && *coe.Request.Query.Offset < 0 { + return nil, schema.UnprocessableContentError("offset must be positive", nil) + } + + if coe.Request.Query.Limit != nil && *coe.Request.Query.Limit <= 0 { + return &schema.RowSet{ + Aggregates: schema.RowSetAggregates{}, + Rows: []map[string]any{}, + }, nil + } + + request, err := EvalObjectPredicate(common.StorageBucketArguments{}, nil, coe.Request.Query.Predicate, coe.Variables) + if err != nil { + return nil, schema.UnprocessableContentError(err.Error(), nil) + } + + if !request.IsValid { + // early returns zero rows + // the evaluated query always returns empty values + return &schema.RowSet{ + Aggregates: schema.RowSetAggregates{}, + Rows: []map[string]any{}, + }, nil + } + + request.evalQuerySelectionFields(coe.Request.Query.Fields) + + options := &common.ListStorageObjectsOptions{ + Prefix: request.ObjectNamePredicate.GetPrefix(), + Include: request.Include, + NumThreads: coe.Concurrency, + } + + if hierarchy, err := utils.GetNullableBoolean(coe.Arguments, argumentHierarchy); err != nil { + return nil, schema.UnprocessableContentError(err.Error(), nil) + } else if hierarchy != nil { + options.Hierarchy = *hierarchy + } + + if after, err := utils.GetNullableString(coe.Arguments, argumentAfter); err != nil { + return nil, schema.UnprocessableContentError(err.Error(), nil) + } else if after != nil && *after != "" { + options.StartAfter = *after + } + + var offset, limit int + if coe.Request.Query.Offset != nil { + offset = *coe.Request.Query.Offset + } + + if coe.Request.Query.Limit != nil { + limit = *coe.Request.Query.Limit + options.MaxResults = offset + limit + } + + predicate := request.ObjectNamePredicate.CheckPostPredicate + + if !request.ObjectNamePredicate.HasPostPredicate() { + predicate = nil + } + + response, err := coe.Storage.ListObjects(ctx, request.GetBucketArguments(), options, predicate) + if err != nil { + return nil, err + } + + objects := response.Objects + + if offset > 0 { + if len(response.Objects) <= offset { + return &schema.RowSet{ + Aggregates: schema.RowSetAggregates{}, + Rows: []map[string]any{}, + }, nil + } + + objects = response.Objects[offset:] + } + + rawResults := make([]map[string]any, len(objects)) + for i, object := range objects { + rawResults[i] = object.ToMap() + } + + result, err := utils.EvalObjectsWithColumnSelection(coe.Request.Query.Fields, rawResults) + if err != nil { + return nil, err + } + + return &schema.RowSet{ + Aggregates: schema.RowSetAggregates{}, + Rows: result, + }, nil +} diff --git a/connector/functions/internal/predicate.go b/connector/collection/predicate.go similarity index 85% rename from connector/functions/internal/predicate.go rename to connector/collection/predicate.go index 173af75..9a888c6 100644 --- a/connector/functions/internal/predicate.go +++ b/connector/collection/predicate.go @@ -1,4 +1,4 @@ -package internal +package collection import ( "errors" @@ -37,7 +37,7 @@ func EvalBucketPredicate(clientID *common.StorageClientID, prefix string, predic } if len(predicate) > 0 { - ok, err := result.evalQueryPredicate(predicate) + ok, err := result.evalQueryPredicate(predicate, true) if err != nil { return nil, err } @@ -75,7 +75,7 @@ func EvalObjectPredicate(bucketInfo common.StorageBucketArguments, preOperator * } if len(predicate) > 0 { - ok, err := result.evalQueryPredicate(predicate) + ok, err := result.evalQueryPredicate(predicate, false) if err != nil { return nil, err } @@ -100,7 +100,7 @@ func (pe PredicateEvaluator) GetBucketArguments() common.StorageBucketArguments return result } -func (pe *PredicateEvaluator) EvalSelection(selection schema.NestedField) error { //nolint:gocognit +func (pe *PredicateEvaluator) EvalSelection(selection schema.NestedField) error { if len(selection) == 0 { return nil } @@ -123,59 +123,63 @@ func (pe *PredicateEvaluator) EvalSelection(selection schema.NestedField) error return pe.EvalSelection(objectsColumn.Fields) } - for _, key := range []string{"metadata", "rawMetadata"} { - if _, ok := expr.Fields[key]; ok { - pe.Include.Metadata = true + pe.evalQuerySelectionFields(expr.Fields) + } - break - } - } + return nil +} - for _, key := range checksumColumnNames { - if _, ok := expr.Fields[key]; ok { - pe.Include.Checksum = true +func (pe *PredicateEvaluator) evalQuerySelectionFields(fields map[string]schema.Field) { + for _, key := range []string{"metadata", "rawMetadata"} { + if _, ok := fields[key]; ok { + pe.Include.Metadata = true - break - } + break } + } - if _, ok := expr.Fields["tags"]; ok { - pe.Include.Tags = true - } + for _, key := range checksumColumnNames { + if _, ok := fields[key]; ok { + pe.Include.Checksum = true - if _, ok := expr.Fields["copy"]; ok { - pe.Include.Copy = true + break } + } - for _, key := range []string{"versionId", "versioning"} { - if _, ok := expr.Fields[key]; ok { - pe.Include.Versions = true + if _, ok := fields["tags"]; ok { + pe.Include.Tags = true + } - break - } - } + if _, ok := fields["copy"]; ok { + pe.Include.Copy = true + } - if _, legalHoldExists := expr.Fields["legalHold"]; legalHoldExists { - pe.Include.LegalHold = true - } + for _, key := range []string{"versionId", "versioning"} { + if _, ok := fields[key]; ok { + pe.Include.Versions = true - if _, ok := expr.Fields["lifecycle"]; ok { - pe.Include.Lifecycle = true + break } + } - if _, ok := expr.Fields["encryption"]; ok { - pe.Include.Encryption = true - } + if _, legalHoldExists := fields["legalHold"]; legalHoldExists { + pe.Include.LegalHold = true + } - if _, ok := expr.Fields["objectLock"]; ok { - pe.IncludeObjectLock = true - } + if _, ok := fields["lifecycle"]; ok { + pe.Include.Lifecycle = true } - return nil + if _, ok := fields["encryption"]; ok { + pe.Include.Encryption = true + } + + if _, ok := fields["objectLock"]; ok { + pe.IncludeObjectLock = true + } } -func (pe *PredicateEvaluator) evalQueryPredicate(expression schema.Expression) (bool, error) { +func (pe *PredicateEvaluator) evalQueryPredicate(expression schema.Expression, forBucket bool) (bool, error) { exprT, err := expression.InterfaceT() if err != nil { return false, err @@ -184,7 +188,7 @@ func (pe *PredicateEvaluator) evalQueryPredicate(expression schema.Expression) ( switch expr := exprT.(type) { case *schema.ExpressionAnd: for _, nestedExpr := range expr.Expressions { - ok, err := pe.evalQueryPredicate(nestedExpr) + ok, err := pe.evalQueryPredicate(nestedExpr, forBucket) if err != nil { return false, err } @@ -219,10 +223,18 @@ func (pe *PredicateEvaluator) evalQueryPredicate(expression schema.Expression) ( } return ok, nil - case StorageObjectColumnObject: - ok, err := pe.evalStringFilter(&pe.ObjectNamePredicate, expr) + case StorageObjectColumnName: + var ok bool + var err error + + if forBucket { + ok, err = pe.evalStringFilter(&pe.BucketPredicate, expr) + } else { + ok, err = pe.evalStringFilter(&pe.ObjectNamePredicate, expr) + } + if err != nil { - return false, fmt.Errorf("%s: %w", StorageObjectColumnObject, err) + return false, fmt.Errorf("%s: %w", StorageObjectColumnName, err) } return ok, nil diff --git a/connector/functions/internal/types.go b/connector/collection/types.go similarity index 69% rename from connector/functions/internal/types.go rename to connector/collection/types.go index cb9d7de..a9652ad 100644 --- a/connector/functions/internal/types.go +++ b/connector/collection/types.go @@ -1,14 +1,18 @@ -package internal +package collection import ( "github.com/hasura/ndc-sdk-go/schema" + "github.com/hasura/ndc-sdk-go/utils" ) const ( + CollectionStorageObjects = "storageObjects" + CollectionStorageBuckets = "storageBuckets" StorageObjectName = "StorageObject" + StorageBucketName = "StorageBucket" StorageObjectColumnClientID = "clientId" - StorageObjectColumnObject = "object" StorageObjectColumnBucket = "bucket" + StorageObjectColumnName = "name" ) const ( @@ -26,6 +30,11 @@ const ( ScalarStringFilter = "StorageStringFilter" ) +const ( + argumentAfter = "after" + argumentHierarchy = "hierarchy" +) + var checksumColumnNames = []string{"checksumCrc32", "checksumCrc32C", "checksumCrc64Nvme", "checksumSha1", "checksumSha256"} // StringComparisonOperator represents the explicit comparison expression for string columns. @@ -37,14 +46,42 @@ type StringComparisonOperator struct { // GetConnectorSchema returns connector schema for object collections. func GetConnectorSchema(clientIDs []string) *schema.SchemaResponse { return &schema.SchemaResponse{ - Collections: []schema.CollectionInfo{}, + Collections: []schema.CollectionInfo{ + { + Name: CollectionStorageObjects, + Description: utils.ToPtr("List storage objects"), + Type: StorageObjectName, + Arguments: schema.CollectionInfoArguments{ + argumentAfter: { + Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), + }, + argumentHierarchy: { + Type: schema.NewNullableType(schema.NewNamedType("Boolean")).Encode(), + }, + }, + UniquenessConstraints: schema.CollectionInfoUniquenessConstraints{}, + ForeignKeys: schema.CollectionInfoForeignKeys{}, + }, + { + Name: CollectionStorageBuckets, + Description: utils.ToPtr("List storage buckets"), + Type: StorageBucketName, + Arguments: schema.CollectionInfoArguments{ + argumentAfter: { + Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), + }, + }, + UniquenessConstraints: schema.CollectionInfoUniquenessConstraints{}, + ForeignKeys: schema.CollectionInfoForeignKeys{}, + }, + }, ObjectTypes: schema.SchemaResponseObjectTypes{ "StorageBucketFilter": schema.ObjectType{ Fields: schema.ObjectTypeFields{ StorageObjectColumnClientID: schema.ObjectField{ Type: schema.NewNamedType(ScalarStorageClientID).Encode(), }, - StorageObjectColumnBucket: schema.ObjectField{ + StorageObjectColumnName: schema.ObjectField{ Type: schema.NewNamedType(ScalarStringFilter).Encode(), }, }, @@ -57,7 +94,7 @@ func GetConnectorSchema(clientIDs []string) *schema.SchemaResponse { StorageObjectColumnBucket: schema.ObjectField{ Type: schema.NewNamedType(ScalarBucketName).Encode(), }, - StorageObjectColumnObject: schema.ObjectField{ + StorageObjectColumnName: schema.ObjectField{ Type: schema.NewNamedType(ScalarStringFilter).Encode(), }, }, diff --git a/connector/functions/internal/utils.go b/connector/collection/utils.go similarity index 98% rename from connector/functions/internal/utils.go rename to connector/collection/utils.go index 76c06cc..6baf20e 100644 --- a/connector/functions/internal/utils.go +++ b/connector/collection/utils.go @@ -1,4 +1,4 @@ -package internal +package collection import ( "fmt" diff --git a/connector/connector.go b/connector/connector.go index 76cdca5..f43590e 100644 --- a/connector/connector.go +++ b/connector/connector.go @@ -7,10 +7,12 @@ import ( "log/slog" "os" "path/filepath" + "slices" "github.com/hasura/ndc-sdk-go/connector" "github.com/hasura/ndc-sdk-go/schema" "github.com/hasura/ndc-sdk-go/utils" + "github.com/hasura/ndc-storage/connector/collection" "github.com/hasura/ndc-storage/connector/functions" "github.com/hasura/ndc-storage/connector/storage" "github.com/hasura/ndc-storage/connector/types" @@ -44,8 +46,7 @@ func (c *Connector) ParseConfiguration(ctx context.Context, configurationDir str Version: "0.1.6", Capabilities: schema.Capabilities{ Query: schema.QueryCapabilities{ - Variables: schema.LeafCapability{}, - NestedFields: schema.NestedFieldCapabilities{}, + Variables: schema.LeafCapability{}, }, Mutation: schema.MutationCapabilities{}, }, @@ -77,11 +78,13 @@ func (c *Connector) TryInitState(ctx context.Context, configuration *types.Confi return nil, err } - connectorSchema, errs := utils.MergeSchemas(GetConnectorSchema(), functions.GetBaseConnectorSchema(manager.GetClientIDs())) + connectorSchema, errs := utils.MergeSchemas(GetConnectorSchema(), collection.GetConnectorSchema(manager.GetClientIDs())) for _, err := range errs { slog.Debug(err.Error()) } + c.evalSchema(connectorSchema) + schemaBytes, err := json.Marshal(connectorSchema) if err != nil { return nil, fmt.Errorf("failed to encode schema: %w", err) @@ -115,3 +118,48 @@ func (c *Connector) GetCapabilities(configuration *types.Configuration) schema.C func (c *Connector) GetSchema(ctx context.Context, configuration *types.Configuration, _ *types.State) (schema.SchemaResponseMarshaler, error) { return c.rawSchema, nil } + +func (c *Connector) evalSchema(connectorSchema *schema.SchemaResponse) { + // override field types of the StorageObject object + objectClientID := connectorSchema.ObjectTypes[collection.StorageObjectName].Fields[collection.StorageObjectColumnClientID] + objectClientID.Type = schema.NewNamedType(collection.ScalarStorageClientID).Encode() + connectorSchema.ObjectTypes[collection.StorageObjectName].Fields[collection.StorageObjectColumnClientID] = objectClientID + + objectBucketField := connectorSchema.ObjectTypes[collection.StorageObjectName].Fields[collection.StorageObjectColumnBucket] + objectBucketField.Type = schema.NewNamedType(collection.ScalarBucketName).Encode() + connectorSchema.ObjectTypes[collection.StorageObjectName].Fields[collection.StorageObjectColumnBucket] = objectBucketField + + objectNameField := connectorSchema.ObjectTypes[collection.StorageObjectName].Fields[collection.StorageObjectColumnName] + objectNameField.Type = schema.NewNamedType(collection.ScalarStringFilter).Encode() + connectorSchema.ObjectTypes[collection.StorageObjectName].Fields[collection.StorageObjectColumnName] = objectNameField + + // override field types of the StorageBucket object + bucketClientID := connectorSchema.ObjectTypes[collection.StorageBucketName].Fields[collection.StorageObjectColumnClientID] + bucketClientID.Type = schema.NewNamedType(collection.ScalarStorageClientID).Encode() + connectorSchema.ObjectTypes[collection.StorageBucketName].Fields[collection.StorageObjectColumnClientID] = bucketClientID + + bucketNameField := connectorSchema.ObjectTypes[collection.StorageBucketName].Fields[collection.StorageObjectColumnName] + bucketNameField.Type = schema.NewNamedType(collection.ScalarStringFilter).Encode() + connectorSchema.ObjectTypes[collection.StorageBucketName].Fields[collection.StorageObjectColumnName] = bucketNameField + + for i, f := range connectorSchema.Functions { + if c.config.Generator.PromptQLCompatible && !slices.Contains([]string{"storageBucketConnections", "storageObjectConnections"}, f.Name) { + // remove boolean expression arguments in commands + delete(f.Arguments, "where") + connectorSchema.Functions[i] = f + } + } + + if c.config.Generator.PromptQLCompatible { + // PromptQL doesn't support bytes representation. + bytesScalar := schema.NewScalarType() + bytesScalar.Representation = schema.NewTypeRepresentationString().Encode() + connectorSchema.ScalarTypes["Bytes"] = *bytesScalar + + for i, f := range connectorSchema.Procedures { + // remove boolean expression arguments in commands + delete(f.Arguments, "where") + connectorSchema.Procedures[i] = f + } + } +} diff --git a/connector/functions/bucket.go b/connector/functions/bucket.go index f94ac6e..1fd903c 100644 --- a/connector/functions/bucket.go +++ b/connector/functions/bucket.go @@ -5,27 +5,27 @@ import ( "github.com/hasura/ndc-sdk-go/schema" "github.com/hasura/ndc-sdk-go/utils" - "github.com/hasura/ndc-storage/connector/functions/internal" + "github.com/hasura/ndc-storage/connector/collection" "github.com/hasura/ndc-storage/connector/storage/common" "github.com/hasura/ndc-storage/connector/types" ) // ProcedureCreateStorageBucket creates a new bucket. -func ProcedureCreateStorageBucket(ctx context.Context, state *types.State, args *common.MakeStorageBucketArguments) (bool, error) { +func ProcedureCreateStorageBucket(ctx context.Context, state *types.State, args *common.MakeStorageBucketArguments) (SuccessResponse, error) { if err := state.Storage.MakeBucket(ctx, args.ClientID, &args.MakeStorageBucketOptions); err != nil { - return false, err + return SuccessResponse{}, err } - return true, nil + return NewSuccessResponse(), nil } -// FunctionStorageBuckets list all buckets. -func FunctionStorageBuckets(ctx context.Context, state *types.State, args *common.ListStorageBucketArguments) (StorageConnection[common.StorageBucket], error) { +// FunctionStorageBucketConnections list all buckets using the relay style. +func FunctionStorageBucketConnections(ctx context.Context, state *types.State, args *common.ListStorageBucketArguments) (StorageConnection[common.StorageBucket], error) { if args.First != nil && *args.First <= 0 { return StorageConnection[common.StorageBucket]{}, schema.UnprocessableContentError("$first argument must be larger than 0", nil) } - request, err := internal.EvalBucketPredicate(args.ClientID, args.Prefix, args.Where, types.QueryVariablesFromContext(ctx)) + request, err := collection.EvalBucketPredicate(args.ClientID, args.Prefix, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { return StorageConnection[common.StorageBucket]{}, err } @@ -79,7 +79,7 @@ func FunctionStorageBuckets(ctx context.Context, state *types.State, args *commo // FunctionStorageBucket gets a bucket by name. func FunctionStorageBucket(ctx context.Context, state *types.State, args *common.StorageBucketArguments) (*common.StorageBucket, error) { - request := internal.PredicateEvaluator{} + request := collection.PredicateEvaluator{} if err := request.EvalSelection(utils.CommandSelectionFieldFromContext(ctx)); err != nil { return nil, err @@ -98,24 +98,29 @@ func FunctionStorageBucket(ctx context.Context, state *types.State, args *common } // FunctionStorageBucketExists checks if a bucket exists. -func FunctionStorageBucketExists(ctx context.Context, state *types.State, args *common.StorageBucketArguments) (bool, error) { - return state.Storage.BucketExists(ctx, args) +func FunctionStorageBucketExists(ctx context.Context, state *types.State, args *common.StorageBucketArguments) (ExistsResponse, error) { + exists, err := state.Storage.BucketExists(ctx, args) + if err != nil { + return ExistsResponse{}, err + } + + return ExistsResponse{Exists: exists}, nil } // ProcedureRemoveStorageBucket removes a bucket, bucket should be empty to be successfully removed. -func ProcedureRemoveStorageBucket(ctx context.Context, state *types.State, args *common.StorageBucketArguments) (bool, error) { +func ProcedureRemoveStorageBucket(ctx context.Context, state *types.State, args *common.StorageBucketArguments) (SuccessResponse, error) { if err := state.Storage.RemoveBucket(ctx, args); err != nil { - return false, err + return SuccessResponse{}, err } - return true, nil + return NewSuccessResponse(), nil } // ProcedureUpdateStorageBucket updates the bucket's configuration. -func ProcedureUpdateStorageBucket(ctx context.Context, state *types.State, args *common.UpdateBucketArguments) (bool, error) { +func ProcedureUpdateStorageBucket(ctx context.Context, state *types.State, args *common.UpdateBucketArguments) (SuccessResponse, error) { if err := state.Storage.UpdateBucket(ctx, args); err != nil { - return false, err + return SuccessResponse{}, err } - return true, nil + return NewSuccessResponse(), nil } diff --git a/connector/functions/object.go b/connector/functions/object.go index a70f119..9496434 100644 --- a/connector/functions/object.go +++ b/connector/functions/object.go @@ -7,13 +7,13 @@ import ( "github.com/hasura/ndc-sdk-go/scalar" "github.com/hasura/ndc-sdk-go/schema" "github.com/hasura/ndc-sdk-go/utils" - "github.com/hasura/ndc-storage/connector/functions/internal" + "github.com/hasura/ndc-storage/connector/collection" "github.com/hasura/ndc-storage/connector/storage/common" "github.com/hasura/ndc-storage/connector/types" ) -// FunctionStorageObjects lists objects in a bucket. -func FunctionStorageObjects(ctx context.Context, state *types.State, args *common.ListStorageObjectsArguments) (StorageConnection[common.StorageObject], error) { +// FunctionStorageObjectConnections lists objects in a bucket using the relay style. +func FunctionStorageObjectConnections(ctx context.Context, state *types.State, args *common.ListStorageObjectsArguments) (StorageConnection[common.StorageObject], error) { request, options, err := evalStorageObjectsArguments(ctx, state, args) if err != nil { return StorageConnection[common.StorageObject]{}, err @@ -80,9 +80,9 @@ func FunctionStorageDeletedObjects(ctx context.Context, state *types.State, args // FunctionStorageObject fetches metadata of an object. func FunctionStorageObject(ctx context.Context, state *types.State, args *common.GetStorageObjectArguments) (*common.StorageObject, error) { - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Object, - Operator: internal.OperatorEqual, + Operator: collection.OperatorEqual, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { return nil, err @@ -103,47 +103,49 @@ func FunctionStorageObject(ctx context.Context, state *types.State, args *common } // FunctionDownloadStorageObject returns a stream of the object data. Most of the common errors occur when reading the stream. -func FunctionDownloadStorageObject(ctx context.Context, state *types.State, args *common.GetStorageObjectArguments) (*scalar.Bytes, error) { +func FunctionDownloadStorageObject(ctx context.Context, state *types.State, args *common.GetStorageObjectArguments) (DownloadStorageObjectResponse, error) { args.Base64Encoded = true reader, err := downloadStorageObject(ctx, state, args) if err != nil { - return nil, err + return DownloadStorageObjectResponse{}, err } defer reader.Close() data, err := io.ReadAll(reader) if err != nil { - return nil, schema.InternalServerError(err.Error(), nil) + return DownloadStorageObjectResponse{}, schema.InternalServerError(err.Error(), nil) } - return scalar.NewBytes(data), nil + dataBytes := scalar.NewBytes(data) + + return DownloadStorageObjectResponse{Data: dataBytes}, nil } // FunctionDownloadStorageObjectText returns the object content in plain text. Use this function only if you know exactly the file as an text file. -func FunctionDownloadStorageObjectText(ctx context.Context, state *types.State, args *common.GetStorageObjectArguments) (*string, error) { +func FunctionDownloadStorageObjectText(ctx context.Context, state *types.State, args *common.GetStorageObjectArguments) (DownloadStorageObjectTextResponse, error) { reader, err := downloadStorageObject(ctx, state, args) if err != nil { - return nil, err + return DownloadStorageObjectTextResponse{}, err } defer reader.Close() data, err := io.ReadAll(reader) if err != nil { - return nil, schema.InternalServerError(err.Error(), nil) + return DownloadStorageObjectTextResponse{}, schema.InternalServerError(err.Error(), nil) } dataStr := string(data) - return &dataStr, nil + return DownloadStorageObjectTextResponse{Data: &dataStr}, nil } func downloadStorageObject(ctx context.Context, state *types.State, args *common.GetStorageObjectArguments) (io.ReadCloser, error) { - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Object, - Operator: internal.OperatorEqual, + Operator: collection.OperatorEqual, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { return nil, err @@ -161,9 +163,9 @@ func downloadStorageObject(ctx context.Context, state *types.State, args *common // This presigned URL can have an associated expiration time in seconds after which it is no longer operational. // The maximum expiry is 604800 seconds (i.e. 7 days) and minimum is 1 second. func FunctionStoragePresignedDownloadUrl(ctx context.Context, state *types.State, args *common.PresignedGetStorageObjectArguments) (*common.PresignedURLResponse, error) { - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Object, - Operator: internal.OperatorEqual, + Operator: collection.OperatorEqual, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { return nil, err @@ -181,9 +183,9 @@ func FunctionStoragePresignedDownloadUrl(ctx context.Context, state *types.State // This presigned URL can have an associated expiration time in seconds after which it is no longer operational. // The default expiry is set to 7 days. func FunctionStoragePresignedUploadUrl(ctx context.Context, state *types.State, args *common.PresignedPutStorageObjectArguments) (*common.PresignedURLResponse, error) { - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Object, - Operator: internal.OperatorEqual, + Operator: collection.OperatorEqual, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { return nil, err @@ -201,22 +203,6 @@ func FunctionStorageIncompleteUploads(ctx context.Context, state *types.State, a return state.Storage.ListIncompleteUploads(ctx, args.StorageBucketArguments, args.ListIncompleteUploadsOptions) } -// PutStorageObjectArguments represents input arguments of the PutObject method. -type PutStorageObjectArguments struct { - common.StorageBucketArguments - - Object string `json:"object"` - Options common.PutStorageObjectOptions `json:"options,omitempty"` - Where schema.Expression `json:"where" ndc:"predicate=StorageObjectFilter"` -} - -// PutStorageObjectArguments represents input arguments of the PutObject method. -type PutStorageObjectBase64Arguments struct { - PutStorageObjectArguments - - Data scalar.Bytes `json:"data"` -} - // ProcedureUploadStorageObject uploads object that are less than 128MiB in a single PUT operation. For objects that are greater than 128MiB in size, // PutObject seamlessly uploads the object as parts of 128MiB or more depending on the actual file size. The max upload size for an object is 5TB. func ProcedureUploadStorageObject(ctx context.Context, state *types.State, args *PutStorageObjectBase64Arguments) (common.StorageUploadInfo, error) { @@ -224,9 +210,9 @@ func ProcedureUploadStorageObject(ctx context.Context, state *types.State, args } func uploadStorageObject(ctx context.Context, state *types.State, args *PutStorageObjectArguments, data []byte) (common.StorageUploadInfo, error) { - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Object, - Operator: internal.OperatorEqual, + Operator: collection.OperatorEqual, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { return common.StorageUploadInfo{}, err @@ -244,13 +230,6 @@ func uploadStorageObject(ctx context.Context, state *types.State, args *PutStora return *result, nil } -// PutStorageObjectTextArguments represents input arguments of the PutStorageObjectText method. -type PutStorageObjectTextArguments struct { - PutStorageObjectArguments - - Data string `json:"data"` -} - // ProcedureUploadStorageObjectText uploads object in plain text to the storage server. The file content is not encoded to base64 so the input size is smaller than 30%. func ProcedureUploadStorageObjectText(ctx context.Context, state *types.State, args *PutStorageObjectTextArguments) (common.StorageUploadInfo, error) { return uploadStorageObject(ctx, state, &args.PutStorageObjectArguments, []byte(args.Data)) @@ -279,45 +258,45 @@ func ProcedureComposeStorageObject(ctx context.Context, state *types.State, args } // ProcedureUpdateStorageObject updates the object's configuration. -func ProcedureUpdateStorageObject(ctx context.Context, state *types.State, args *common.UpdateStorageObjectArguments) (bool, error) { - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ +func ProcedureUpdateStorageObject(ctx context.Context, state *types.State, args *common.UpdateStorageObjectArguments) (SuccessResponse, error) { + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Object, - Operator: internal.OperatorEqual, + Operator: collection.OperatorEqual, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { - return false, err + return SuccessResponse{}, err } if !request.IsValid { - return false, errPermissionDenied + return SuccessResponse{}, errPermissionDenied } if err := state.Storage.UpdateObject(ctx, request.GetBucketArguments(), request.ObjectNamePredicate.GetPrefix(), args.UpdateStorageObjectOptions); err != nil { - return false, err + return SuccessResponse{}, err } - return true, nil + return NewSuccessResponse(), nil } // ProcedureRemoveStorageObject removes an object with some specified options. -func ProcedureRemoveStorageObject(ctx context.Context, state *types.State, args *common.RemoveStorageObjectArguments) (bool, error) { - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ +func ProcedureRemoveStorageObject(ctx context.Context, state *types.State, args *common.RemoveStorageObjectArguments) (SuccessResponse, error) { + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Object, - Operator: internal.OperatorEqual, + Operator: collection.OperatorEqual, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { - return false, err + return SuccessResponse{}, err } if !request.IsValid { - return false, errPermissionDenied + return SuccessResponse{}, errPermissionDenied } if err := state.Storage.RemoveObject(ctx, request.GetBucketArguments(), request.ObjectNamePredicate.GetPrefix(), args.RemoveStorageObjectOptions); err != nil { - return false, err + return SuccessResponse{}, err } - return true, nil + return NewSuccessResponse(), nil } // ProcedureRemoveStorageObjects remove a list of objects obtained from an input channel. The call sends a delete request to the server up to 1000 objects at a time. @@ -347,43 +326,43 @@ func ProcedureRemoveStorageObjects(ctx context.Context, state *types.State, args } // ProcedureRemoveIncompleteStorageUpload removes a partially uploaded object. -func ProcedureRemoveIncompleteStorageUpload(ctx context.Context, state *types.State, args *common.RemoveIncompleteUploadArguments) (bool, error) { +func ProcedureRemoveIncompleteStorageUpload(ctx context.Context, state *types.State, args *common.RemoveIncompleteUploadArguments) (SuccessResponse, error) { if err := state.Storage.RemoveIncompleteUpload(ctx, args); err != nil { - return false, err + return SuccessResponse{}, err } - return true, nil + return NewSuccessResponse(), nil } // ProcedureRestoreStorageObject restore a soft-deleted object. -func ProcedureRestoreStorageObject(ctx context.Context, state *types.State, args *common.RestoreStorageObjectArguments) (bool, error) { - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ +func ProcedureRestoreStorageObject(ctx context.Context, state *types.State, args *common.RestoreStorageObjectArguments) (SuccessResponse, error) { + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Object, - Operator: internal.OperatorEqual, + Operator: collection.OperatorEqual, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { - return false, err + return SuccessResponse{}, err } if !request.IsValid { - return false, errPermissionDenied + return SuccessResponse{}, errPermissionDenied } if err := state.Storage.RestoreObject(ctx, request.GetBucketArguments(), request.ObjectNamePredicate.GetPrefix()); err != nil { - return false, err + return SuccessResponse{}, err } - return true, nil + return NewSuccessResponse(), nil } -func evalStorageObjectsArguments(ctx context.Context, state *types.State, args *common.ListStorageObjectsArguments) (*internal.PredicateEvaluator, *common.ListStorageObjectsOptions, error) { +func evalStorageObjectsArguments(ctx context.Context, state *types.State, args *common.ListStorageObjectsArguments) (*collection.PredicateEvaluator, *common.ListStorageObjectsOptions, error) { if args.First != nil && *args.First <= 0 { return nil, nil, schema.UnprocessableContentError("$first argument must be larger than 0", nil) } - request, err := internal.EvalObjectPredicate(args.StorageBucketArguments, &internal.StringComparisonOperator{ + request, err := collection.EvalObjectPredicate(args.StorageBucketArguments, &collection.StringComparisonOperator{ Value: args.Prefix, - Operator: internal.OperatorStartsWith, + Operator: collection.OperatorStartsWith, }, args.Where, types.QueryVariablesFromContext(ctx)) if err != nil { return nil, nil, err diff --git a/connector/functions/types.generated.go b/connector/functions/types.generated.go index c4836d5..c461615 100644 --- a/connector/functions/types.generated.go +++ b/connector/functions/types.generated.go @@ -14,6 +14,30 @@ import ( "slices" ) +// ToMap encodes the struct to a value map +func (j DownloadStorageObjectResponse) ToMap() map[string]any { + r := make(map[string]any) + r["data"] = j.Data + + return r +} + +// ToMap encodes the struct to a value map +func (j DownloadStorageObjectTextResponse) ToMap() map[string]any { + r := make(map[string]any) + r["data"] = j.Data + + return r +} + +// ToMap encodes the struct to a value map +func (j ExistsResponse) ToMap() map[string]any { + r := make(map[string]any) + r["exists"] = j.Exists + + return r +} + // ToMap encodes the struct to a value map func (j PutStorageObjectArguments) ToMap() map[string]any { r := make(map[string]any) @@ -27,6 +51,14 @@ func (j PutStorageObjectArguments) ToMap() map[string]any { return r } +// ToMap encodes the struct to a value map +func (j SuccessResponse) ToMap() map[string]any { + r := make(map[string]any) + r["success"] = j.Success + + return r +} + // DataConnectorHandler implements the data connector handler type DataConnectorHandler struct{} @@ -64,8 +96,11 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat switch request.Collection { case "downloadStorageObject": - if len(queryFields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := queryFields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.GetStorageObjectArguments parseErr := args.FromValue(rawArgs) @@ -78,12 +113,28 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat connector_addSpanEvent(span, logger, "execute_function", map[string]any{ "arguments": args, }) - return FunctionDownloadStorageObject(ctx, state, &args) + rawResult, err := FunctionDownloadStorageObject(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) + if err != nil { + return nil, err + } + return result, nil case "downloadStorageObjectText": - if len(queryFields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := queryFields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.GetStorageObjectArguments parseErr := args.FromValue(rawArgs) @@ -96,7 +147,20 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat connector_addSpanEvent(span, logger, "execute_function", map[string]any{ "arguments": args, }) - return FunctionDownloadStorageObjectText(ctx, state, &args) + rawResult, err := FunctionDownloadStorageObjectText(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) + if err != nil { + return nil, err + } + return result, nil case "storageBucket": @@ -135,12 +199,15 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat } return result, nil - case "storageBucketExists": + case "storageBucketConnections": - if len(queryFields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := queryFields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } - var args common.StorageBucketArguments + var args common.ListStorageBucketArguments parseErr := args.FromValue(rawArgs) if parseErr != nil { return nil, schema.UnprocessableContentError("failed to resolve arguments", map[string]any{ @@ -151,9 +218,22 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat connector_addSpanEvent(span, logger, "execute_function", map[string]any{ "arguments": args, }) - return FunctionStorageBucketExists(ctx, state, &args) + rawResult, err := FunctionStorageBucketConnections(ctx, state, &args) - case "storageBuckets": + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) + if err != nil { + return nil, err + } + return result, nil + + case "storageBucketExists": selection, err := queryFields.AsObject() if err != nil { @@ -161,7 +241,7 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat "cause": err.Error(), }) } - var args common.ListStorageBucketArguments + var args common.StorageBucketArguments parseErr := args.FromValue(rawArgs) if parseErr != nil { return nil, schema.UnprocessableContentError("failed to resolve arguments", map[string]any{ @@ -172,7 +252,7 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat connector_addSpanEvent(span, logger, "execute_function", map[string]any{ "arguments": args, }) - rawResult, err := FunctionStorageBuckets(ctx, state, &args) + rawResult, err := FunctionStorageBucketExists(ctx, state, &args) if err != nil { return nil, err @@ -292,7 +372,7 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat } return result, nil - case "storageObjects": + case "storageObjectConnections": selection, err := queryFields.AsObject() if err != nil { @@ -311,7 +391,7 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat connector_addSpanEvent(span, logger, "execute_function", map[string]any{ "arguments": args, }) - rawResult, err := FunctionStorageObjects(ctx, state, &args) + rawResult, err := FunctionStorageObjectConnections(ctx, state, &args) if err != nil { return nil, err @@ -405,7 +485,7 @@ func (dch DataConnectorHandler) execQuery(ctx context.Context, state *types.Stat } } -var enumValues_FunctionName = []string{"downloadStorageObject", "downloadStorageObjectText", "storageBucket", "storageBucketExists", "storageBuckets", "storageDeletedObjects", "storageIncompleteUploads", "storageObject", "storageObjects", "storagePresignedDownloadUrl", "storagePresignedUploadUrl"} +var enumValues_FunctionName = []string{"downloadStorageObject", "downloadStorageObjectText", "storageBucket", "storageBucketConnections", "storageBucketExists", "storageDeletedObjects", "storageIncompleteUploads", "storageObject", "storageObjectConnections", "storagePresignedDownloadUrl", "storagePresignedUploadUrl"} // MutationExists check if the mutation name exists func (dch DataConnectorHandler) MutationExists(name string) bool { @@ -484,8 +564,11 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State case "createStorageBucket": - if len(operation.Fields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := operation.Fields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.MakeStorageBucketArguments if err := json.Unmarshal(operation.Arguments, &args); err != nil { @@ -494,7 +577,16 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State }) } span.AddEvent("execute_procedure") - result, err := ProcedureCreateStorageBucket(ctx, state, &args) + rawResult, err := ProcedureCreateStorageBucket(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) if err != nil { return nil, err @@ -503,8 +595,11 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State case "removeIncompleteStorageUpload": - if len(operation.Fields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := operation.Fields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.RemoveIncompleteUploadArguments if err := json.Unmarshal(operation.Arguments, &args); err != nil { @@ -513,7 +608,16 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State }) } span.AddEvent("execute_procedure") - result, err := ProcedureRemoveIncompleteStorageUpload(ctx, state, &args) + rawResult, err := ProcedureRemoveIncompleteStorageUpload(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) if err != nil { return nil, err @@ -522,8 +626,11 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State case "removeStorageBucket": - if len(operation.Fields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := operation.Fields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.StorageBucketArguments if err := json.Unmarshal(operation.Arguments, &args); err != nil { @@ -532,7 +639,16 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State }) } span.AddEvent("execute_procedure") - result, err := ProcedureRemoveStorageBucket(ctx, state, &args) + rawResult, err := ProcedureRemoveStorageBucket(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) if err != nil { return nil, err @@ -541,8 +657,11 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State case "removeStorageObject": - if len(operation.Fields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := operation.Fields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.RemoveStorageObjectArguments if err := json.Unmarshal(operation.Arguments, &args); err != nil { @@ -551,7 +670,16 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State }) } span.AddEvent("execute_procedure") - result, err := ProcedureRemoveStorageObject(ctx, state, &args) + rawResult, err := ProcedureRemoveStorageObject(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) if err != nil { return nil, err @@ -591,8 +719,11 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State case "restoreStorageObject": - if len(operation.Fields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := operation.Fields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.RestoreStorageObjectArguments if err := json.Unmarshal(operation.Arguments, &args); err != nil { @@ -601,7 +732,16 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State }) } span.AddEvent("execute_procedure") - result, err := ProcedureRestoreStorageObject(ctx, state, &args) + rawResult, err := ProcedureRestoreStorageObject(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) if err != nil { return nil, err @@ -610,8 +750,11 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State case "updateStorageBucket": - if len(operation.Fields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := operation.Fields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.UpdateBucketArguments if err := json.Unmarshal(operation.Arguments, &args); err != nil { @@ -620,7 +763,16 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State }) } span.AddEvent("execute_procedure") - result, err := ProcedureUpdateStorageBucket(ctx, state, &args) + rawResult, err := ProcedureUpdateStorageBucket(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) if err != nil { return nil, err @@ -629,8 +781,11 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State case "updateStorageObject": - if len(operation.Fields) > 0 { - return nil, schema.UnprocessableContentError("cannot evaluate selection fields for scalar", nil) + selection, err := operation.Fields.AsObject() + if err != nil { + return nil, schema.UnprocessableContentError("the selection field type must be object", map[string]any{ + "cause": err.Error(), + }) } var args common.UpdateStorageObjectArguments if err := json.Unmarshal(operation.Arguments, &args); err != nil { @@ -639,7 +794,16 @@ func (dch DataConnectorHandler) Mutation(ctx context.Context, state *types.State }) } span.AddEvent("execute_procedure") - result, err := ProcedureUpdateStorageObject(ctx, state, &args) + rawResult, err := ProcedureUpdateStorageObject(ctx, state, &args) + + if err != nil { + return nil, err + } + + connector_addSpanEvent(span, logger, "evaluate_response_selection", map[string]any{ + "raw_result": rawResult, + }) + result, err := utils.EvalNestedColumnObject(selection, rawResult) if err != nil { return nil, err diff --git a/connector/functions/types.go b/connector/functions/types.go index 3e3f078..993d1fe 100644 --- a/connector/functions/types.go +++ b/connector/functions/types.go @@ -1,13 +1,11 @@ package functions import ( + "github.com/hasura/ndc-sdk-go/scalar" "github.com/hasura/ndc-sdk-go/schema" - "github.com/hasura/ndc-storage/connector/functions/internal" "github.com/hasura/ndc-storage/connector/storage/common" ) -var GetBaseConnectorSchema = internal.GetConnectorSchema - var errPermissionDenied = schema.ForbiddenError("permission dennied", nil) // StorageConnectionEdge the connection information of the relay pagination response. @@ -21,3 +19,51 @@ type StorageConnectionEdge[T any] struct { Node T `json:"node"` Cursor string `json:"cursor"` } + +// SuccessResponse represents a common successful response structure. +type SuccessResponse struct { + Success bool `json:"success"` +} + +// NewSuccessResponse creates a SuccessResponse instance with default success=true. +func NewSuccessResponse() SuccessResponse { + return SuccessResponse{Success: true} +} + +// ExistsResponse represents a common existing response structure. +type ExistsResponse struct { + Exists bool `json:"exists"` +} + +// DownloadStorageObjectResponse represents the object data response in base64-encode string format. +type DownloadStorageObjectResponse struct { + Data *scalar.Bytes `json:"data"` +} + +// DownloadStorageObjectTextResponse represents the object data response in string format. +type DownloadStorageObjectTextResponse struct { + Data *string `json:"data"` +} + +// PutStorageObjectArguments represents input arguments of the PutObject method. +type PutStorageObjectArguments struct { + common.StorageBucketArguments + + Object string `json:"object"` + Options common.PutStorageObjectOptions `json:"options,omitempty"` + Where schema.Expression `json:"where" ndc:"predicate=StorageObjectFilter"` +} + +// PutStorageObjectArguments represents input arguments of the PutObject method. +type PutStorageObjectBase64Arguments struct { + PutStorageObjectArguments + + Data scalar.Bytes `json:"data"` +} + +// PutStorageObjectTextArguments represents input arguments of the PutStorageObjectText method. +type PutStorageObjectTextArguments struct { + PutStorageObjectArguments + + Data string `json:"data"` +} diff --git a/connector/query.go b/connector/query.go index a91b18d..7ebff3b 100644 --- a/connector/query.go +++ b/connector/query.go @@ -6,6 +6,7 @@ import ( "github.com/hasura/ndc-sdk-go/schema" "github.com/hasura/ndc-sdk-go/utils" + "github.com/hasura/ndc-storage/connector/collection" "github.com/hasura/ndc-storage/connector/types" "go.opentelemetry.io/otel/codes" "golang.org/x/sync/errgroup" @@ -87,7 +88,31 @@ func (c *Connector) execQuery(ctx context.Context, state *types.State, request * }) } - result, err := c.apiHandler.Query(context.WithValue(ctx, types.QueryVariablesContextKey, variables), state, request, rawArgs) + var result *schema.RowSet + + switch request.Collection { + case collection.CollectionStorageBuckets: + executor := collection.CollectionBucketExecutor{ + Storage: state.Storage, + Request: request, + Arguments: rawArgs, + Variables: variables, + Concurrency: c.config.Concurrency.Query, + } + result, err = executor.Execute(ctx) + case collection.CollectionStorageObjects: + executor := collection.CollectionObjectExecutor{ + Storage: state.Storage, + Request: request, + Arguments: rawArgs, + Variables: variables, + Concurrency: c.config.Concurrency.Query, + } + result, err = executor.Execute(ctx) + default: + result, err = c.apiHandler.Query(context.WithValue(ctx, types.QueryVariablesContextKey, variables), state, request, rawArgs) + } + if err != nil { span.SetStatus(codes.Error, fmt.Sprintf("failed to execute function %d", index)) span.RecordError(err) diff --git a/connector/query_test.go b/connector/query_test.go index 5c7b7e0..c3f045c 100644 --- a/connector/query_test.go +++ b/connector/query_test.go @@ -35,6 +35,9 @@ func TestConnectorQueries(t *testing.T) { "clientId": "%s", "name": "dummy-bucket-%d" }`, cid, i)), + Fields: schema.NewNestedObject(map[string]schema.FieldEncoder{ + "success": schema.NewColumnField("success", nil), + }).Encode(), }) } @@ -84,11 +87,17 @@ func TestConnectorQueries(t *testing.T) { "contentType": "application/json", "expires": "2099-01-01T00:00:00Z", "sendContentMd5": true, - "metadata": map[string]any{ - "Foo": "Baz", + "metadata": []map[string]any{ + { + "key": "Foo", + "value": "Bar", + }, }, - "tags": map[string]any{ - "category": "movie", + "tags": []map[string]any{ + { + "key": "category", + "value": "movie", + }, }, }, } @@ -160,11 +169,20 @@ func TestMaxDownloadSizeValidation(t *testing.T) { } }, "collection": "%s", - "collection_relationships": {}, + "collection_relationships": {}, "query": { "fields": { "__value": { "column": "__value", + "fields": { + "fields": { + "data": { + "column": "data", + "type": "column" + } + }, + "type": "object" + }, "type": "column" } } diff --git a/connector/schema.generated.go b/connector/schema.generated.go index 6460436..b8be5e8 100644 --- a/connector/schema.generated.go +++ b/connector/schema.generated.go @@ -34,7 +34,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Description: toPtr("is the bucket's Cross-Origin Resource Sharing (CORS) configuration."), Fields: schema.ObjectTypeFields{ "maxAge": schema.ObjectField{ - Type: schema.NewNamedType("Duration").Encode(), + Type: schema.NewNamedType("DurationString").Encode(), }, "methods": schema.ObjectField{ Type: schema.NewArrayType(schema.NewNamedType("String")).Encode(), @@ -84,17 +84,41 @@ func GetConnectorSchema() *schema.SchemaResponse { }, }, }, + "DownloadStorageObjectResponse": schema.ObjectType{ + Description: toPtr("represents the object data response in base64-encode string format."), + Fields: schema.ObjectTypeFields{ + "data": schema.ObjectField{ + Type: schema.NewNullableType(schema.NewNamedType("Bytes")).Encode(), + }, + }, + }, + "DownloadStorageObjectTextResponse": schema.ObjectType{ + Description: toPtr("represents the object data response in string format."), + Fields: schema.ObjectTypeFields{ + "data": schema.ObjectField{ + Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), + }, + }, + }, + "ExistsResponse": schema.ObjectType{ + Description: toPtr("represents a common existing response structure."), + Fields: schema.ObjectTypeFields{ + "exists": schema.ObjectField{ + Type: schema.NewNamedType("Boolean").Encode(), + }, + }, + }, "GetStorageObjectOptions": schema.ObjectType{ Description: toPtr("are used to specify additional headers or options during GET requests."), Fields: schema.ObjectTypeFields{ "headers": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "partNumber": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("Int32")).Encode(), }, "requestParams": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versionId": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -148,7 +172,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), }, "tags": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, }, }, @@ -221,7 +245,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Int64")).Encode(), }, "tags": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, }, }, @@ -306,10 +330,10 @@ func GetConnectorSchema() *schema.SchemaResponse { Description: toPtr("represent the options for the PresignedGetObject method."), Fields: schema.ObjectTypeFields{ "expiry": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("Duration")).Encode(), + Type: schema.NewNullableType(schema.NewNamedType("DurationString")).Encode(), }, "requestParams": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, }, }, @@ -317,7 +341,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Description: toPtr("holds the presigned URL and expiry information."), Fields: schema.ObjectTypeFields{ "expiredAt": schema.ObjectField{ - Type: schema.NewNamedType("String").Encode(), + Type: schema.NewNamedType("TimestampTZ").Encode(), }, "url": schema.ObjectField{ Type: schema.NewNamedType("String").Encode(), @@ -384,7 +408,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Boolean")).Encode(), }, "metadata": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "numThreads": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("Int32")).Encode(), @@ -402,7 +426,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), }, "tags": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "websiteRedirectLocation": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -427,7 +451,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Description: toPtr("the container of Multi Delete S3 API error."), Fields: schema.ObjectTypeFields{ "error": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNamedType("String").Encode(), }, "objectName": schema.ObjectField{ Type: schema.NewNamedType("String").Encode(), @@ -557,7 +581,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), }, "tags": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versioning": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("StorageBucketVersioningConfiguration")).Encode(), @@ -647,7 +671,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Boolean")).Encode(), }, "metadata": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "mode": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("StorageRetentionMode")).Encode(), @@ -662,7 +686,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Int64")).Encode(), }, "tags": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, }, }, @@ -726,6 +750,17 @@ func GetConnectorSchema() *schema.SchemaResponse { }, }, }, + "StorageKeyValue": schema.ObjectType{ + Description: toPtr("represent a key-value string pair"), + Fields: schema.ObjectTypeFields{ + "key": schema.ObjectField{ + Type: schema.NewNamedType("String").Encode(), + }, + "value": schema.ObjectField{ + Type: schema.NewNamedType("String").Encode(), + }, + }, + }, "StorageObject": schema.ObjectType{ Description: toPtr("container for object metadata."), Fields: schema.ObjectTypeFields{ @@ -856,7 +891,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), }, "metadata": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "name": schema.ObjectField{ Type: schema.NewNamedType("String").Encode(), @@ -868,7 +903,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), }, "rawMetadata": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "rehydratePriority": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -910,7 +945,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Int32")).Encode(), }, "tags": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versionId": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1015,7 +1050,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNamedType("TimestampTZ").Encode(), }, "retentionDuration": schema.ObjectField{ - Type: schema.NewNamedType("Duration").Encode(), + Type: schema.NewNamedType("DurationString").Encode(), }, }, }, @@ -1102,6 +1137,14 @@ func GetConnectorSchema() *schema.SchemaResponse { }, }, }, + "SuccessResponse": schema.ObjectType{ + Description: toPtr("represents a common successful response structure."), + Fields: schema.ObjectTypeFields{ + "success": schema.ObjectField{ + Type: schema.NewNamedType("Boolean").Encode(), + }, + }, + }, "UpdateStorageBucketOptions": schema.ObjectType{ Description: toPtr("hold update options for the bucket."), Fields: schema.ObjectTypeFields{ @@ -1115,7 +1158,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("SetStorageObjectLockConfig")).Encode(), }, "tags": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versioningEnabled": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("Boolean")).Encode(), @@ -1129,13 +1172,13 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Boolean")).Encode(), }, "metadata": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "retention": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("SetStorageObjectRetentionOptions")).Encode(), }, "tags": schema.ObjectField{ - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versionId": schema.ObjectField{ Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1147,7 +1190,7 @@ func GetConnectorSchema() *schema.SchemaResponse { { Name: "downloadStorageObject", Description: toPtr("returns a stream of the object data. Most of the common errors occur when reading the stream."), - ResultType: schema.NewNullableType(schema.NewNamedType("Bytes")).Encode(), + ResultType: schema.NewNamedType("DownloadStorageObjectResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "bucket": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1156,7 +1199,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("StorageClientID")).Encode(), }, "headers": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "object": { Type: schema.NewNamedType("String").Encode(), @@ -1165,7 +1208,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Int32")).Encode(), }, "requestParams": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versionId": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1178,7 +1221,7 @@ func GetConnectorSchema() *schema.SchemaResponse { { Name: "downloadStorageObjectText", Description: toPtr("returns the object content in plain text. Use this function only if you know exactly the file as an text file."), - ResultType: schema.NewNullableType(schema.NewNamedType("String")).Encode(), + ResultType: schema.NewNamedType("DownloadStorageObjectTextResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "bucket": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1187,7 +1230,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("StorageClientID")).Encode(), }, "headers": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "object": { Type: schema.NewNamedType("String").Encode(), @@ -1196,7 +1239,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Int32")).Encode(), }, "requestParams": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versionId": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1220,21 +1263,8 @@ func GetConnectorSchema() *schema.SchemaResponse { }, }, { - Name: "storageBucketExists", - Description: toPtr("checks if a bucket exists."), - ResultType: schema.NewNamedType("Boolean").Encode(), - Arguments: map[string]schema.ArgumentInfo{ - "bucket": { - Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), - }, - "clientId": { - Type: schema.NewNullableType(schema.NewNamedType("StorageClientID")).Encode(), - }, - }, - }, - { - Name: "storageBuckets", - Description: toPtr("list all buckets."), + Name: "storageBucketConnections", + Description: toPtr("list all buckets using the relay style."), ResultType: schema.NewNamedType("StorageConnection_StorageBucket").Encode(), Arguments: map[string]schema.ArgumentInfo{ "after": { @@ -1254,6 +1284,19 @@ func GetConnectorSchema() *schema.SchemaResponse { }, }, }, + { + Name: "storageBucketExists", + Description: toPtr("checks if a bucket exists."), + ResultType: schema.NewNamedType("ExistsResponse").Encode(), + Arguments: map[string]schema.ArgumentInfo{ + "bucket": { + Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), + }, + "clientId": { + Type: schema.NewNullableType(schema.NewNamedType("StorageClientID")).Encode(), + }, + }, + }, { Name: "storageDeletedObjects", Description: toPtr("list deleted objects in a bucket."), @@ -1310,7 +1353,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("StorageClientID")).Encode(), }, "headers": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "object": { Type: schema.NewNamedType("String").Encode(), @@ -1319,7 +1362,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Int32")).Encode(), }, "requestParams": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versionId": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1330,8 +1373,8 @@ func GetConnectorSchema() *schema.SchemaResponse { }, }, { - Name: "storageObjects", - Description: toPtr("lists objects in a bucket."), + Name: "storageObjectConnections", + Description: toPtr("lists objects in a bucket using the relay style."), ResultType: schema.NewNamedType("StorageConnection_StorageObject").Encode(), Arguments: map[string]schema.ArgumentInfo{ "after": { @@ -1369,13 +1412,13 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("StorageClientID")).Encode(), }, "expiry": { - Type: schema.NewNullableType(schema.NewNamedType("Duration")).Encode(), + Type: schema.NewNullableType(schema.NewNamedType("DurationString")).Encode(), }, "object": { Type: schema.NewNamedType("String").Encode(), }, "requestParams": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "where": { Type: schema.NewNullableType(schema.NewPredicateType("StorageObjectFilter")).Encode(), @@ -1394,7 +1437,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("StorageClientID")).Encode(), }, "expiry": { - Type: schema.NewNullableType(schema.NewNamedType("Duration")).Encode(), + Type: schema.NewNullableType(schema.NewNamedType("DurationString")).Encode(), }, "object": { Type: schema.NewNamedType("String").Encode(), @@ -1441,7 +1484,7 @@ func GetConnectorSchema() *schema.SchemaResponse { { Name: "createStorageBucket", Description: toPtr("creates a new bucket."), - ResultType: schema.NewNamedType("Boolean").Encode(), + ResultType: schema.NewNamedType("SuccessResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "clientId": { Type: schema.NewNullableType(schema.NewNamedType("StorageClientID")).Encode(), @@ -1456,14 +1499,14 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), }, "tags": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, }, }, { Name: "removeIncompleteStorageUpload", Description: toPtr("removes a partially uploaded object."), - ResultType: schema.NewNamedType("Boolean").Encode(), + ResultType: schema.NewNamedType("SuccessResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "bucket": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1479,7 +1522,7 @@ func GetConnectorSchema() *schema.SchemaResponse { { Name: "removeStorageBucket", Description: toPtr("removes a bucket, bucket should be empty to be successfully removed."), - ResultType: schema.NewNamedType("Boolean").Encode(), + ResultType: schema.NewNamedType("SuccessResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "bucket": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1492,7 +1535,7 @@ func GetConnectorSchema() *schema.SchemaResponse { { Name: "removeStorageObject", Description: toPtr("removes an object with some specified options."), - ResultType: schema.NewNamedType("Boolean").Encode(), + ResultType: schema.NewNamedType("SuccessResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "bucket": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1554,7 +1597,7 @@ func GetConnectorSchema() *schema.SchemaResponse { { Name: "restoreStorageObject", Description: toPtr("restore a soft-deleted object."), - ResultType: schema.NewNamedType("Boolean").Encode(), + ResultType: schema.NewNamedType("SuccessResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "bucket": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1573,7 +1616,7 @@ func GetConnectorSchema() *schema.SchemaResponse { { Name: "updateStorageBucket", Description: toPtr("updates the bucket's configuration."), - ResultType: schema.NewNamedType("Boolean").Encode(), + ResultType: schema.NewNamedType("SuccessResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "bucket": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1591,7 +1634,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("SetStorageObjectLockConfig")).Encode(), }, "tags": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versioningEnabled": { Type: schema.NewNullableType(schema.NewNamedType("Boolean")).Encode(), @@ -1601,7 +1644,7 @@ func GetConnectorSchema() *schema.SchemaResponse { { Name: "updateStorageObject", Description: toPtr("updates the object's configuration."), - ResultType: schema.NewNamedType("Boolean").Encode(), + ResultType: schema.NewNamedType("SuccessResponse").Encode(), Arguments: map[string]schema.ArgumentInfo{ "bucket": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1613,7 +1656,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("Boolean")).Encode(), }, "metadata": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "object": { Type: schema.NewNamedType("String").Encode(), @@ -1622,7 +1665,7 @@ func GetConnectorSchema() *schema.SchemaResponse { Type: schema.NewNullableType(schema.NewNamedType("SetStorageObjectRetentionOptions")).Encode(), }, "tags": { - Type: schema.NewNullableType(schema.NewNamedType("JSON")).Encode(), + Type: schema.NewNullableType(schema.NewArrayType(schema.NewNamedType("StorageKeyValue"))).Encode(), }, "versionId": { Type: schema.NewNullableType(schema.NewNamedType("String")).Encode(), @@ -1704,10 +1747,10 @@ func GetConnectorSchema() *schema.SchemaResponse { ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{}, Representation: schema.NewTypeRepresentationDate().Encode(), }, - "Duration": schema.ScalarType{ + "DurationString": schema.ScalarType{ AggregateFunctions: schema.ScalarTypeAggregateFunctions{}, ComparisonOperators: map[string]schema.ComparisonOperatorDefinition{}, - Representation: schema.NewTypeRepresentationJSON().Encode(), + Representation: schema.NewTypeRepresentationString().Encode(), }, "GoogleStorageRPO": schema.ScalarType{ AggregateFunctions: schema.ScalarTypeAggregateFunctions{}, diff --git a/connector/storage/azblob/bucket.go b/connector/storage/azblob/bucket.go index 865d779..cf3857c 100644 --- a/connector/storage/azblob/bucket.go +++ b/connector/storage/azblob/bucket.go @@ -25,8 +25,8 @@ func (c *Client) MakeBucket(ctx context.Context, args *common.MakeStorageBucketO Metadata: map[string]*string{}, } - for key, value := range args.Tags { - options.Metadata[key] = &value + for _, item := range args.Tags { + options.Metadata[item.Key] = &item.Value } _, err := c.client.CreateContainer(ctx, args.Name, options) @@ -95,13 +95,12 @@ L: result.Name = *container.Name } - if container.Metadata != nil { - result.Tags = map[string]string{} - - for key, value := range container.Metadata { - if value != nil { - result.Tags[key] = *value - } + for key, value := range container.Metadata { + if value != nil { + result.Tags = append(result.Tags, common.StorageKeyValue{ + Key: key, + Value: *value, + }) } } @@ -216,13 +215,12 @@ func (c *Client) getBucket(ctx context.Context, bucketName string, options commo result.Name = *container.Name } - if container.Metadata != nil { - result.Tags = map[string]string{} - - for key, value := range container.Metadata { - if value != nil { - result.Tags[key] = *value - } + for key, value := range container.Metadata { + if value != nil { + result.Tags = append(result.Tags, common.StorageKeyValue{ + Key: key, + Value: *value, + }) } } @@ -243,7 +241,7 @@ func (c *Client) UpdateBucket(ctx context.Context, bucketName string, opts commo defer span.End() if opts.Tags != nil { - if err := c.SetBucketTagging(ctx, bucketName, opts.Tags); err != nil { + if err := c.SetBucketTagging(ctx, bucketName, common.KeyValuesToStringMap(*opts.Tags)); err != nil { return err } } diff --git a/connector/storage/azblob/config.go b/connector/storage/azblob/config.go index 4c95db8..8b028fb 100644 --- a/connector/storage/azblob/config.go +++ b/connector/storage/azblob/config.go @@ -246,7 +246,7 @@ func (ac AuthCredentials) JSONSchema() *jsonschema.Schema { //nolint:funlen }) entraProps.Set("audience", &jsonschema.Schema{ Description: "Audience to use when requesting tokens for Azure Active Directory authentication", - Type: envStringRefName, + Ref: envStringRefName, }) entraProps.Set("disableInstanceDiscovery", &jsonschema.Schema{ diff --git a/connector/storage/azblob/object.go b/connector/storage/azblob/object.go index 8ac1875..596abad 100644 --- a/connector/storage/azblob/object.go +++ b/connector/storage/azblob/object.go @@ -351,7 +351,7 @@ func (c *Client) PutObject(ctx context.Context, bucketName string, objectName st uploadOptions := &azblob.UploadStreamOptions{ HTTPHeaders: &blob.HTTPHeaders{}, - Tags: opts.Tags, + Tags: common.KeyValuesToStringMap(opts.Tags), Metadata: map[string]*string{}, Concurrency: int(opts.NumThreads), BlockSize: int64(opts.PartSize), @@ -366,10 +366,8 @@ func (c *Client) PutObject(ctx context.Context, bucketName string, objectName st uploadOptions.AccessTier = &accessTier } - for key, value := range opts.Metadata { - if value != "" { - uploadOptions.Metadata[key] = &value - } + for _, item := range opts.Metadata { + uploadOptions.Metadata[item.Key] = &item.Value } if opts.CacheControl != "" { @@ -448,15 +446,13 @@ func (c *Client) CopyObject(ctx context.Context, dest common.StorageCopyDestOpti blobClient := c.client.ServiceClient().NewContainerClient(dest.Bucket).NewBlobClient(dest.Object) options := &blob.CopyFromURLOptions{ - BlobTags: dest.Tags, + BlobTags: common.KeyValuesToStringMap(dest.Tags), Metadata: make(map[string]*string), LegalHold: dest.LegalHold, } - for key, value := range dest.Metadata { - if value != "" { - options.Metadata[key] = &value - } + for _, item := range dest.Metadata { + options.Metadata[item.Key] = &item.Value } resp, err := blobClient.CopyFromURL(ctx, srcURL, options) @@ -590,7 +586,7 @@ func (c *Client) RemoveObjects(ctx context.Context, bucketName string, opts *com return []common.RemoveStorageObjectError{ { - Error: err, + Error: err.Error(), }, } } @@ -603,7 +599,7 @@ func (c *Client) RemoveObjects(ctx context.Context, bucketName string, opts *com if err != nil { return []common.RemoveStorageObjectError{ { - Error: err, + Error: err.Error(), }, } } @@ -612,7 +608,7 @@ func (c *Client) RemoveObjects(ctx context.Context, bucketName string, opts *com if err := batchBuilder.Delete(obj.Name, &container.BatchDeleteOptions{}); err != nil { return []common.RemoveStorageObjectError{ { - Error: err, + Error: err.Error(), }, } } @@ -620,7 +616,7 @@ func (c *Client) RemoveObjects(ctx context.Context, bucketName string, opts *com if _, err := containerClient.SubmitBatch(ctx, batchBuilder, nil); err != nil { errs = append(errs, common.RemoveStorageObjectError{ - Error: err, + Error: err.Error(), }) } } @@ -646,7 +642,7 @@ func (c *Client) UpdateObject(ctx context.Context, bucketName string, objectName } if opts.Tags != nil { - if err := c.SetObjectTags(ctx, bucketName, objectName, opts.VersionID, opts.Tags); err != nil { + if err := c.SetObjectTags(ctx, bucketName, objectName, opts.VersionID, common.KeyValuesToStringMap(*opts.Tags)); err != nil { return err } } diff --git a/connector/storage/azblob/utils.go b/connector/storage/azblob/utils.go index 55cc6a6..723f33e 100644 --- a/connector/storage/azblob/utils.go +++ b/connector/storage/azblob/utils.go @@ -19,7 +19,6 @@ var errNotSupported = schema.NotSupportedError("Azure Blob Storage doesn't suppo func serializeObjectInfo(item *container.BlobItem) common.StorageObject { //nolint:funlen,cyclop object := common.StorageObject{ - Metadata: make(map[string]string), IsLatest: item.IsCurrentVersion, Deleted: item.Deleted, VersionID: item.VersionID, @@ -30,20 +29,24 @@ func serializeObjectInfo(item *container.BlobItem) common.StorageObject { //noli } if item.BlobTags != nil && len(item.BlobTags.BlobTagSet) > 0 { - object.Tags = make(map[string]string) - for _, bt := range item.BlobTags.BlobTagSet { if bt.Key == nil || bt.Value == nil { continue } - object.Tags[*bt.Key] = *bt.Value + object.Tags = append(object.Tags, common.StorageKeyValue{ + Key: *bt.Key, + Value: *bt.Value, + }) } } for key, value := range item.Metadata { if value != nil { - object.Metadata[key] = *value + object.Metadata = append(object.Metadata, common.StorageKeyValue{ + Key: key, + Value: *value, + }) } } diff --git a/connector/storage/common/arguments.go b/connector/storage/common/arguments.go index 0c9dbdb..2dade7a 100644 --- a/connector/storage/common/arguments.go +++ b/connector/storage/common/arguments.go @@ -7,6 +7,12 @@ import ( "github.com/hasura/ndc-sdk-go/schema" ) +// StorageKeyValue represent a key-value string pair +type StorageKeyValue struct { + Key string `json:"key"` + Value string `json:"value"` +} + // ListStorageBucketArguments represent the input arguments for the ListBuckets methods. type ListStorageBucketArguments struct { // The storage client ID. @@ -67,7 +73,7 @@ type MakeStorageBucketOptions struct { // Enable object locking ObjectLock bool `json:"objectLock,omitempty"` // Optional tags - Tags map[string]string `json:"tags,omitempty"` + Tags []StorageKeyValue `json:"tags,omitempty"` } // ListIncompleteUploadsArguments the input arguments of the ListIncompleteUploads method. @@ -99,17 +105,17 @@ type PresignedGetStorageObjectArguments struct { // PresignedGetStorageObjectOptions represent the options for the PresignedGetObject method. type PresignedGetStorageObjectOptions struct { - Expiry *scalar.Duration `json:"expiry"` - RequestParams map[string][]string `json:"requestParams,omitempty"` + Expiry *scalar.DurationString `json:"expiry"` + RequestParams []StorageKeyValue `json:"requestParams,omitempty"` } // PresignedPutStorageObjectArguments represent the input arguments for the PresignedPutObject method. type PresignedPutStorageObjectArguments struct { StorageBucketArguments - Object string `json:"object"` - Expiry *scalar.Duration `json:"expiry"` - Where schema.Expression `json:"where" ndc:"predicate=StorageObjectFilter"` + Object string `json:"object"` + Expiry *scalar.DurationString `json:"expiry"` + Where schema.Expression `json:"where" ndc:"predicate=StorageObjectFilter"` } // ListStorageObjectsArguments holds all arguments of a list object request. @@ -185,8 +191,8 @@ type GetStorageObjectArguments struct { // GetStorageObjectOptions are used to specify additional headers or options during GET requests. type GetStorageObjectOptions struct { - Headers map[string]string `json:"headers,omitempty"` - RequestParams map[string][]string `json:"requestParams,omitempty"` + Headers []StorageKeyValue `json:"headers,omitempty"` + RequestParams []StorageKeyValue `json:"requestParams,omitempty"` // ServerSideEncryption *ServerSideEncryptionMethod `json:"serverSideEncryption"` VersionID *string `json:"versionId"` PartNumber *int `json:"partNumber"` @@ -214,10 +220,10 @@ type StorageCopyDestOptions struct { // if no user-metadata is provided, it is copied from source // (when there is only once source object in the compose // request) - Metadata map[string]string `json:"metadata,omitempty"` + Metadata []StorageKeyValue `json:"metadata,omitempty"` // `tags` is the user defined object tags to be set on destination. - Tags map[string]string `json:"tags,omitempty"` + Tags []StorageKeyValue `json:"tags,omitempty"` // Specifies whether you want to apply a Legal Hold to the copied object. LegalHold *bool `json:"legalHold"` @@ -279,8 +285,8 @@ type UpdateStorageObjectOptions struct { VersionID string `json:"versionId,omitempty"` Retention *SetStorageObjectRetentionOptions `json:"retention"` LegalHold *bool `json:"legalHold"` - Metadata map[string]string `json:"metadata,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Metadata *[]StorageKeyValue `json:"metadata"` + Tags *[]StorageKeyValue `json:"tags"` } // IsEmpty checks if all elements in the option object is null. @@ -323,8 +329,8 @@ type PutStorageObjectRetentionOptions struct { // PutStorageObjectOptions represents options specified by user for PutObject call. type PutStorageObjectOptions struct { - Metadata map[string]string `json:"metadata,omitempty"` - Tags map[string]string `json:"tags,omitempty"` + Metadata []StorageKeyValue `json:"metadata,omitempty"` + Tags []StorageKeyValue `json:"tags,omitempty"` ContentType string `json:"contentType,omitempty"` ContentEncoding string `json:"contentEncoding,omitempty"` ContentDisposition string `json:"contentDisposition,omitempty"` @@ -362,8 +368,8 @@ type PutStorageObjectOptions struct { // PresignedURLResponse holds the presigned URL and expiry information. type PresignedURLResponse struct { - URL string `json:"url"` - ExpiredAt string `json:"expiredAt"` + URL string `json:"url"` + ExpiredAt time.Time `json:"expiredAt"` } // UpdateBucketArguments hold update options for the bucket. @@ -374,7 +380,7 @@ type UpdateBucketArguments struct { // UpdateStorageBucketOptions hold update options for the bucket. type UpdateStorageBucketOptions struct { - Tags map[string]string `json:"tags,omitempty"` + Tags *[]StorageKeyValue `json:"tags"` VersioningEnabled *bool `json:"versioningEnabled"` Lifecycle *ObjectLifecycleConfiguration `json:"lifecycle"` Encryption *ServerSideEncryptionConfiguration `json:"encryption"` diff --git a/connector/storage/common/storage.go b/connector/storage/common/storage.go index 3a1a368..402a125 100644 --- a/connector/storage/common/storage.go +++ b/connector/storage/common/storage.go @@ -107,7 +107,7 @@ type StorageBucket struct { // The name of the bucket. Name string `json:"name"` // Bucket tags or metadata. - Tags map[string]string `json:"tags,omitempty"` + Tags []StorageKeyValue `json:"tags,omitempty"` // The versioning configuration Versioning *StorageBucketVersioningConfiguration `json:"versioning"` // The versioning configuration @@ -215,7 +215,7 @@ type GoogleStorageRPO string type BucketCors struct { // MaxAge is the value to return in the Access-Control-Max-Age // header used in preflight responses. - MaxAge scalar.Duration `json:"maxAge"` + MaxAge scalar.DurationString `json:"maxAge"` // Methods is the list of HTTP methods on which to include CORS response // headers, (GET, OPTIONS, POST, etc) Note: "*" is permitted in the list @@ -290,7 +290,7 @@ type StorageObjectSoftDeletePolicy struct { // RetentionDuration is the amount of time that soft-deleted objects in the // bucket will be retained and cannot be permanently deleted. - RetentionDuration scalar.Duration `json:"retentionDuration"` + RetentionDuration scalar.DurationString `json:"retentionDuration"` } // StorageOwner name. @@ -342,13 +342,13 @@ type StorageObject struct { // Collection of additional metadata on the object. // In MinIO and S3, x-amz-meta-* headers stripped "x-amz-meta-" prefix containing the first value. - Metadata map[string]string `json:"metadata,omitempty"` + Metadata []StorageKeyValue `json:"metadata,omitempty"` // Raw metadata headers, eg: x-amz-meta-*, content-encoding etc... Only returned by MinIO servers. - RawMetadata map[string]string `json:"rawMetadata,omitempty"` + RawMetadata []StorageKeyValue `json:"rawMetadata,omitempty"` // User tags - Tags map[string]string `json:"tags,omitempty"` + Tags []StorageKeyValue `json:"tags,omitempty"` // The total count value of tags TagCount int `json:"tagCount,omitempty"` @@ -506,7 +506,7 @@ type StorageRetentionMode string type RemoveStorageObjectError struct { ObjectName string `json:"objectName"` VersionID string `json:"versionId"` - Error error `json:"error"` + Error string `json:"error"` } // ChecksumType contains information about the checksum type. @@ -638,7 +638,7 @@ type ObjectLifecycleFilter struct { MatchesSuffix []string `json:"matchesSuffix,omitempty"` // Tags structure key/value pair representing an object tag to apply configuration - Tags map[string]string `json:"tags,omitempty"` + Tags []StorageKeyValue `json:"tags,omitempty"` ObjectSizeLessThan *int64 `json:"objectSizeLessThan,omitempty"` ObjectSizeGreaterThan *int64 `json:"objectSizeGreaterThan,omitempty"` } @@ -761,11 +761,11 @@ type SourceSelectionCriteria struct { type StorageReplicationFilter struct { Prefix *string `json:"prefix,omitempty"` And *StorageReplicationFilterAnd `json:"and,omitempty"` - Tag map[string]string `json:"tag,omitempty"` + Tag []StorageKeyValue `json:"tag,omitempty"` } // StorageReplicationFilterAnd - a tag to combine a prefix and multiple tags for replication configuration rule. type StorageReplicationFilterAnd struct { Prefix *string `json:"prefix,omitempty"` - Tags map[string]string `json:"tag,omitempty"` + Tags []StorageKeyValue `json:"tag,omitempty"` } diff --git a/connector/storage/common/telemetry.go b/connector/storage/common/telemetry.go index debd81d..35707a1 100644 --- a/connector/storage/common/telemetry.go +++ b/connector/storage/common/telemetry.go @@ -63,7 +63,7 @@ func SetObjectInfoSpanAttributes(span trace.Span, object *StorageObject) { span.SetAttributes(attribute.Int("storage.object.metadata_count", len(object.Metadata))) } - if !object.Expires.IsZero() { + if object.Expires != nil && !object.Expires.IsZero() { span.SetAttributes(attribute.String("storage.object.expires", object.Expires.Format(time.RFC3339))) } diff --git a/connector/storage/common/types.generated.go b/connector/storage/common/types.generated.go index 1c6bb7a..7b93a07 100644 --- a/connector/storage/common/types.generated.go +++ b/connector/storage/common/types.generated.go @@ -35,7 +35,7 @@ func (j *GetStorageObjectArguments) FromValue(input map[string]any) error { // FromValue decodes values from map func (j *GetStorageObjectOptions) FromValue(input map[string]any) error { var err error - j.Headers, err = utils.DecodeObjectValueDefault[map[string]string](input, "headers") + j.Headers, err = utils.DecodeObjectValueDefault[[]StorageKeyValue](input, "headers") if err != nil { return err } @@ -43,7 +43,7 @@ func (j *GetStorageObjectOptions) FromValue(input map[string]any) error { if err != nil { return err } - j.RequestParams, err = utils.DecodeObjectValueDefault[map[string][]string](input, "requestParams") + j.RequestParams, err = utils.DecodeObjectValueDefault[[]StorageKeyValue](input, "requestParams") if err != nil { return err } @@ -159,11 +159,11 @@ func (j *PresignedGetStorageObjectArguments) FromValue(input map[string]any) err // FromValue decodes values from map func (j *PresignedGetStorageObjectOptions) FromValue(input map[string]any) error { var err error - j.Expiry, err = utils.DecodeNullableObjectValue[scalar.Duration](input, "expiry") + j.Expiry, err = utils.DecodeNullableObjectValue[scalar.DurationString](input, "expiry") if err != nil { return err } - j.RequestParams, err = utils.DecodeObjectValueDefault[map[string][]string](input, "requestParams") + j.RequestParams, err = utils.DecodeObjectValueDefault[[]StorageKeyValue](input, "requestParams") if err != nil { return err } @@ -177,7 +177,7 @@ func (j *PresignedPutStorageObjectArguments) FromValue(input map[string]any) err if err != nil { return err } - j.Expiry, err = utils.DecodeNullableObjectValue[scalar.Duration](input, "expiry") + j.Expiry, err = utils.DecodeNullableObjectValue[scalar.DurationString](input, "expiry") if err != nil { return err } @@ -206,6 +206,20 @@ func (j *StorageBucketArguments) FromValue(input map[string]any) error { return nil } +// FromValue decodes values from map +func (j *StorageKeyValue) FromValue(input map[string]any) error { + var err error + j.Key, err = utils.GetString(input, "key") + if err != nil { + return err + } + j.Value, err = utils.GetString(input, "value") + if err != nil { + return err + } + return nil +} + // ToMap encodes the struct to a value map func (j BucketAutoclass) ToMap() map[string]any { r := make(map[string]any) @@ -265,9 +279,17 @@ func (j CustomPlacementConfig) ToMap() map[string]any { // ToMap encodes the struct to a value map func (j GetStorageObjectOptions) ToMap() map[string]any { r := make(map[string]any) - r["headers"] = j.Headers + j_Headers := make([]any, len(j.Headers)) + for i, j_Headers_v := range j.Headers { + j_Headers[i] = j_Headers_v + } + r["headers"] = j_Headers r["partNumber"] = j.PartNumber - r["requestParams"] = j.RequestParams + j_RequestParams := make([]any, len(j.RequestParams)) + for i, j_RequestParams_v := range j.RequestParams { + j_RequestParams[i] = j_RequestParams_v + } + r["requestParams"] = j_RequestParams r["versionId"] = j.VersionID return r @@ -302,7 +324,11 @@ func (j MakeStorageBucketOptions) ToMap() map[string]any { r["name"] = j.Name r["objectLock"] = j.ObjectLock r["region"] = j.Region - r["tags"] = j.Tags + j_Tags := make([]any, len(j.Tags)) + for i, j_Tags_v := range j.Tags { + j_Tags[i] = j_Tags_v + } + r["tags"] = j_Tags return r } @@ -363,7 +389,11 @@ func (j ObjectLifecycleFilter) ToMap() map[string]any { r["matchesSuffix"] = j.MatchesSuffix r["objectSizeGreaterThan"] = j.ObjectSizeGreaterThan r["objectSizeLessThan"] = j.ObjectSizeLessThan - r["tags"] = j.Tags + j_Tags := make([]any, len(j.Tags)) + for i, j_Tags_v := range j.Tags { + j_Tags[i] = j_Tags_v + } + r["tags"] = j_Tags return r } @@ -437,7 +467,11 @@ func (j ObjectLifecycleTransition) ToMap() map[string]any { func (j PresignedGetStorageObjectOptions) ToMap() map[string]any { r := make(map[string]any) r["expiry"] = j.Expiry - r["requestParams"] = j.RequestParams + j_RequestParams := make([]any, len(j.RequestParams)) + for i, j_RequestParams_v := range j.RequestParams { + j_RequestParams[i] = j_RequestParams_v + } + r["requestParams"] = j_RequestParams return r } @@ -466,7 +500,11 @@ func (j PutStorageObjectOptions) ToMap() map[string]any { r["disableMultipart"] = j.DisableMultipart r["expires"] = j.Expires r["legalHold"] = j.LegalHold - r["metadata"] = j.Metadata + j_Metadata := make([]any, len(j.Metadata)) + for i, j_Metadata_v := range j.Metadata { + j_Metadata[i] = j_Metadata_v + } + r["metadata"] = j_Metadata r["numThreads"] = j.NumThreads r["partSize"] = j.PartSize if j.Retention != nil { @@ -474,7 +512,11 @@ func (j PutStorageObjectOptions) ToMap() map[string]any { } r["sendContentMd5"] = j.SendContentMd5 r["storageClass"] = j.StorageClass - r["tags"] = j.Tags + j_Tags := make([]any, len(j.Tags)) + for i, j_Tags_v := range j.Tags { + j_Tags[i] = j_Tags_v + } + r["tags"] = j_Tags r["websiteRedirectLocation"] = j.WebsiteRedirectLocation return r @@ -583,7 +625,11 @@ func (j StorageBucket) ToMap() map[string]any { r["softDeletePolicy"] = (*j.SoftDeletePolicy) } r["storageClass"] = j.StorageClass - r["tags"] = j.Tags + j_Tags := make([]any, len(j.Tags)) + for i, j_Tags_v := range j.Tags { + j_Tags[i] = j_Tags_v + } + r["tags"] = j_Tags if j.Versioning != nil { r["versioning"] = (*j.Versioning) } @@ -619,12 +665,20 @@ func (j StorageCopyDestOptions) ToMap() map[string]any { r := make(map[string]any) r["bucket"] = j.Bucket r["legalHold"] = j.LegalHold - r["metadata"] = j.Metadata + j_Metadata := make([]any, len(j.Metadata)) + for i, j_Metadata_v := range j.Metadata { + j_Metadata[i] = j_Metadata_v + } + r["metadata"] = j_Metadata r["mode"] = j.Mode r["object"] = j.Object r["retainUntilDate"] = j.RetainUntilDate r["size"] = j.Size - r["tags"] = j.Tags + j_Tags := make([]any, len(j.Tags)) + for i, j_Tags_v := range j.Tags { + j_Tags[i] = j_Tags_v + } + r["tags"] = j_Tags return r } @@ -667,6 +721,15 @@ func (j StorageGrantee) ToMap() map[string]any { return r } +// ToMap encodes the struct to a value map +func (j StorageKeyValue) ToMap() map[string]any { + r := make(map[string]any) + r["key"] = j.Key + r["value"] = j.Value + + return r +} + // ToMap encodes the struct to a value map func (j StorageObject) ToMap() map[string]any { r := make(map[string]any) @@ -714,13 +777,21 @@ func (j StorageObject) ToMap() map[string]any { r["leaseStatus"] = j.LeaseStatus r["legalHold"] = j.LegalHold r["mediaLink"] = j.MediaLink - r["metadata"] = j.Metadata + j_Metadata := make([]any, len(j.Metadata)) + for i, j_Metadata_v := range j.Metadata { + j_Metadata[i] = j_Metadata_v + } + r["metadata"] = j_Metadata r["name"] = j.Name if j.Owner != nil { r["owner"] = (*j.Owner) } r["permissions"] = j.Permissions - r["rawMetadata"] = j.RawMetadata + j_RawMetadata := make([]any, len(j.RawMetadata)) + for i, j_RawMetadata_v := range j.RawMetadata { + j_RawMetadata[i] = j_RawMetadata_v + } + r["rawMetadata"] = j_RawMetadata r["rehydratePriority"] = j.RehydratePriority r["remainingRetentionDays"] = j.RemainingRetentionDays r["replicationReady"] = j.ReplicationReady @@ -736,7 +807,11 @@ func (j StorageObject) ToMap() map[string]any { r["size"] = j.Size r["storageClass"] = j.StorageClass r["tagCount"] = j.TagCount - r["tags"] = j.Tags + j_Tags := make([]any, len(j.Tags)) + for i, j_Tags_v := range j.Tags { + j_Tags[i] = j_Tags_v + } + r["tags"] = j_Tags r["versionId"] = j.VersionID return r @@ -867,7 +942,13 @@ func (j UpdateStorageBucketOptions) ToMap() map[string]any { if j.ObjectLock != nil { r["objectLock"] = (*j.ObjectLock) } - r["tags"] = j.Tags + if j.Tags != nil { + j_Tags := make([]any, len((*j.Tags))) + for i, j_Tags_v := range *j.Tags { + j_Tags[i] = j_Tags_v + } + r["tags"] = j_Tags + } r["versioningEnabled"] = j.VersioningEnabled return r @@ -877,11 +958,23 @@ func (j UpdateStorageBucketOptions) ToMap() map[string]any { func (j UpdateStorageObjectOptions) ToMap() map[string]any { r := make(map[string]any) r["legalHold"] = j.LegalHold - r["metadata"] = j.Metadata + if j.Metadata != nil { + j_Metadata := make([]any, len((*j.Metadata))) + for i, j_Metadata_v := range *j.Metadata { + j_Metadata[i] = j_Metadata_v + } + r["metadata"] = j_Metadata + } if j.Retention != nil { r["retention"] = (*j.Retention) } - r["tags"] = j.Tags + if j.Tags != nil { + j_Tags := make([]any, len((*j.Tags))) + for i, j_Tags_v := range *j.Tags { + j_Tags[i] = j_Tags_v + } + r["tags"] = j_Tags + } r["versionId"] = j.VersionID return r diff --git a/connector/storage/common/utils.go b/connector/storage/common/utils.go index 2fa1ac3..d95ef55 100644 --- a/connector/storage/common/utils.go +++ b/connector/storage/common/utils.go @@ -5,8 +5,10 @@ import ( "crypto/md5" "hash" "io" + "net/http" "sync" + "github.com/hasura/ndc-sdk-go/utils" md5simd "github.com/minio/md5-simd" ) @@ -67,3 +69,45 @@ func CalculateContentMd5(reader io.Reader) (io.Reader, []byte, error) { return reader, result, nil } + +// KeyValuesToStringMap converts a storage key value slice to a string map. +func KeyValuesToStringMap(inputs []StorageKeyValue) map[string]string { + result := make(map[string]string) + + for _, item := range inputs { + result[item.Key] = item.Value + } + + return result +} + +// StringMapToKeyValues converts a string map to a key value slice. +func StringMapToKeyValues(inputs map[string]string) []StorageKeyValue { + if len(inputs) == 0 { + return []StorageKeyValue{} + } + + keys := utils.GetSortedKeys(inputs) + result := make([]StorageKeyValue, len(keys)) + + for i, key := range keys { + value := inputs[key] + result[i] = StorageKeyValue{ + Key: key, + Value: value, + } + } + + return result +} + +// KeyValuesToHeader converts a storage key value slice to a http.Header instance. +func KeyValuesToHeaders(inputs []StorageKeyValue) http.Header { + result := http.Header{} + + for _, item := range inputs { + result.Add(item.Key, item.Value) + } + + return result +} diff --git a/connector/storage/config.go b/connector/storage/config.go index e1526ef..4ad3a33 100644 --- a/connector/storage/config.go +++ b/connector/storage/config.go @@ -46,11 +46,6 @@ func (c *Client) ValidateBucket(key string) (string, error) { return c.defaultBucket, nil } -// FormatTimestamp formats the Time value to string -func FormatTimestamp(value time.Time) string { - return value.Format(time.RFC3339) -} - // ClientConfig abstracts a storage client configuration. type ClientConfig map[string]any diff --git a/connector/storage/gcs/bucket.go b/connector/storage/gcs/bucket.go index aefc9e3..1eacdf5 100644 --- a/connector/storage/gcs/bucket.go +++ b/connector/storage/gcs/bucket.go @@ -20,7 +20,7 @@ func (c *Client) MakeBucket(ctx context.Context, args *common.MakeStorageBucketO attrs := &storage.BucketAttrs{ Location: args.Region, - Labels: args.Tags, + Labels: common.KeyValuesToStringMap(args.Tags), Name: args.Name, } @@ -158,18 +158,21 @@ func (c *Client) UpdateBucket(ctx context.Context, bucketName string, opts commo inputAttrs := storage.BucketAttrsToUpdate{} if opts.Tags != nil { - for key, value := range opts.Tags { - span.SetAttributes(attribute.String("storage.bucket_tag"+key, value)) + tagKeys := map[string]bool{} + for _, item := range *opts.Tags { + tagKeys[item.Key] = true + + span.SetAttributes(attribute.String("storage.bucket_tag"+item.Key, item.Value)) } for key := range attrs.Labels { - if _, ok := opts.Tags[key]; !ok { + if _, ok := tagKeys[key]; !ok { inputAttrs.DeleteLabel(key) } } - for key, value := range opts.Tags { - inputAttrs.SetLabel(key, value) + for _, item := range *opts.Tags { + inputAttrs.SetLabel(item.Key, item.Value) } } diff --git a/connector/storage/gcs/config.go b/connector/storage/gcs/config.go index 5baa6fd..97b9ed4 100644 --- a/connector/storage/gcs/config.go +++ b/connector/storage/gcs/config.go @@ -10,6 +10,7 @@ import ( "slices" "strings" + "cloud.google.com/go/storage" "github.com/hasura/ndc-sdk-go/utils" "github.com/hasura/ndc-storage/connector/storage/common" "github.com/invopop/jsonschema" @@ -87,7 +88,10 @@ func (cc ClientConfig) toClientOptions(ctx context.Context, logger *slog.Logger) opts = append(opts, option.WithGRPCConnectionPool(cc.GRPCConnPoolSize)) } } else if utils.IsDebug(logger) { - httpTransport, err := ghttp.NewTransport(ctx, common.NewTransport(logger, port, secure), opts...) + httpTransport, err := ghttp.NewTransport(ctx, + common.NewTransport(logger, port, secure), + append(opts, option.WithScopes(storage.ScopeFullControl, "https://www.googleapis.com/auth/cloud-platform"))..., + ) if err != nil { return nil, err } diff --git a/connector/storage/gcs/object.go b/connector/storage/gcs/object.go index bfee14d..4d8ddaf 100644 --- a/connector/storage/gcs/object.go +++ b/connector/storage/gcs/object.go @@ -177,7 +177,7 @@ func (c *Client) PutObject(ctx context.Context, bucketName string, objectName st w := c.client.Bucket(bucketName).Object(objectName).NewWriter(ctx) w.ChunkSize = chunkSize - w.Metadata = opts.Metadata + w.Metadata = common.KeyValuesToStringMap(opts.Metadata) w.CacheControl = opts.CacheControl w.ContentDisposition = opts.ContentDisposition w.ContentEncoding = opts.ContentEncoding @@ -334,7 +334,7 @@ func (c *Client) RemoveObjects(ctx context.Context, bucketName string, opts *com return []common.RemoveStorageObjectError{ { - Error: err, + Error: err.Error(), }, } } @@ -357,7 +357,7 @@ func (c *Client) RemoveObjects(ctx context.Context, bucketName string, opts *com errs = append(errs, common.RemoveStorageObjectError{ ObjectName: item.Name, VersionID: strconv.Itoa(int(item.Generation)), - Error: err, + Error: err.Error(), }) } } @@ -371,7 +371,7 @@ func (c *Client) RemoveObjects(ctx context.Context, bucketName string, opts *com if err != nil { errs = append(errs, common.RemoveStorageObjectError{ ObjectName: name, - Error: err, + Error: err.Error(), }) } @@ -386,7 +386,7 @@ func (c *Client) RemoveObjects(ctx context.Context, bucketName string, opts *com if err := eg.Wait(); err != nil { return []common.RemoveStorageObjectError{ { - Error: err, + Error: err.Error(), }, } } @@ -442,7 +442,7 @@ func (c *Client) UpdateObject(ctx context.Context, bucketName string, objectName } if opts.Metadata != nil { - updateAttrs.Metadata = opts.Metadata + updateAttrs.Metadata = common.KeyValuesToStringMap(*opts.Metadata) } _, err := handle.Update(ctx, updateAttrs) @@ -487,14 +487,7 @@ func (c *Client) presignObject(ctx context.Context, method string, bucketName st _, span := c.startOtelSpan(ctx, method+" PresignedObject", bucketName) defer span.End() - reqParams := url.Values{} - - for key, params := range opts.RequestParams { - for _, param := range params { - reqParams.Add(key, param) - } - } - + reqParams := url.Values(common.KeyValuesToHeaders(opts.RequestParams)) span.SetAttributes( attribute.String("storage.key", objectName), attribute.String("url.query", reqParams.Encode()), @@ -533,6 +526,6 @@ func (c *Client) presignObject(ctx context.Context, method string, bucketName st // This presigned URL can have an associated expiration time in seconds after which it is no longer operational. The default expiry is set to 7 days. func (c *Client) PresignedPutObject(ctx context.Context, bucketName string, objectName string, expiry time.Duration) (string, error) { return c.presignObject(ctx, http.MethodPut, bucketName, objectName, common.PresignedGetStorageObjectOptions{ - Expiry: &scalar.Duration{Duration: expiry}, + Expiry: &scalar.DurationString{Duration: expiry}, }) } diff --git a/connector/storage/gcs/utils.go b/connector/storage/gcs/utils.go index 450c21b..c370d5f 100644 --- a/connector/storage/gcs/utils.go +++ b/connector/storage/gcs/utils.go @@ -25,7 +25,7 @@ var errNotSupported = schema.NotSupportedError("Google Cloud Storage doesn't sup func serializeBucketInfo(bucket *storage.BucketAttrs) common.StorageBucket { result := common.StorageBucket{ Name: bucket.Name, - Tags: bucket.Labels, + Tags: common.StringMapToKeyValues(bucket.Labels), CORS: make([]common.BucketCors, len(bucket.CORS)), CreationTime: &bucket.Created, LastModified: &bucket.Updated, @@ -62,7 +62,7 @@ func serializeBucketInfo(bucket *storage.BucketAttrs) common.StorageBucket { for i, cors := range bucket.CORS { result.CORS[i] = common.BucketCors{ - MaxAge: scalar.NewDuration(cors.MaxAge), + MaxAge: scalar.NewDurationString(cors.MaxAge), Methods: cors.Methods, Origins: cors.Origins, ResponseHeaders: cors.ResponseHeaders, @@ -96,7 +96,7 @@ func serializeBucketInfo(bucket *storage.BucketAttrs) common.StorageBucket { if bucket.SoftDeletePolicy != nil { result.SoftDeletePolicy = &common.StorageObjectSoftDeletePolicy{ EffectiveTime: bucket.SoftDeletePolicy.EffectiveTime, - RetentionDuration: scalar.NewDuration(bucket.SoftDeletePolicy.RetentionDuration), + RetentionDuration: scalar.NewDurationString(bucket.SoftDeletePolicy.RetentionDuration), } } @@ -150,7 +150,7 @@ func serializeObjectInfo(obj *storage.ObjectAttrs) common.StorageObject { //noli CreationTime: &obj.Created, LastModified: obj.Updated, Size: &obj.Size, - Metadata: obj.Metadata, + Metadata: common.StringMapToKeyValues(obj.Metadata), LegalHold: &obj.TemporaryHold, } diff --git a/connector/storage/minio/bucket.go b/connector/storage/minio/bucket.go index 1fed8e1..14552d7 100644 --- a/connector/storage/minio/bucket.go +++ b/connector/storage/minio/bucket.go @@ -34,7 +34,7 @@ func (mc *Client) MakeBucket(ctx context.Context, args *common.MakeStorageBucket } if len(args.Tags) > 0 { - if err := mc.SetBucketTagging(ctx, args.Name, args.Tags); err != nil { + if err := mc.SetBucketTagging(ctx, args.Name, common.KeyValuesToStringMap(args.Tags)); err != nil { span.SetStatus(codes.Error, err.Error()) span.RecordError(err) @@ -199,7 +199,7 @@ func (mc *Client) UpdateBucket(ctx context.Context, bucketName string, opts comm defer span.End() if opts.Tags != nil { - if err := mc.SetBucketTagging(ctx, bucketName, opts.Tags); err != nil { + if err := mc.SetBucketTagging(ctx, bucketName, common.KeyValuesToStringMap(*opts.Tags)); err != nil { return err } } @@ -619,9 +619,9 @@ func validateBucketReplicationFilter(input common.StorageReplicationFilter) repl } if len(input.Tag) > 0 { - for key, value := range input.Tag { - result.Tag.Key = key - result.Tag.Value = value + for _, item := range input.Tag { + result.Tag.Key = item.Key + result.Tag.Value = item.Value break } @@ -632,10 +632,10 @@ func validateBucketReplicationFilter(input common.StorageReplicationFilter) repl result.And.Prefix = *input.Prefix } - for key, value := range input.And.Tags { + for _, item := range input.And.Tags { t := replication.Tag{ - Key: key, - Value: value, + Key: item.Key, + Value: item.Value, } result.And.Tags = append(result.And.Tags, t) @@ -704,8 +704,11 @@ func serializeBucketReplicationRule(item replication.Rule) common.StorageReplica } if item.Filter.Tag.Key != "" || item.Filter.Tag.Value != "" { - rule.Filter.Tag = map[string]string{ - item.Filter.Tag.Key: item.Filter.Tag.Value, + rule.Filter.Tag = []common.StorageKeyValue{ + { + Key: item.Filter.Tag.Key, + Value: item.Filter.Tag.Value, + }, } } @@ -715,10 +718,11 @@ func serializeBucketReplicationRule(item replication.Rule) common.StorageReplica rule.Filter.And.Prefix = &item.Filter.Prefix } - rule.Filter.And.Tags = make(map[string]string) - for _, tag := range item.Filter.And.Tags { - rule.Filter.And.Tags[tag.Key] = tag.Value + rule.Filter.And.Tags = append(rule.Filter.And.Tags, common.StorageKeyValue{ + Key: tag.Key, + Value: tag.Value, + }) } } @@ -737,7 +741,7 @@ func (mc *Client) populateBucket(ctx context.Context, item minio.BucketInfo, opt return bucket, err } - bucket.Tags = tags + bucket.Tags = common.StringMapToKeyValues(tags) } if options.Include.Versioning { diff --git a/connector/storage/minio/lifecycle.go b/connector/storage/minio/lifecycle.go index 5dafaf9..b29b597 100644 --- a/connector/storage/minio/lifecycle.go +++ b/connector/storage/minio/lifecycle.go @@ -181,17 +181,17 @@ func validateLifecycleFilters(input []common.ObjectLifecycleFilter) lifecycle.Fi return result } - for key, value := range input[0].Tags { + for _, item := range input[0].Tags { if result.Tag.Key == "" { - result.Tag.Key = key - result.Tag.Value = value + result.Tag.Key = item.Key + result.Tag.Value = item.Value continue } result.And.Tags = append(result.And.Tags, lifecycle.Tag{ - Key: key, - Value: value, + Key: item.Key, + Value: item.Value, }) } @@ -211,10 +211,10 @@ func validateLifecycleFilters(input []common.ObjectLifecycleFilter) lifecycle.Fi return result } - for key, value := range input[1].Tags { + for _, item := range input[1].Tags { result.And.Tags = append(result.And.Tags, lifecycle.Tag{ - Key: key, - Value: value, + Key: item.Key, + Value: item.Value, }) } @@ -361,8 +361,11 @@ func serializeLifecycleFilter(input lifecycle.Filter) []common.ObjectLifecycleFi } if input.Tag.Key != "" || input.Tag.Value != "" { - firstItem.Tags = map[string]string{ - input.Tag.Key: input.Tag.Value, + firstItem.Tags = []common.StorageKeyValue{ + { + Key: input.Tag.Key, + Value: input.Tag.Value, + }, } } @@ -385,14 +388,15 @@ func serializeLifecycleFilter(input lifecycle.Filter) []common.ObjectLifecycleFi sndItem.ObjectSizeLessThan = &input.And.ObjectSizeLessThan } - sndItem.Tags = make(map[string]string) - for _, t := range input.And.Tags { if t.IsEmpty() { continue } - sndItem.Tags[t.Key] = t.Value + sndItem.Tags = append(sndItem.Tags, common.StorageKeyValue{ + Key: t.Key, + Value: t.Value, + }) } result = append(result, sndItem) diff --git a/connector/storage/minio/object.go b/connector/storage/minio/object.go index f7d2709..dd035a2 100644 --- a/connector/storage/minio/object.go +++ b/connector/storage/minio/object.go @@ -231,8 +231,8 @@ func (mc *Client) PutObject(ctx context.Context, bucketName string, objectName s ) options := minio.PutObjectOptions{ - UserMetadata: opts.Metadata, - UserTags: opts.Tags, + UserMetadata: common.KeyValuesToStringMap(opts.Metadata), + UserTags: common.KeyValuesToStringMap(opts.Tags), ContentType: opts.ContentType, ContentEncoding: opts.ContentEncoding, ContentDisposition: opts.ContentDisposition, @@ -449,7 +449,7 @@ func (mc *Client) RemoveObjects(ctx context.Context, bucketName string, opts *co errs = append(errs, common.RemoveStorageObjectError{ ObjectName: err.ObjectName, VersionID: err.VersionID, - Error: err.Err, + Error: err.Err.Error(), }) } @@ -474,7 +474,7 @@ func (mc *Client) UpdateObject(ctx context.Context, bucketName string, objectNam } if opts.Tags != nil { - if err := mc.SetObjectTags(ctx, bucketName, objectName, opts.VersionID, opts.Tags); err != nil { + if err := mc.SetObjectTags(ctx, bucketName, objectName, opts.VersionID, common.KeyValuesToStringMap(*opts.Tags)); err != nil { return err } } @@ -696,20 +696,16 @@ func (mc *Client) presignObject(ctx context.Context, method string, bucketName s ctx, span := mc.startOtelSpan(ctx, method+" PresignedObject", bucketName) defer span.End() - reqParams := url.Values{} - - for key, params := range opts.RequestParams { - for _, param := range params { - reqParams.Add(key, param) - } - } + reqParams := url.Values(common.KeyValuesToHeaders(opts.RequestParams)) span.SetAttributes( attribute.String("storage.key", objectName), attribute.String("url.query", reqParams.Encode()), ) - if opts.Expiry != nil { + expiry := time.Hour + if opts.Expiry != nil && opts.Expiry.Duration > 0 { + expiry = opts.Expiry.Duration span.SetAttributes(attribute.String("storage.expiry", opts.Expiry.String())) } @@ -725,7 +721,7 @@ func (mc *Client) presignObject(ctx context.Context, method string, bucketName s header.Set("Host", mc.publicHost.Host) } - result, err = mc.client.PresignHeader(ctx, method, bucketName, objectName, opts.Expiry.Duration, reqParams, header) + result, err = mc.client.PresignHeader(ctx, method, bucketName, objectName, expiry, reqParams, header) if err != nil { span.SetStatus(codes.Error, err.Error()) span.RecordError(err) @@ -846,7 +842,7 @@ func (mc *Client) populateObject(ctx context.Context, result *common.StorageObje return err } - result.Tags = userTags + result.Tags = common.StringMapToKeyValues(userTags) } if include.LegalHold { diff --git a/connector/storage/minio/utils.go b/connector/storage/minio/utils.go index 35e3739..dbfde60 100644 --- a/connector/storage/minio/utils.go +++ b/connector/storage/minio/utils.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/hasura/ndc-sdk-go/schema" + "github.com/hasura/ndc-sdk-go/utils" "github.com/hasura/ndc-storage/connector/storage/common" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/notification" @@ -71,9 +72,7 @@ func serializeObjectInfo(obj *minio.ObjectInfo, fromList bool) common.StorageObj Name: obj.Key, LastModified: obj.LastModified, Size: &obj.Size, - Metadata: map[string]string{}, - RawMetadata: map[string]string{}, - Tags: obj.UserTags, + Tags: common.StringMapToKeyValues(obj.UserTags), TagCount: obj.UserTagCount, Grant: grants, IsLatest: &obj.IsLatest, @@ -88,12 +87,15 @@ func serializeObjectInfo(obj *minio.ObjectInfo, fromList bool) common.StorageObj } if fromList { - object.RawMetadata = obj.UserMetadata + object.RawMetadata = common.StringMapToKeyValues(obj.UserMetadata) for key, value := range obj.UserMetadata { lowerKey := strings.ToLower(key) if strings.HasPrefix(lowerKey, userMetadataHeaderPrefix) { - object.Metadata[key[len(userMetadataHeaderPrefix):]] = value + object.Metadata = append(object.Metadata, common.StorageKeyValue{ + Key: key[len(userMetadataHeaderPrefix):], + Value: value, + }) } switch lowerKey { @@ -110,15 +112,21 @@ func serializeObjectInfo(obj *minio.ObjectInfo, fromList bool) common.StorageObj } } } else { - object.Metadata = obj.UserMetadata + object.Metadata = common.StringMapToKeyValues(obj.UserMetadata) + keys := utils.GetSortedKeys(obj.Metadata) + + for _, key := range keys { + values := obj.Metadata[key] - for key, values := range obj.Metadata { if len(values) == 0 { continue } value := strings.Join(values, ", ") - object.RawMetadata[key] = value + object.RawMetadata = append(object.RawMetadata, common.StorageKeyValue{ + Key: key, + Value: value, + }) switch strings.ToLower(key) { case common.HeaderContentType: @@ -298,19 +306,17 @@ func serializeGetObjectOptions(span trace.Span, opts common.GetStorageObjectOpti span.SetAttributes(attribute.Int("storage.part_number", options.PartNumber)) } - for key, value := range opts.Headers { - span.SetAttributes(attribute.StringSlice("http.request.header."+key, []string{value})) - options.Set(key, value) + for _, item := range opts.Headers { + span.SetAttributes(attribute.StringSlice("http.request.header."+item.Key, []string{item.Value})) + options.Set(item.Key, item.Value) } if len(opts.RequestParams) > 0 { q := url.Values{} - for key, values := range opts.RequestParams { - for _, value := range values { - options.AddReqParam(key, value) - q.Add(key, value) - } + for _, item := range opts.RequestParams { + options.AddReqParam(item.Key, item.Value) + q.Add(item.Key, item.Value) } span.SetAttributes(attribute.String("url.query", q.Encode())) @@ -346,9 +352,9 @@ func convertCopyDestOptions(dst common.StorageCopyDestOptions) *minio.CopyDestOp destOptions := minio.CopyDestOptions{ Bucket: dst.Bucket, Object: dst.Object, - UserMetadata: dst.Metadata, + UserMetadata: common.KeyValuesToStringMap(dst.Metadata), ReplaceMetadata: dst.Metadata != nil, - UserTags: dst.Tags, + UserTags: common.KeyValuesToStringMap(dst.Tags), ReplaceTags: dst.Tags != nil, Size: dst.Size, LegalHold: validateLegalHoldStatus(dst.LegalHold), diff --git a/connector/storage/object.go b/connector/storage/object.go index bdb707c..8ad3f81 100644 --- a/connector/storage/object.go +++ b/connector/storage/object.go @@ -263,6 +263,7 @@ func (m *Manager) PresignedGetObject(ctx context.Context, bucketInfo common.Stor exp = opts.Expiry.Duration } else if client.defaultPresignedExpiry != nil { exp = *client.defaultPresignedExpiry + opts.Expiry = &scalar.DurationString{Duration: exp} } if exp == 0 { @@ -276,7 +277,7 @@ func (m *Manager) PresignedGetObject(ctx context.Context, bucketInfo common.Stor return &common.PresignedURLResponse{ URL: rawURL, - ExpiredAt: FormatTimestamp(time.Now().Add(opts.Expiry.Duration)), + ExpiredAt: time.Now().Add(exp), }, nil } @@ -284,7 +285,7 @@ func (m *Manager) PresignedGetObject(ctx context.Context, bucketInfo common.Stor // Browsers/Mobile clients may point to this URL to upload objects directly to a bucket even if it is private. // This presigned URL can have an associated expiration time in seconds after which it is no longer operational. // The default expiry is set to 7 days. -func (m *Manager) PresignedPutObject(ctx context.Context, bucketInfo common.StorageBucketArguments, objectName string, expiry *scalar.Duration) (*common.PresignedURLResponse, error) { +func (m *Manager) PresignedPutObject(ctx context.Context, bucketInfo common.StorageBucketArguments, objectName string, expiry *scalar.DurationString) (*common.PresignedURLResponse, error) { if err := s3utils.CheckValidObjectName(objectName); err != nil { return nil, schema.UnprocessableContentError(err.Error(), nil) } @@ -313,6 +314,6 @@ func (m *Manager) PresignedPutObject(ctx context.Context, bucketInfo common.Stor return &common.PresignedURLResponse{ URL: rawURL, - ExpiredAt: FormatTimestamp(time.Now().Add(exp)), + ExpiredAt: time.Now().Add(exp), }, nil } diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-azblob/expected.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-azblob/expected.json index e28c88a..fb198e9 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-azblob/expected.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-azblob/expected.json @@ -1,8 +1,3 @@ { - "operation_results": [ - { - "result": true, - "type": "procedure" - } - ] -} \ No newline at end of file + "operation_results": [{ "result": { "success": true }, "type": "procedure" }] +} diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-azblob/request.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-azblob/request.json index 7b6dcdc..aac4135 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-azblob/request.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-azblob/request.json @@ -8,9 +8,21 @@ "clientId": "azblob", "name": "azblob-bucket-test", "objectLock": true, - "tags": { - "provider": "azure" - } + "tags": [ + { + "key": "provider", + "value": "azure" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-empty/expected.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-empty/expected.json index e28c88a..fb198e9 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-empty/expected.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-empty/expected.json @@ -1,8 +1,3 @@ { - "operation_results": [ - { - "result": true, - "type": "procedure" - } - ] -} \ No newline at end of file + "operation_results": [{ "result": { "success": true }, "type": "procedure" }] +} diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-empty/request.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-empty/request.json index 42b7983..8b9b92b 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-empty/request.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-empty/request.json @@ -8,6 +8,15 @@ "clientId": "minio", "name": "minio-bucket-empty", "region": "us-east-1" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-gcs/expected.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-gcs/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-gcs/expected.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-gcs/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-gcs/request.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-gcs/request.json index 7e8bc3e..f4cd004 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-gcs/request.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-gcs/request.json @@ -8,9 +8,21 @@ "clientId": "gcs", "name": "gcs-bucket", "objectLock": true, - "tags": { - "provider": "gcp" - } + "tags": [ + { + "key": "provider", + "value": "gcp" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-lock/expected.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-lock/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-lock/expected.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-lock/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-lock/request.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-lock/request.json index 9ee3ce1..4ebf9a8 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-lock/request.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-lock/request.json @@ -9,6 +9,15 @@ "name": "minio-bucket-lock", "objectLock": true, "region": "us-east-1" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-s3/expected.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-s3/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-s3/expected.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-s3/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket-s3/request.json b/connector/testdata/01-setup/mutation/01-createStorageBucket-s3/request.json index 7c36c84..88cec12 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket-s3/request.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket-s3/request.json @@ -9,6 +9,15 @@ "name": "s3-bucket-test", "objectLock": true, "region": "us-east-1" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket/expected.json b/connector/testdata/01-setup/mutation/01-createStorageBucket/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket/expected.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/01-setup/mutation/01-createStorageBucket/request.json b/connector/testdata/01-setup/mutation/01-createStorageBucket/request.json index ff87e31..1b451f9 100644 --- a/connector/testdata/01-setup/mutation/01-createStorageBucket/request.json +++ b/connector/testdata/01-setup/mutation/01-createStorageBucket/request.json @@ -9,9 +9,21 @@ "name": "minio-bucket-test", "objectLock": false, "region": "us-east-1", - "tags": { - "UserID": "1" - } + "tags": [ + { + "key": "UserID", + "value": "1" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/02-updateStorageBucket-azblob/expected.json b/connector/testdata/01-setup/mutation/02-updateStorageBucket-azblob/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/02-updateStorageBucket-azblob/expected.json +++ b/connector/testdata/01-setup/mutation/02-updateStorageBucket-azblob/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/01-setup/mutation/02-updateStorageBucket-azblob/request.json b/connector/testdata/01-setup/mutation/02-updateStorageBucket-azblob/request.json index 2a03f0e..d802b81 100644 --- a/connector/testdata/01-setup/mutation/02-updateStorageBucket-azblob/request.json +++ b/connector/testdata/01-setup/mutation/02-updateStorageBucket-azblob/request.json @@ -7,9 +7,21 @@ "arguments": { "clientId": "azblob", "bucket": "azblob-bucket-test", - "tags": { - "Foo": "baz" - } + "tags": [ + { + "key": "Foo", + "value": "baz" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/02-updateStorageBucket-gcs/expected.json b/connector/testdata/01-setup/mutation/02-updateStorageBucket-gcs/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/02-updateStorageBucket-gcs/expected.json +++ b/connector/testdata/01-setup/mutation/02-updateStorageBucket-gcs/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/01-setup/mutation/02-updateStorageBucket-gcs/request.json b/connector/testdata/01-setup/mutation/02-updateStorageBucket-gcs/request.json index 8623f28..6545f22 100644 --- a/connector/testdata/01-setup/mutation/02-updateStorageBucket-gcs/request.json +++ b/connector/testdata/01-setup/mutation/02-updateStorageBucket-gcs/request.json @@ -7,9 +7,21 @@ "arguments": { "clientId": "gcs", "bucket": "gcs-bucket", - "tags": { - "Foo": "gcs-bar" - } + "tags": [ + { + "key": "Foo", + "value": "gcs-bar" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/02-updateStorageBucket/expected.json b/connector/testdata/01-setup/mutation/02-updateStorageBucket/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/02-updateStorageBucket/expected.json +++ b/connector/testdata/01-setup/mutation/02-updateStorageBucket/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/01-setup/mutation/02-updateStorageBucket/request.json b/connector/testdata/01-setup/mutation/02-updateStorageBucket/request.json index 57b3d0a..c67dc92 100644 --- a/connector/testdata/01-setup/mutation/02-updateStorageBucket/request.json +++ b/connector/testdata/01-setup/mutation/02-updateStorageBucket/request.json @@ -27,17 +27,23 @@ "objectSizeGreaterThan": 1000000, "objectSizeLessThan": 1, "matchesPrefix": ["30LomArtyT"], - "tags": { - "raZx9yPMwi": "JbBh0wCDaQ" - } + "tags": [ + { + "key": "raZx9yPMwi", + "value": "JbBh0wCDaQ" + } + ] }, { "objectSizeGreaterThan": 1000000, "objectSizeLessThan": 1, "matchesPrefix": ["JSqXP0pJZF"], - "tags": { - "7Uw1or2jrq": "00sA2cRTCB" - } + "tags": [ + { + "key": "7Uw1or2jrq", + "value": "00sA2cRTCB" + } + ] } ], "id": "aXD6eFi5JE", @@ -57,9 +63,21 @@ } ] }, - "tags": { - "Foo": "bar" - } + "tags": [ + { + "key": "Foo", + "value": "bar" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/03-uploadStorageObject-2/request.json b/connector/testdata/01-setup/mutation/03-uploadStorageObject-2/request.json index 511e3c4..4676136 100644 --- a/connector/testdata/01-setup/mutation/03-uploadStorageObject-2/request.json +++ b/connector/testdata/01-setup/mutation/03-uploadStorageObject-2/request.json @@ -25,12 +25,18 @@ "partSize": 3573915715657741285, "sendContentMd5": false, "storageClass": "STANDARD", - "metadata": { - "Foo": "Bar" - }, - "tags": { - "UserID": "1" - }, + "metadata": [ + { + "key": "Foo", + "value": "Bar" + } + ], + "tags": [ + { + "key": "UserID", + "value": "1" + } + ], "websiteRedirectLocation": "http://localhost:9001" } }, diff --git a/connector/testdata/01-setup/mutation/03-uploadStorageObject-3/request.json b/connector/testdata/01-setup/mutation/03-uploadStorageObject-3/request.json index d8f8c80..e058c16 100644 --- a/connector/testdata/01-setup/mutation/03-uploadStorageObject-3/request.json +++ b/connector/testdata/01-setup/mutation/03-uploadStorageObject-3/request.json @@ -25,12 +25,18 @@ "partSize": 3573915715657741285, "sendContentMd5": false, "storageClass": "STANDARD", - "metadata": { - "Foo": "Bar" - }, - "tags": { - "UserID": "1" - }, + "metadata": [ + { + "key": "Foo", + "value": "Bar" + } + ], + "tags": [ + { + "key": "UserID", + "value": "1" + } + ], "websiteRedirectLocation": "http://localhost:9001" } }, diff --git a/connector/testdata/01-setup/mutation/03-uploadStorageObject-azblob/request.json b/connector/testdata/01-setup/mutation/03-uploadStorageObject-azblob/request.json index 109b6ad..e0a0c4f 100644 --- a/connector/testdata/01-setup/mutation/03-uploadStorageObject-azblob/request.json +++ b/connector/testdata/01-setup/mutation/03-uploadStorageObject-azblob/request.json @@ -25,12 +25,18 @@ "partSize": 1024000000, "sendContentMd5": true, "storageClass": "Cool", - "metadata": { - "Foo": "Bar" - }, - "tags": { - "UserID": "1" - }, + "metadata": [ + { + "key": "Foo", + "value": "Bar" + } + ], + "tags": [ + { + "key": "UserID", + "value": "1" + } + ], "websiteRedirectLocation": "http://localhost:9001" } }, diff --git a/connector/testdata/01-setup/mutation/03-uploadStorageObject-gcs/request.json b/connector/testdata/01-setup/mutation/03-uploadStorageObject-gcs/request.json index 8a88a90..bf13448 100644 --- a/connector/testdata/01-setup/mutation/03-uploadStorageObject-gcs/request.json +++ b/connector/testdata/01-setup/mutation/03-uploadStorageObject-gcs/request.json @@ -26,12 +26,18 @@ "partSize": 1024000000, "sendContentMd5": true, "storageClass": "Cool", - "metadata": { - "Foo": "Bar" - }, - "tags": { - "UserID": "1" - }, + "metadata": [ + { + "key": "Foo", + "value": "Bar" + } + ], + "tags": [ + { + "key": "UserID", + "value": "1" + } + ], "websiteRedirectLocation": "http://localhost:9001" } }, diff --git a/connector/testdata/01-setup/mutation/03-uploadStorageObject/request.json b/connector/testdata/01-setup/mutation/03-uploadStorageObject/request.json index 74cd9cd..101d303 100644 --- a/connector/testdata/01-setup/mutation/03-uploadStorageObject/request.json +++ b/connector/testdata/01-setup/mutation/03-uploadStorageObject/request.json @@ -25,12 +25,18 @@ "partSize": 3573915715657741285, "sendContentMd5": false, "storageClass": "STANDARD", - "metadata": { - "Foo": "Bar" - }, - "tags": { - "UserID": "1" - }, + "metadata": [ + { + "key": "Foo", + "value": "Bar" + } + ], + "tags": [ + { + "key": "UserID", + "value": "1" + } + ], "websiteRedirectLocation": "http://localhost:9001" } }, diff --git a/connector/testdata/01-setup/mutation/03-uploadStorageObjectText/request.json b/connector/testdata/01-setup/mutation/03-uploadStorageObjectText/request.json index 779ae29..9d8c004 100644 --- a/connector/testdata/01-setup/mutation/03-uploadStorageObjectText/request.json +++ b/connector/testdata/01-setup/mutation/03-uploadStorageObjectText/request.json @@ -30,12 +30,18 @@ "partSize": 35739157156577, "sendContentMd5": false, "storageClass": "STANDARD", - "metadata": { - "Foo": "Baz" - }, - "tags": { - "UserID": "2" - }, + "metadata": [ + { + "key": "Foo", + "value": "Bar" + } + ], + "tags": [ + { + "key": "UserID", + "value": "2" + } + ], "websiteRedirectLocation": "http://localhost:9001" } }, diff --git a/connector/testdata/01-setup/mutation/04-copyStorageObject-azblob/request.json b/connector/testdata/01-setup/mutation/04-copyStorageObject-azblob/request.json index 1a93986..b95c22b 100644 --- a/connector/testdata/01-setup/mutation/04-copyStorageObject-azblob/request.json +++ b/connector/testdata/01-setup/mutation/04-copyStorageObject-azblob/request.json @@ -9,12 +9,18 @@ "bucket": "azblob-bucket-test", "object": "public/hello2.txt", "size": 8502136105187820186, - "metadata": { - "UserID": "2" - }, - "tags": { - "Copy": "true" - } + "metadata": [ + { + "key": "UserID", + "value": "2" + } + ], + "tags": [ + { + "key": "Copy", + "value": "true" + } + ] }, "source": { "bucket": "azblob-bucket-test", diff --git a/connector/testdata/01-setup/mutation/04-copyStorageObject-gcs/request.json b/connector/testdata/01-setup/mutation/04-copyStorageObject-gcs/request.json index deeccd7..737429c 100644 --- a/connector/testdata/01-setup/mutation/04-copyStorageObject-gcs/request.json +++ b/connector/testdata/01-setup/mutation/04-copyStorageObject-gcs/request.json @@ -10,12 +10,18 @@ "bucket": "gcs-bucket", "object": "public/hello2.txt", "size": 8502136105187820186, - "metadata": { - "UserID": "2" - }, - "tags": { - "Copy": "true" - } + "metadata": [ + { + "key": "UserID", + "value": "2" + } + ], + "tags": [ + { + "key": "Copy", + "value": "true" + } + ] }, "source": { "bucket": "gcs-bucket", diff --git a/connector/testdata/01-setup/mutation/04-copyStorageObject/request.json b/connector/testdata/01-setup/mutation/04-copyStorageObject/request.json index 55b4b82..c783a10 100644 --- a/connector/testdata/01-setup/mutation/04-copyStorageObject/request.json +++ b/connector/testdata/01-setup/mutation/04-copyStorageObject/request.json @@ -9,12 +9,18 @@ "bucket": "minio-bucket-test", "object": "public/workd2.txt", "size": 8502136105187820186, - "metadata": { - "UserID": "2" - }, - "tags": { - "Copy": "true" - } + "metadata": [ + { + "key": "UserID", + "value": "2" + } + ], + "tags": [ + { + "key": "Copy", + "value": "true" + } + ] }, "source": { "bucket": "minio-bucket-test", diff --git a/connector/testdata/01-setup/mutation/05-updateStorageBucketRetention/expected.json b/connector/testdata/01-setup/mutation/05-updateStorageBucketRetention/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/05-updateStorageBucketRetention/expected.json +++ b/connector/testdata/01-setup/mutation/05-updateStorageBucketRetention/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/01-setup/mutation/05-updateStorageBucketRetention/request.json b/connector/testdata/01-setup/mutation/05-updateStorageBucketRetention/request.json index fd9f827..9d5bf28 100644 --- a/connector/testdata/01-setup/mutation/05-updateStorageBucketRetention/request.json +++ b/connector/testdata/01-setup/mutation/05-updateStorageBucketRetention/request.json @@ -12,6 +12,15 @@ "unit": "DAYS", "validity": 1 } + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/06-setStorageObjectRetention/expected.json b/connector/testdata/01-setup/mutation/06-setStorageObjectRetention/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/06-setStorageObjectRetention/expected.json +++ b/connector/testdata/01-setup/mutation/06-setStorageObjectRetention/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/01-setup/mutation/06-setStorageObjectRetention/request.json b/connector/testdata/01-setup/mutation/06-setStorageObjectRetention/request.json index 9de4729..c95138f 100644 --- a/connector/testdata/01-setup/mutation/06-setStorageObjectRetention/request.json +++ b/connector/testdata/01-setup/mutation/06-setStorageObjectRetention/request.json @@ -12,6 +12,15 @@ "mode": "Locked", "retainUntilDate": "2099-01-01T00:00:00Z" } + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/07-setStorageObjectTags-azblob/expected.json b/connector/testdata/01-setup/mutation/07-setStorageObjectTags-azblob/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/07-setStorageObjectTags-azblob/expected.json +++ b/connector/testdata/01-setup/mutation/07-setStorageObjectTags-azblob/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/01-setup/mutation/07-setStorageObjectTags-azblob/request.json b/connector/testdata/01-setup/mutation/07-setStorageObjectTags-azblob/request.json index 291692c..f5fa6dd 100644 --- a/connector/testdata/01-setup/mutation/07-setStorageObjectTags-azblob/request.json +++ b/connector/testdata/01-setup/mutation/07-setStorageObjectTags-azblob/request.json @@ -7,10 +7,25 @@ "arguments": { "bucket": "azblob-bucket-test", "object": "public/hello.txt", - "tags": { - "Foo": "baz", - "UserID": "3" - } + "tags": [ + { + "key": "Foo", + "value": "baz" + }, + { + "key": "UserID", + "value": "3" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/07-setStorageObjectTags/expected.json b/connector/testdata/01-setup/mutation/07-setStorageObjectTags/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/07-setStorageObjectTags/expected.json +++ b/connector/testdata/01-setup/mutation/07-setStorageObjectTags/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/01-setup/mutation/07-setStorageObjectTags/request.json b/connector/testdata/01-setup/mutation/07-setStorageObjectTags/request.json index 9fed04a..b03bb4b 100644 --- a/connector/testdata/01-setup/mutation/07-setStorageObjectTags/request.json +++ b/connector/testdata/01-setup/mutation/07-setStorageObjectTags/request.json @@ -7,10 +7,25 @@ "arguments": { "bucket": "minio-bucket-test", "object": "public/workd2.txt", - "tags": { - "Foo": "baz", - "UserID": "3" - } + "tags": [ + { + "key": "Foo", + "value": "baz" + }, + { + "key": "UserID", + "value": "3" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/01-setup/mutation/07-updateStorageObject-gcs/expected.json b/connector/testdata/01-setup/mutation/07-updateStorageObject-gcs/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/01-setup/mutation/07-updateStorageObject-gcs/expected.json +++ b/connector/testdata/01-setup/mutation/07-updateStorageObject-gcs/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/01-setup/mutation/07-updateStorageObject-gcs/request.json b/connector/testdata/01-setup/mutation/07-updateStorageObject-gcs/request.json index 6919975..837a5b6 100644 --- a/connector/testdata/01-setup/mutation/07-updateStorageObject-gcs/request.json +++ b/connector/testdata/01-setup/mutation/07-updateStorageObject-gcs/request.json @@ -8,10 +8,25 @@ "clientId": "gcs", "bucket": "gcs-bucket", "object": "public/hello.txt", - "metadata": { - "Foo": "gcp-baz", - "UserID": "3" - } + "metadata": [ + { + "key": "Foo", + "value": "gcp-baz" + }, + { + "key": "UserID", + "value": "3" + } + ] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/02-get/query/downloadStorageObject/expected.json b/connector/testdata/02-get/query/downloadStorageObject/expected.json index 2a658ff..d7f5832 100644 --- a/connector/testdata/02-get/query/downloadStorageObject/expected.json +++ b/connector/testdata/02-get/query/downloadStorageObject/expected.json @@ -1 +1 @@ -[{ "rows": [{ "__value": "SVpHWjhMMHZzVw==" }] }] +[{ "rows": [{ "__value": { "data": "SVpHWjhMMHZzVw==" } }] }] diff --git a/connector/testdata/02-get/query/downloadStorageObject/request.json b/connector/testdata/02-get/query/downloadStorageObject/request.json index 831534f..c16fecd 100644 --- a/connector/testdata/02-get/query/downloadStorageObject/request.json +++ b/connector/testdata/02-get/query/downloadStorageObject/request.json @@ -35,6 +35,15 @@ "fields": { "__value": { "column": "__value", + "fields": { + "fields": { + "data": { + "column": "data", + "type": "column" + } + }, + "type": "object" + }, "type": "column" } } diff --git a/connector/testdata/02-get/query/downloadStorageObjectText/expected.json b/connector/testdata/02-get/query/downloadStorageObjectText/expected.json index 1923f9d..4456202 100644 --- a/connector/testdata/02-get/query/downloadStorageObjectText/expected.json +++ b/connector/testdata/02-get/query/downloadStorageObjectText/expected.json @@ -1 +1 @@ -[{ "rows": [{ "__value": "IZGZ8L0vsW" }] }] +[{ "rows": [{ "__value": { "data": "IZGZ8L0vsW" } }] }] diff --git a/connector/testdata/02-get/query/downloadStorageObjectText/request.json b/connector/testdata/02-get/query/downloadStorageObjectText/request.json index a484050..7323d2f 100644 --- a/connector/testdata/02-get/query/downloadStorageObjectText/request.json +++ b/connector/testdata/02-get/query/downloadStorageObjectText/request.json @@ -35,6 +35,15 @@ "fields": { "__value": { "column": "__value", + "fields": { + "fields": { + "data": { + "column": "data", + "type": "column" + } + }, + "type": "object" + }, "type": "column" } } diff --git a/connector/testdata/02-get/query/storageBucket/expected.json b/connector/testdata/02-get/query/storageBucket/expected.json index 0734cbc..46e5a3c 100644 --- a/connector/testdata/02-get/query/storageBucket/expected.json +++ b/connector/testdata/02-get/query/storageBucket/expected.json @@ -10,6 +10,7 @@ "encryption": null, "etag": null, "hierarchicalNamespace": null, + "lastModified": null, "lifecycle": { "rules": [ { @@ -30,7 +31,7 @@ "matchesSuffix": null, "objectSizeGreaterThan": null, "objectSizeLessThan": null, - "tags": null + "tags": [] }, { "matchesPrefix": ["JSqXP0pJZF"], @@ -38,9 +39,7 @@ "matchesSuffix": null, "objectSizeGreaterThan": 1000000, "objectSizeLessThan": 1, - "tags": { - "7Uw1or2jrq": "00sA2cRTCB" - } + "tags": [{ "key": "7Uw1or2jrq", "value": "00sA2cRTCB" }] } ], "id": "aXD6eFi5JE", @@ -63,10 +62,7 @@ "rpo": null, "softDeletePolicy": null, "storageClass": null, - "tags": { - "Foo": "bar" - }, - "lastModified": null, + "tags": [{ "key": "Foo", "value": "bar" }], "versioning": { "enabled": true, "excludeFolders": false, diff --git a/connector/testdata/02-get/query/storageBucket/request.json b/connector/testdata/02-get/query/storageBucket/request.json index 7afcec8..1a7182a 100644 --- a/connector/testdata/02-get/query/storageBucket/request.json +++ b/connector/testdata/02-get/query/storageBucket/request.json @@ -229,6 +229,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageBuckets-azblob/expected.json b/connector/testdata/02-get/query/storageBucketConnections-azblob/expected.json similarity index 97% rename from connector/testdata/02-get/query/storageBuckets-azblob/expected.json rename to connector/testdata/02-get/query/storageBucketConnections-azblob/expected.json index 7bd4244..1ad3888 100644 --- a/connector/testdata/02-get/query/storageBuckets-azblob/expected.json +++ b/connector/testdata/02-get/query/storageBucketConnections-azblob/expected.json @@ -25,7 +25,7 @@ "rpo": null, "softDeletePolicy": null, "storageClass": null, - "tags": null, + "tags": [], "versioning": null, "website": null } diff --git a/connector/testdata/02-get/query/storageBuckets-azblob/request.json b/connector/testdata/02-get/query/storageBucketConnections-azblob/request.json similarity index 95% rename from connector/testdata/02-get/query/storageBuckets-azblob/request.json rename to connector/testdata/02-get/query/storageBucketConnections-azblob/request.json index a37854f..ed22a49 100644 --- a/connector/testdata/02-get/query/storageBuckets-azblob/request.json +++ b/connector/testdata/02-get/query/storageBucketConnections-azblob/request.json @@ -21,7 +21,7 @@ }, { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "azblob" } } @@ -29,7 +29,7 @@ } } }, - "collection": "storageBuckets", + "collection": "storageBucketConnections", "collection_relationships": {}, "query": { "fields": { @@ -266,6 +266,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageBuckets-gcs/expected.json b/connector/testdata/02-get/query/storageBucketConnections-gcs/expected.json similarity index 97% rename from connector/testdata/02-get/query/storageBuckets-gcs/expected.json rename to connector/testdata/02-get/query/storageBucketConnections-gcs/expected.json index dbc9197..4eafa7b 100644 --- a/connector/testdata/02-get/query/storageBuckets-gcs/expected.json +++ b/connector/testdata/02-get/query/storageBucketConnections-gcs/expected.json @@ -25,7 +25,7 @@ "rpo": null, "softDeletePolicy": null, "storageClass": "STANDARD", - "tags": null, + "tags": [], "versioning": { "enabled": false, "excludeFolders": null, diff --git a/connector/testdata/02-get/query/storageBuckets-gcs/request.json b/connector/testdata/02-get/query/storageBucketConnections-gcs/request.json similarity index 95% rename from connector/testdata/02-get/query/storageBuckets-gcs/request.json rename to connector/testdata/02-get/query/storageBucketConnections-gcs/request.json index c0a3fb1..72c7df5 100644 --- a/connector/testdata/02-get/query/storageBuckets-gcs/request.json +++ b/connector/testdata/02-get/query/storageBucketConnections-gcs/request.json @@ -25,7 +25,7 @@ }, { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "gcs" } } @@ -33,7 +33,7 @@ } } }, - "collection": "storageBuckets", + "collection": "storageBucketConnections", "collection_relationships": {}, "query": { "fields": { @@ -270,6 +270,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageBuckets/expected.json b/connector/testdata/02-get/query/storageBucketConnections/expected.json similarity index 96% rename from connector/testdata/02-get/query/storageBuckets/expected.json rename to connector/testdata/02-get/query/storageBucketConnections/expected.json index 9666e42..5a54fc4 100644 --- a/connector/testdata/02-get/query/storageBuckets/expected.json +++ b/connector/testdata/02-get/query/storageBucketConnections/expected.json @@ -26,7 +26,7 @@ "rpo": null, "softDeletePolicy": null, "storageClass": null, - "tags": null, + "tags": [], "versioning": null, "website": null } @@ -53,7 +53,7 @@ "rpo": null, "softDeletePolicy": null, "storageClass": null, - "tags": null, + "tags": [], "versioning": null, "website": null } @@ -80,7 +80,7 @@ "rpo": null, "softDeletePolicy": null, "storageClass": null, - "tags": null, + "tags": [], "versioning": null, "website": null } diff --git a/connector/testdata/02-get/query/storageBuckets/request.json b/connector/testdata/02-get/query/storageBucketConnections/request.json similarity index 95% rename from connector/testdata/02-get/query/storageBuckets/request.json rename to connector/testdata/02-get/query/storageBucketConnections/request.json index 728b956..ef8ce0d 100644 --- a/connector/testdata/02-get/query/storageBuckets/request.json +++ b/connector/testdata/02-get/query/storageBucketConnections/request.json @@ -13,7 +13,7 @@ "value": null } }, - "collection": "storageBuckets", + "collection": "storageBucketConnections", "collection_relationships": {}, "query": { "fields": { @@ -254,6 +254,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageBucketExists/expected.json b/connector/testdata/02-get/query/storageBucketExists/expected.json index 69aafbe..3f74aee 100644 --- a/connector/testdata/02-get/query/storageBucketExists/expected.json +++ b/connector/testdata/02-get/query/storageBucketExists/expected.json @@ -2,7 +2,9 @@ { "rows": [ { - "__value": true + "__value": { + "exists": true + } } ] } diff --git a/connector/testdata/02-get/query/storageBucketExists/request.json b/connector/testdata/02-get/query/storageBucketExists/request.json index e6b7636..739faf0 100644 --- a/connector/testdata/02-get/query/storageBucketExists/request.json +++ b/connector/testdata/02-get/query/storageBucketExists/request.json @@ -15,6 +15,15 @@ "fields": { "__value": { "column": "__value", + "fields": { + "fields": { + "exists": { + "column": "exists", + "type": "column" + } + }, + "type": "object" + }, "type": "column" } } diff --git a/connector/testdata/02-get/query/storageDeletedObjects-azblob/request.json b/connector/testdata/02-get/query/storageDeletedObjects-azblob/request.json index b52c3fa..fd72c17 100644 --- a/connector/testdata/02-get/query/storageDeletedObjects-azblob/request.json +++ b/connector/testdata/02-get/query/storageDeletedObjects-azblob/request.json @@ -14,7 +14,7 @@ }, { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "public" } } @@ -263,6 +263,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -292,6 +308,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -361,6 +393,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "versionId": { diff --git a/connector/testdata/02-get/query/storageDeletedObjects-gcs/request.json b/connector/testdata/02-get/query/storageDeletedObjects-gcs/request.json index bf0df1c..75049bc 100644 --- a/connector/testdata/02-get/query/storageDeletedObjects-gcs/request.json +++ b/connector/testdata/02-get/query/storageDeletedObjects-gcs/request.json @@ -274,6 +274,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -303,6 +319,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -372,6 +404,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "versionId": { diff --git a/connector/testdata/02-get/query/storageDeletedObjects/expected.json b/connector/testdata/02-get/query/storageDeletedObjects/expected.json index 3745572..c6f4f48 100644 --- a/connector/testdata/02-get/query/storageDeletedObjects/expected.json +++ b/connector/testdata/02-get/query/storageDeletedObjects/expected.json @@ -4,10 +4,7 @@ { "__value": { "objects": [], - "pageInfo": { - "cursor": null, - "hasNextPage": false - } + "pageInfo": { "cursor": null, "hasNextPage": false } } } ] diff --git a/connector/testdata/02-get/query/storageDeletedObjects/request.json b/connector/testdata/02-get/query/storageDeletedObjects/request.json index 9cf1331..376cf73 100644 --- a/connector/testdata/02-get/query/storageDeletedObjects/request.json +++ b/connector/testdata/02-get/query/storageDeletedObjects/request.json @@ -254,6 +254,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -283,6 +299,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -352,6 +384,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "versionId": { diff --git a/connector/testdata/02-get/query/storageObject-azblob/expected.json b/connector/testdata/02-get/query/storageObject-azblob/expected.json index a895bc3..07a4dc7 100644 --- a/connector/testdata/02-get/query/storageObject-azblob/expected.json +++ b/connector/testdata/02-get/query/storageObject-azblob/expected.json @@ -39,13 +39,16 @@ "leaseStatus": "unlocked", "legalHold": null, "mediaLink": null, - "metadata": { - "foo": "Bar" - }, + "metadata": [ + { + "key": "foo", + "value": "Bar" + } + ], "name": "public/hello.txt", "owner": null, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": null, @@ -59,10 +62,16 @@ "size": 10, "storageClass": "Cool", "tagCount": 2, - "tags": { - "Foo": "baz", - "UserID": "3" - }, + "tags": [ + { + "key": "Foo", + "value": "baz" + }, + { + "key": "UserID", + "value": "3" + } + ], "versionId": null } } diff --git a/connector/testdata/02-get/query/storageObject-azblob/request.json b/connector/testdata/02-get/query/storageObject-azblob/request.json index ff5ddb9..5631ce5 100644 --- a/connector/testdata/02-get/query/storageObject-azblob/request.json +++ b/connector/testdata/02-get/query/storageObject-azblob/request.json @@ -19,7 +19,7 @@ "expressions": [ { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "public" } }, @@ -249,6 +249,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -278,6 +294,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -347,6 +379,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "versionId": { diff --git a/connector/testdata/02-get/query/storageObject-gcs/expected.json b/connector/testdata/02-get/query/storageObject-gcs/expected.json index 6a17cb1..314ee39 100644 --- a/connector/testdata/02-get/query/storageObject-gcs/expected.json +++ b/connector/testdata/02-get/query/storageObject-gcs/expected.json @@ -8,8 +8,8 @@ "acl": [ { "entity": "projectOwner-test-project", - "projectTeam": {}, - "role": "OWNER" + "role": "OWNER", + "projectTeam": {} } ], "archiveStatus": null, @@ -47,14 +47,14 @@ "leaseStatus": null, "legalHold": false, "mediaLink": "http://0.0.0.0:4443/download/storage/v1/b/gcs-bucket/o/public%2Fhello.txt?alt=media", - "metadata": { - "Foo": "gcp-baz", - "UserID": "3" - }, + "metadata": [ + { "key": "Foo", "value": "gcp-baz" }, + { "key": "UserID", "value": "3" } + ], "name": "public/hello.txt", "owner": null, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": null, @@ -68,7 +68,7 @@ "size": 10, "storageClass": "Cool", "tagCount": 0, - "tags": null + "tags": [] } } ] diff --git a/connector/testdata/02-get/query/storageObject-gcs/request.json b/connector/testdata/02-get/query/storageObject-gcs/request.json index 751f4ce..5531d14 100644 --- a/connector/testdata/02-get/query/storageObject-gcs/request.json +++ b/connector/testdata/02-get/query/storageObject-gcs/request.json @@ -19,7 +19,7 @@ "expressions": [ { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "public" } }, @@ -257,6 +257,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -286,6 +302,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -355,6 +387,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageObject-null/request.json b/connector/testdata/02-get/query/storageObject-null/request.json index 03b78cb..201b3a0 100644 --- a/connector/testdata/02-get/query/storageObject-null/request.json +++ b/connector/testdata/02-get/query/storageObject-null/request.json @@ -19,7 +19,7 @@ "expressions": [ { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "not-found" } }, @@ -257,6 +257,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -286,6 +302,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -355,6 +387,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "versionId": { diff --git a/connector/testdata/02-get/query/storageObject/expected.json b/connector/testdata/02-get/query/storageObject/expected.json index 3a9478c..4e18f9d 100644 --- a/connector/testdata/02-get/query/storageObject/expected.json +++ b/connector/testdata/02-get/query/storageObject/expected.json @@ -40,21 +40,45 @@ "leaseStatus": null, "legalHold": null, "mediaLink": null, - "metadata": { - "Foo": "Bar" - }, + "metadata": [ + { + "key": "Foo", + "value": "Bar" + } + ], "name": "public/hello.txt", "owner": null, "permissions": null, - "rawMetadata": { - "Cache-Control": "max-age=180, public", - "Content-Disposition": "attachment", - "Content-Encoding": "gzip", - "Content-Language": "en-US", - "Content-Type": "text/plain", - "X-Amz-Meta-Foo": "Bar", - "X-Amz-Tagging-Count": "1" - }, + "rawMetadata": [ + { + "key": "Cache-Control", + "value": "max-age=180, public" + }, + { + "key": "Content-Disposition", + "value": "attachment" + }, + { + "key": "Content-Encoding", + "value": "gzip" + }, + { + "key": "Content-Language", + "value": "en-US" + }, + { + "key": "Content-Type", + "value": "text/plain" + }, + { + "key": "X-Amz-Meta-Foo", + "value": "Bar" + }, + { + "key": "X-Amz-Tagging-Count", + "value": "1" + } + ], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": false, @@ -68,9 +92,12 @@ "size": 10, "storageClass": null, "tagCount": 1, - "tags": { - "UserID": "1" - } + "tags": [ + { + "key": "UserID", + "value": "1" + } + ] } } ] diff --git a/connector/testdata/02-get/query/storageObject/request.json b/connector/testdata/02-get/query/storageObject/request.json index 335e24e..e09f28a 100644 --- a/connector/testdata/02-get/query/storageObject/request.json +++ b/connector/testdata/02-get/query/storageObject/request.json @@ -19,7 +19,7 @@ "expressions": [ { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "public" } }, @@ -253,6 +253,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -282,6 +298,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -351,6 +383,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageObjects-azblob/expected.json b/connector/testdata/02-get/query/storageObjectConnections-azblob/expected.json similarity index 96% rename from connector/testdata/02-get/query/storageObjects-azblob/expected.json rename to connector/testdata/02-get/query/storageObjectConnections-azblob/expected.json index b843c76..b8a4ff4 100644 --- a/connector/testdata/02-get/query/storageObjects-azblob/expected.json +++ b/connector/testdata/02-get/query/storageObjectConnections-azblob/expected.json @@ -44,11 +44,11 @@ "leaseStatus": "unlocked", "legalHold": null, "mediaLink": null, - "metadata": {}, + "metadata": [], "name": "public/hello.txt", "owner": null, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": null, @@ -62,7 +62,7 @@ "size": 10, "storageClass": "Cool", "tagCount": 2, - "tags": null + "tags": [] } } ], diff --git a/connector/testdata/02-get/query/storageObjects-azblob/request.json b/connector/testdata/02-get/query/storageObjectConnections-azblob/request.json similarity index 87% rename from connector/testdata/02-get/query/storageObjects-azblob/request.json rename to connector/testdata/02-get/query/storageObjectConnections-azblob/request.json index 878136c..3dd258b 100644 --- a/connector/testdata/02-get/query/storageObjects-azblob/request.json +++ b/connector/testdata/02-get/query/storageObjectConnections-azblob/request.json @@ -1,5 +1,5 @@ { - "collection": "storageObjects", + "collection": "storageObjectConnections", "arguments": { "first": { "type": "literal", "value": 1 }, "where": { @@ -15,7 +15,7 @@ }, { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "public" } } @@ -247,6 +247,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -276,6 +292,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -345,6 +377,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageObjects-gcs/expected.json b/connector/testdata/02-get/query/storageObjectConnections-gcs/expected.json similarity index 92% rename from connector/testdata/02-get/query/storageObjects-gcs/expected.json rename to connector/testdata/02-get/query/storageObjectConnections-gcs/expected.json index 3cd70ad..748e81d 100644 --- a/connector/testdata/02-get/query/storageObjects-gcs/expected.json +++ b/connector/testdata/02-get/query/storageObjectConnections-gcs/expected.json @@ -52,11 +52,14 @@ "leaseStatus": null, "legalHold": false, "mediaLink": "http://0.0.0.0:4443/download/storage/v1/b/gcs-bucket/o/public%2Fhello.txt?alt=media", - "metadata": { "Foo": "gcp-baz", "UserID": "3" }, + "metadata": [ + { "key": "Foo", "value": "gcp-baz" }, + { "key": "UserID", "value": "3" } + ], "name": "public/hello.txt", "owner": null, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": null, @@ -70,7 +73,7 @@ "size": 10, "storageClass": "Cool", "tagCount": 0, - "tags": null + "tags": [] } } ], diff --git a/connector/testdata/02-get/query/storageObjects-gcs/request.json b/connector/testdata/02-get/query/storageObjectConnections-gcs/request.json similarity index 88% rename from connector/testdata/02-get/query/storageObjects-gcs/request.json rename to connector/testdata/02-get/query/storageObjectConnections-gcs/request.json index 84c333c..7634254 100644 --- a/connector/testdata/02-get/query/storageObjects-gcs/request.json +++ b/connector/testdata/02-get/query/storageObjectConnections-gcs/request.json @@ -1,5 +1,5 @@ { - "collection": "storageObjects", + "collection": "storageObjectConnections", "arguments": { "first": { "type": "literal", "value": 1 }, "where": { @@ -21,7 +21,7 @@ }, { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "public" } } @@ -269,6 +269,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -298,6 +314,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -367,6 +399,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageObjects/expected.json b/connector/testdata/02-get/query/storageObjectConnections/expected.json similarity index 96% rename from connector/testdata/02-get/query/storageObjects/expected.json rename to connector/testdata/02-get/query/storageObjectConnections/expected.json index 69a2ffd..1a64b7c 100644 --- a/connector/testdata/02-get/query/storageObjects/expected.json +++ b/connector/testdata/02-get/query/storageObjectConnections/expected.json @@ -46,14 +46,14 @@ "leaseStatus": null, "legalHold": null, "mediaLink": null, - "metadata": {}, + "metadata": [], "name": "public/hello.txt", "owner": { "id": "minio", "name": "02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4" }, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": false, @@ -67,7 +67,7 @@ "size": 10, "storageClass": "STANDARD", "tagCount": 0, - "tags": null + "tags": [] } }, { @@ -112,14 +112,14 @@ "leaseStatus": null, "legalHold": null, "mediaLink": null, - "metadata": {}, + "metadata": [], "name": "public/hello2.txt", "owner": { "id": "minio", "name": "02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4" }, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": false, @@ -133,7 +133,7 @@ "size": 10, "storageClass": "STANDARD", "tagCount": 0, - "tags": null + "tags": [] } }, { @@ -178,14 +178,14 @@ "leaseStatus": null, "legalHold": null, "mediaLink": null, - "metadata": {}, + "metadata": [], "name": "public/hello3.txt", "owner": { "id": "minio", "name": "02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4" }, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": false, @@ -199,7 +199,7 @@ "size": 10, "storageClass": "STANDARD", "tagCount": 0, - "tags": null + "tags": [] } }, { @@ -244,14 +244,14 @@ "leaseStatus": null, "legalHold": null, "mediaLink": null, - "metadata": {}, + "metadata": [], "name": "public/workd2.txt", "owner": { "id": "minio", "name": "02d6176db174dc93cb1b899f7c6078f08654445fe8cf1b6ce98d8855f66bdbf4" }, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": false, @@ -265,7 +265,7 @@ "size": 10, "storageClass": "STANDARD", "tagCount": 0, - "tags": null + "tags": [] } } ], diff --git a/connector/testdata/02-get/query/storageObjects/request.json b/connector/testdata/02-get/query/storageObjectConnections/request.json similarity index 87% rename from connector/testdata/02-get/query/storageObjects/request.json rename to connector/testdata/02-get/query/storageObjectConnections/request.json index 82d80fa..064e2e3 100644 --- a/connector/testdata/02-get/query/storageObjects/request.json +++ b/connector/testdata/02-get/query/storageObjectConnections/request.json @@ -1,5 +1,5 @@ { - "collection": "storageObjects", + "collection": "storageObjectConnections", "arguments": { "where": { "type": "literal", @@ -14,7 +14,7 @@ }, { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "public" } } @@ -262,6 +262,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -291,6 +307,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -360,6 +392,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/02-get/query/storageObjects2-azblob/expected.json b/connector/testdata/02-get/query/storageObjectConnections2-azblob/expected.json similarity index 96% rename from connector/testdata/02-get/query/storageObjects2-azblob/expected.json rename to connector/testdata/02-get/query/storageObjectConnections2-azblob/expected.json index 0a2fc15..16ce7bf 100644 --- a/connector/testdata/02-get/query/storageObjects2-azblob/expected.json +++ b/connector/testdata/02-get/query/storageObjectConnections2-azblob/expected.json @@ -50,11 +50,11 @@ "leaseStatus": "unlocked", "legalHold": null, "mediaLink": null, - "metadata": {}, + "metadata": [], "name": "public/hello2.txt", "owner": null, "permissions": null, - "rawMetadata": null, + "rawMetadata": [], "rehydratePriority": null, "remainingRetentionDays": null, "replicationReady": null, @@ -68,7 +68,7 @@ "size": 10, "storageClass": "Cool", "tagCount": 1, - "tags": null + "tags": [] } } ], diff --git a/connector/testdata/02-get/query/storageObjects2-azblob/request.json b/connector/testdata/02-get/query/storageObjectConnections2-azblob/request.json similarity index 87% rename from connector/testdata/02-get/query/storageObjects2-azblob/request.json rename to connector/testdata/02-get/query/storageObjectConnections2-azblob/request.json index e4061f4..50920ea 100644 --- a/connector/testdata/02-get/query/storageObjects2-azblob/request.json +++ b/connector/testdata/02-get/query/storageObjectConnections2-azblob/request.json @@ -1,5 +1,5 @@ { - "collection": "storageObjects", + "collection": "storageObjectConnections", "arguments": { "clientId": { "type": "literal", "value": "azblob-connstr" }, "first": { "type": "literal", "value": 1 }, @@ -23,7 +23,7 @@ }, { "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, + "column": { "type": "column", "name": "name", "path": [] }, "operator": "_starts_with", "value": { "type": "scalar", "value": "public" } } @@ -259,6 +259,22 @@ }, "metadata": { "column": "metadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "name": { @@ -288,6 +304,22 @@ }, "rawMetadata": { "column": "rawMetadata", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" }, "rehydratePriority": { @@ -357,6 +389,22 @@ }, "tags": { "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, "type": "column" } }, diff --git a/connector/testdata/03-cleanup/mutation/01-removeIncompleteStorageUpload/expected.json b/connector/testdata/03-cleanup/mutation/01-removeIncompleteStorageUpload/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/01-removeIncompleteStorageUpload/expected.json +++ b/connector/testdata/03-cleanup/mutation/01-removeIncompleteStorageUpload/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/03-cleanup/mutation/01-removeIncompleteStorageUpload/request.json b/connector/testdata/03-cleanup/mutation/01-removeIncompleteStorageUpload/request.json index 08d9e12..663b1a8 100644 --- a/connector/testdata/03-cleanup/mutation/01-removeIncompleteStorageUpload/request.json +++ b/connector/testdata/03-cleanup/mutation/01-removeIncompleteStorageUpload/request.json @@ -7,6 +7,15 @@ "arguments": { "bucket": "minio-bucket-test", "object": "public/hello.txt-2" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/03-cleanup/mutation/02-removeStorageObject-azblob/expected.json b/connector/testdata/03-cleanup/mutation/02-removeStorageObject-azblob/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/02-removeStorageObject-azblob/expected.json +++ b/connector/testdata/03-cleanup/mutation/02-removeStorageObject-azblob/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/03-cleanup/mutation/02-removeStorageObject-azblob/request.json b/connector/testdata/03-cleanup/mutation/02-removeStorageObject-azblob/request.json index 076072a..46fe377 100644 --- a/connector/testdata/03-cleanup/mutation/02-removeStorageObject-azblob/request.json +++ b/connector/testdata/03-cleanup/mutation/02-removeStorageObject-azblob/request.json @@ -9,6 +9,15 @@ "forceDelete": true, "governanceBypass": true, "object": "public/hello.txt" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/03-cleanup/mutation/02-removeStorageObject-gcs/expected.json b/connector/testdata/03-cleanup/mutation/02-removeStorageObject-gcs/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/02-removeStorageObject-gcs/expected.json +++ b/connector/testdata/03-cleanup/mutation/02-removeStorageObject-gcs/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/03-cleanup/mutation/02-removeStorageObject-gcs/request.json b/connector/testdata/03-cleanup/mutation/02-removeStorageObject-gcs/request.json index 96426df..5a133f7 100644 --- a/connector/testdata/03-cleanup/mutation/02-removeStorageObject-gcs/request.json +++ b/connector/testdata/03-cleanup/mutation/02-removeStorageObject-gcs/request.json @@ -10,6 +10,15 @@ "forceDelete": true, "governanceBypass": true, "object": "public/hello.txt" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/03-cleanup/mutation/02-removeStorageObject/expected.json b/connector/testdata/03-cleanup/mutation/02-removeStorageObject/expected.json index 777dfc1..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/02-removeStorageObject/expected.json +++ b/connector/testdata/03-cleanup/mutation/02-removeStorageObject/expected.json @@ -1 +1,10 @@ -{ "operation_results": [{ "result": true, "type": "procedure" }] } +{ + "operation_results": [ + { + "result": { + "success": true + }, + "type": "procedure" + } + ] +} diff --git a/connector/testdata/03-cleanup/mutation/02-removeStorageObject/request.json b/connector/testdata/03-cleanup/mutation/02-removeStorageObject/request.json index 4634e65..d125286 100644 --- a/connector/testdata/03-cleanup/mutation/02-removeStorageObject/request.json +++ b/connector/testdata/03-cleanup/mutation/02-removeStorageObject/request.json @@ -9,6 +9,15 @@ "forceDelete": true, "governanceBypass": true, "object": "public/hello.txt-2" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/03-cleanup/mutation/03-removeStorageObjectTags/expected.json b/connector/testdata/03-cleanup/mutation/03-removeStorageObjectTags/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/03-removeStorageObjectTags/expected.json +++ b/connector/testdata/03-cleanup/mutation/03-removeStorageObjectTags/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/03-cleanup/mutation/03-removeStorageObjectTags/request.json b/connector/testdata/03-cleanup/mutation/03-removeStorageObjectTags/request.json index bf0c9bf..ca027b7 100644 --- a/connector/testdata/03-cleanup/mutation/03-removeStorageObjectTags/request.json +++ b/connector/testdata/03-cleanup/mutation/03-removeStorageObjectTags/request.json @@ -7,7 +7,16 @@ "arguments": { "bucket": "minio-bucket-test", "object": "a9cSGZGzM2", - "tags": {} + "tags": [] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/03-cleanup/mutation/05-suspendStorageBucketVersioning/expected.json b/connector/testdata/03-cleanup/mutation/05-suspendStorageBucketVersioning/expected.json index e28c88a..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/05-suspendStorageBucketVersioning/expected.json +++ b/connector/testdata/03-cleanup/mutation/05-suspendStorageBucketVersioning/expected.json @@ -1,8 +1,10 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] -} \ No newline at end of file +} diff --git a/connector/testdata/03-cleanup/mutation/05-suspendStorageBucketVersioning/request.json b/connector/testdata/03-cleanup/mutation/05-suspendStorageBucketVersioning/request.json index 1ad254b..92cde67 100644 --- a/connector/testdata/03-cleanup/mutation/05-suspendStorageBucketVersioning/request.json +++ b/connector/testdata/03-cleanup/mutation/05-suspendStorageBucketVersioning/request.json @@ -7,7 +7,16 @@ "arguments": { "bucket": "minio-bucket-test", "versioning": false, - "tags": {} + "tags": [] + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-azblob/expected.json b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-azblob/expected.json index e62ec74..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-azblob/expected.json +++ b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-azblob/expected.json @@ -1,7 +1,9 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] diff --git a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-azblob/request.json b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-azblob/request.json index 81c876c..e61f793 100644 --- a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-azblob/request.json +++ b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-azblob/request.json @@ -6,6 +6,15 @@ "name": "removeStorageBucket", "arguments": { "bucket": "azblob-bucket-test" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-gcs/expected.json b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-gcs/expected.json index e62ec74..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-gcs/expected.json +++ b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-gcs/expected.json @@ -1,7 +1,9 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] diff --git a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-gcs/request.json b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-gcs/request.json index ee20b56..1f83c8a 100644 --- a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-gcs/request.json +++ b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket-gcs/request.json @@ -7,6 +7,15 @@ "arguments": { "clientId": "gcs", "bucket": "gcs-bucket" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket/expected.json b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket/expected.json index e62ec74..fb1758a 100644 --- a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket/expected.json +++ b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket/expected.json @@ -1,7 +1,9 @@ { "operation_results": [ { - "result": true, + "result": { + "success": true + }, "type": "procedure" } ] diff --git a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket/request.json b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket/request.json index d54e692..7b44ad1 100644 --- a/connector/testdata/03-cleanup/mutation/07-removeStorageBucket/request.json +++ b/connector/testdata/03-cleanup/mutation/07-removeStorageBucket/request.json @@ -6,6 +6,15 @@ "name": "removeStorageBucket", "arguments": { "bucket": "minio-bucket-empty" + }, + "fields": { + "fields": { + "success": { + "column": "success", + "type": "column" + } + }, + "type": "object" } } ] diff --git a/connector/testdata/bucket/query/filter-contains/expected.json b/connector/testdata/bucket/query/filter-contains/expected.json index 3be8ac8..1de39d0 100644 --- a/connector/testdata/bucket/query/filter-contains/expected.json +++ b/connector/testdata/bucket/query/filter-contains/expected.json @@ -2,63 +2,33 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-8", - "node": { - "clientId": "minio", - "etag": null, - "name": "dummy-bucket-8", - "storageClass": null, - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-8", + "storageClass": null, + "tags": [] } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-8", - "node": { - "clientId": "azblob", - "etag": null, - "name": "dummy-bucket-8", - "storageClass": null, - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-8", + "storageClass": null, + "tags": [] } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-8", - "node": { - "clientId": "gcs", - "etag": "RVRhZw==", - "name": "dummy-bucket-8", - "storageClass": "STANDARD", - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-8", + "storageClass": "STANDARD", + "tags": [] } ] } diff --git a/connector/testdata/bucket/query/filter-contains/request.json b/connector/testdata/bucket/query/filter-contains/request.json index 1defcdb..370fb42 100644 --- a/connector/testdata/bucket/query/filter-contains/request.json +++ b/connector/testdata/bucket/query/filter-contains/request.json @@ -1,44 +1,5 @@ { - "arguments": { - "first": { - "type": "literal", - "value": 3 - }, - "after": { - "type": "literal", - "value": null - }, - "prefix": { - "type": "literal", - "value": "dummy" - }, - "where": { - "type": "literal", - "value": { - "expressions": [ - { - "column": { "type": "column", "name": "bucket" }, - "operator": "_icontains", - "type": "binary_comparison_operator", - "value": { "type": "scalar", "value": "BUCKET" } - }, - { - "column": { "type": "column", "name": "bucket" }, - "operator": "_contains", - "type": "binary_comparison_operator", - "value": { "type": "scalar", "value": "8" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - } - ], - "type": "and" - } - } - }, + "arguments": {}, "variables": [ { "$clientId": "minio" }, { "$clientId": "azblob" }, @@ -48,73 +9,72 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", "fields": { "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - }, - "tags": { - "column": "tags", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" + "fields": { + "key": { + "column": "key", + "type": "column" }, - "type": "column" + "value": { + "column": "value", + "type": "column" + } }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } + "type": "object" }, - "type": "object" + "type": "array" }, "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_icontains", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "BUCKET" } + }, + { + "column": { "type": "column", "name": "name" }, + "operator": "_contains", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "8" } + }, + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "dummy" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ] } } } diff --git a/connector/testdata/bucket/query/limit-3-6/expected.json b/connector/testdata/bucket/query/limit-3-6/expected.json index 072e31c..ef962ab 100644 --- a/connector/testdata/bucket/query/limit-3-6/expected.json +++ b/connector/testdata/bucket/query/limit-3-6/expected.json @@ -2,123 +2,75 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-3", - "node": { - "clientId": "minio", - "etag": null, - "name": "dummy-bucket-3", - "storageClass": null, - "tags": null - } - }, - { - "cursor": "dummy-bucket-4", - "node": { - "clientId": "minio", - "etag": null, - "name": "dummy-bucket-4", - "storageClass": null, - "tags": null - } - }, - { - "cursor": "dummy-bucket-5", - "node": { - "clientId": "minio", - "etag": null, - "name": "dummy-bucket-5", - "storageClass": null, - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-3", + "storageClass": null, + "tags": [] + }, + { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-4", + "storageClass": null, + "tags": [] + }, + { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-5", + "storageClass": null, + "tags": [] } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-3", - "node": { - "clientId": "azblob", - "etag": null, - "name": "dummy-bucket-3", - "storageClass": null, - "tags": null - } - }, - { - "cursor": "dummy-bucket-4", - "node": { - "clientId": "azblob", - "etag": null, - "name": "dummy-bucket-4", - "storageClass": null, - "tags": null - } - }, - { - "cursor": "dummy-bucket-5", - "node": { - "clientId": "azblob", - "etag": null, - "name": "dummy-bucket-5", - "storageClass": null, - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-3", + "storageClass": null, + "tags": [] + }, + { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-4", + "storageClass": null, + "tags": [] + }, + { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-5", + "storageClass": null, + "tags": [] } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-3", - "node": { - "clientId": "gcs", - "etag": "RVRhZw==", - "name": "dummy-bucket-3", - "storageClass": "STANDARD", - "tags": null - } - }, - { - "cursor": "dummy-bucket-4", - "node": { - "clientId": "gcs", - "etag": "RVRhZw==", - "name": "dummy-bucket-4", - "storageClass": "STANDARD", - "tags": null - } - }, - { - "cursor": "dummy-bucket-5", - "node": { - "clientId": "gcs", - "etag": "RVRhZw==", - "name": "dummy-bucket-5", - "storageClass": "STANDARD", - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-3", + "storageClass": "STANDARD", + "tags": [] + }, + { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-4", + "storageClass": "STANDARD", + "tags": [] + }, + { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-5", + "storageClass": "STANDARD", + "tags": [] } ] } diff --git a/connector/testdata/bucket/query/limit-3-6/request.json b/connector/testdata/bucket/query/limit-3-6/request.json index d513b7d..06b6ed6 100644 --- a/connector/testdata/bucket/query/limit-3-6/request.json +++ b/connector/testdata/bucket/query/limit-3-6/request.json @@ -1,32 +1,8 @@ { "arguments": { - "first": { - "type": "literal", - "value": 3 - }, "after": { "type": "literal", "value": "dummy-bucket-2" - }, - "where": { - "type": "literal", - "value": { - "expressions": [ - { - "column": { "type": "column", "name": "bucket" }, - "operator": "_starts_with", - "type": "binary_comparison_operator", - "value": { "type": "scalar", "value": "dummy" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - } - ], - "type": "and" - } } }, "variables": [ @@ -38,73 +14,60 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", "fields": { "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - }, - "tags": { - "column": "tags", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" + "fields": { + "key": { + "column": "key", + "type": "column" }, - "type": "column" + "value": { + "column": "value", + "type": "column" + } }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } + "type": "object" }, - "type": "object" + "type": "array" }, "type": "column" } + }, + "limit": 3, + "predicate": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "dummy" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" } } } diff --git a/connector/testdata/bucket/query/limit-3/expected.json b/connector/testdata/bucket/query/limit-3/expected.json index f0e1dd9..74893ac 100644 --- a/connector/testdata/bucket/query/limit-3/expected.json +++ b/connector/testdata/bucket/query/limit-3/expected.json @@ -2,123 +2,75 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-0", - "node": { - "clientId": "minio", - "etag": null, - "name": "dummy-bucket-0", - "storageClass": null, - "tags": null - } - }, - { - "cursor": "dummy-bucket-1", - "node": { - "clientId": "minio", - "etag": null, - "name": "dummy-bucket-1", - "storageClass": null, - "tags": null - } - }, - { - "cursor": "dummy-bucket-2", - "node": { - "clientId": "minio", - "etag": null, - "name": "dummy-bucket-2", - "storageClass": null, - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-0", + "storageClass": null, + "tags": [] + }, + { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-1", + "storageClass": null, + "tags": [] + }, + { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-2", + "storageClass": null, + "tags": [] } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-0", - "node": { - "clientId": "azblob", - "etag": null, - "name": "dummy-bucket-0", - "storageClass": null, - "tags": null - } - }, - { - "cursor": "dummy-bucket-1", - "node": { - "clientId": "azblob", - "etag": null, - "name": "dummy-bucket-1", - "storageClass": null, - "tags": null - } - }, - { - "cursor": "dummy-bucket-2", - "node": { - "clientId": "azblob", - "etag": null, - "name": "dummy-bucket-2", - "storageClass": null, - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-0", + "storageClass": null, + "tags": [] + }, + { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-1", + "storageClass": null, + "tags": [] + }, + { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-2", + "storageClass": null, + "tags": [] } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-0", - "node": { - "clientId": "gcs", - "etag": "RVRhZw==", - "name": "dummy-bucket-0", - "storageClass": "STANDARD", - "tags": null - } - }, - { - "cursor": "dummy-bucket-1", - "node": { - "clientId": "gcs", - "etag": "RVRhZw==", - "name": "dummy-bucket-1", - "storageClass": "STANDARD", - "tags": null - } - }, - { - "cursor": "dummy-bucket-2", - "node": { - "clientId": "gcs", - "etag": "RVRhZw==", - "name": "dummy-bucket-2", - "storageClass": "STANDARD", - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-0", + "storageClass": "STANDARD", + "tags": [] + }, + { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-1", + "storageClass": "STANDARD", + "tags": [] + }, + { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-2", + "storageClass": "STANDARD", + "tags": [] } ] } diff --git a/connector/testdata/bucket/query/limit-3/request.json b/connector/testdata/bucket/query/limit-3/request.json index 55e0ca5..2229a02 100644 --- a/connector/testdata/bucket/query/limit-3/request.json +++ b/connector/testdata/bucket/query/limit-3/request.json @@ -1,30 +1,8 @@ { "arguments": { - "first": { - "type": "literal", - "value": 3 - }, "after": { "type": "literal", "value": null - }, - "prefix": { - "type": "literal", - "value": "dummy" - }, - "where": { - "type": "literal", - "value": { - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - } - ], - "type": "and" - } } }, "variables": [ @@ -36,73 +14,60 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", "fields": { "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - }, - "tags": { - "column": "tags", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" + "fields": { + "key": { + "column": "key", + "type": "column" }, - "type": "column" + "value": { + "column": "value", + "type": "column" + } }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } + "type": "object" }, - "type": "object" + "type": "array" }, "type": "column" } + }, + "limit": 3, + "predicate": { + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "dummy" } + } + ], + "type": "and" } } } diff --git a/connector/testdata/bucket/query/limit-9-12/expected.json b/connector/testdata/bucket/query/limit-9-12/expected.json index 172523e..35475d5 100644 --- a/connector/testdata/bucket/query/limit-9-12/expected.json +++ b/connector/testdata/bucket/query/limit-9-12/expected.json @@ -2,63 +2,33 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-9", - "node": { - "clientId": "minio", - "etag": null, - "name": "dummy-bucket-9", - "storageClass": null, - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-9", + "storageClass": null, + "tags": [] } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-9", - "node": { - "clientId": "azblob", - "etag": null, - "name": "dummy-bucket-9", - "storageClass": null, - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-9", + "storageClass": null, + "tags": [] } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "dummy-bucket-9", - "node": { - "clientId": "gcs", - "etag": "RVRhZw==", - "name": "dummy-bucket-9", - "storageClass": "STANDARD", - "tags": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-9", + "storageClass": "STANDARD", + "tags": [] } ] } diff --git a/connector/testdata/bucket/query/limit-9-12/request.json b/connector/testdata/bucket/query/limit-9-12/request.json index 7e9d869..8fe13a9 100644 --- a/connector/testdata/bucket/query/limit-9-12/request.json +++ b/connector/testdata/bucket/query/limit-9-12/request.json @@ -1,32 +1,8 @@ { "arguments": { - "first": { - "type": "literal", - "value": 3 - }, "after": { "type": "literal", "value": "dummy-bucket-8" - }, - "where": { - "type": "literal", - "value": { - "expressions": [ - { - "column": { "type": "column", "name": "bucket" }, - "operator": "_starts_with", - "type": "binary_comparison_operator", - "value": { "type": "scalar", "value": "dummy" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - } - ], - "type": "and" - } } }, "variables": [ @@ -38,73 +14,60 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", "fields": { "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - }, - "tags": { - "column": "tags", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" + "fields": { + "key": { + "column": "key", + "type": "column" }, - "type": "column" + "value": { + "column": "value", + "type": "column" + } }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } + "type": "object" }, - "type": "object" + "type": "array" }, "type": "column" } + }, + "limit": 3, + "predicate": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "dummy" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" } } } diff --git a/connector/testdata/bucket/query/no-result-2/expected.json b/connector/testdata/bucket/query/no-result-2/expected.json index 2a35071..fe5f05a 100644 --- a/connector/testdata/bucket/query/no-result-2/expected.json +++ b/connector/testdata/bucket/query/no-result-2/expected.json @@ -1,7 +1 @@ -[ - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - } -] +[{ "rows": [] }] diff --git a/connector/testdata/bucket/query/no-result-2/request.json b/connector/testdata/bucket/query/no-result-2/request.json index d465c83..8e0d76b 100644 --- a/connector/testdata/bucket/query/no-result-2/request.json +++ b/connector/testdata/bucket/query/no-result-2/request.json @@ -1,106 +1,64 @@ { - "arguments": { - "first": { - "type": "literal", - "value": 3 - }, - "after": { - "type": "literal", - "value": null - }, - "where": { - "type": "literal", - "value": { - "expressions": [ - { - "column": { "type": "column", "name": "bucket" }, - "operator": "_starts_with", - "type": "binary_comparison_operator", - "value": { "type": "scalar", "value": "dummy" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - } - ], - "type": "and" - } - } - }, + "arguments": {}, "variables": [{ "$clientId": "not-found" }], "collection": "storageBuckets", "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", "fields": { "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - }, - "tags": { - "column": "tags", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" + "fields": { + "key": { + "column": "key", + "type": "column" }, - "type": "column" + "value": { + "column": "value", + "type": "column" + } }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } + "type": "object" }, - "type": "object" + "type": "array" }, "type": "column" } + }, + "limit": 3, + "predicate": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "dummy" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" } } } diff --git a/connector/testdata/bucket/query/no-result-3/expected.json b/connector/testdata/bucket/query/no-result-3/expected.json index 995103f..02b840a 100644 --- a/connector/testdata/bucket/query/no-result-3/expected.json +++ b/connector/testdata/bucket/query/no-result-3/expected.json @@ -1,17 +1 @@ -[ - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - }, - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - }, - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - } -] +[{ "rows": [] }, { "rows": [] }, { "rows": [] }] diff --git a/connector/testdata/bucket/query/no-result-3/request.json b/connector/testdata/bucket/query/no-result-3/request.json index f39ac45..cda9f66 100644 --- a/connector/testdata/bucket/query/no-result-3/request.json +++ b/connector/testdata/bucket/query/no-result-3/request.json @@ -1,32 +1,5 @@ { - "arguments": { - "first": { - "type": "literal", - "value": 3 - }, - "prefix": { - "type": "literal", - "value": "abcxyz" - }, - "after": { - "type": "literal", - "value": null - }, - "where": { - "type": "literal", - "value": { - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - } - ], - "type": "and" - } - } - }, + "arguments": {}, "variables": [ { "$clientId": "minio" }, { "$clientId": "azblob" }, @@ -36,73 +9,60 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", "fields": { "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - }, - "tags": { - "column": "tags", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" + "fields": { + "key": { + "column": "key", + "type": "column" }, - "type": "column" + "value": { + "column": "value", + "type": "column" + } }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } + "type": "object" }, - "type": "object" + "type": "array" }, "type": "column" } + }, + "limit": 3, + "predicate": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "abcxyz" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" } } } diff --git a/connector/testdata/bucket/query/no-result/expected.json b/connector/testdata/bucket/query/no-result/expected.json index 995103f..02b840a 100644 --- a/connector/testdata/bucket/query/no-result/expected.json +++ b/connector/testdata/bucket/query/no-result/expected.json @@ -1,17 +1 @@ -[ - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - }, - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - }, - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - } -] +[{ "rows": [] }, { "rows": [] }, { "rows": [] }] diff --git a/connector/testdata/bucket/query/no-result/request.json b/connector/testdata/bucket/query/no-result/request.json index 553c538..cda9f66 100644 --- a/connector/testdata/bucket/query/no-result/request.json +++ b/connector/testdata/bucket/query/no-result/request.json @@ -1,34 +1,5 @@ { - "arguments": { - "first": { - "type": "literal", - "value": 3 - }, - "after": { - "type": "literal", - "value": null - }, - "where": { - "type": "literal", - "value": { - "expressions": [ - { - "column": { "type": "column", "name": "bucket" }, - "operator": "_starts_with", - "type": "binary_comparison_operator", - "value": { "type": "scalar", "value": "abcxyz" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - } - ], - "type": "and" - } - } - }, + "arguments": {}, "variables": [ { "$clientId": "minio" }, { "$clientId": "azblob" }, @@ -38,73 +9,60 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", "fields": { "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - }, - "tags": { - "column": "tags", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" + "fields": { + "key": { + "column": "key", + "type": "column" }, - "type": "column" + "value": { + "column": "value", + "type": "column" + } }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } + "type": "object" }, - "type": "object" + "type": "array" }, "type": "column" } + }, + "limit": 3, + "predicate": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "abcxyz" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" } } } diff --git a/connector/testdata/bucket/query/relay-filter-contains/expected.json b/connector/testdata/bucket/query/relay-filter-contains/expected.json new file mode 100644 index 0000000..bccb259 --- /dev/null +++ b/connector/testdata/bucket/query/relay-filter-contains/expected.json @@ -0,0 +1,65 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-8", + "node": { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-8", + "storageClass": null, + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-8", + "node": { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-8", + "storageClass": null, + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-8", + "node": { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-8", + "storageClass": "STANDARD", + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + } +] diff --git a/connector/testdata/bucket/query/relay-filter-contains/request.json b/connector/testdata/bucket/query/relay-filter-contains/request.json new file mode 100644 index 0000000..6e248e0 --- /dev/null +++ b/connector/testdata/bucket/query/relay-filter-contains/request.json @@ -0,0 +1,136 @@ +{ + "arguments": { + "first": { + "type": "literal", + "value": 3 + }, + "after": { + "type": "literal", + "value": null + }, + "prefix": { + "type": "literal", + "value": "dummy" + }, + "where": { + "type": "literal", + "value": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_icontains", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "BUCKET" } + }, + { + "column": { "type": "column", "name": "name" }, + "operator": "_contains", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "8" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection": "storageBucketConnections", + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/bucket/query/relay-limit-3-6/expected.json b/connector/testdata/bucket/query/relay-limit-3-6/expected.json new file mode 100644 index 0000000..d581c88 --- /dev/null +++ b/connector/testdata/bucket/query/relay-limit-3-6/expected.json @@ -0,0 +1,125 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-3", + "node": { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-3", + "storageClass": null, + "tags": [] + } + }, + { + "cursor": "dummy-bucket-4", + "node": { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-4", + "storageClass": null, + "tags": [] + } + }, + { + "cursor": "dummy-bucket-5", + "node": { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-5", + "storageClass": null, + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-3", + "node": { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-3", + "storageClass": null, + "tags": [] + } + }, + { + "cursor": "dummy-bucket-4", + "node": { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-4", + "storageClass": null, + "tags": [] + } + }, + { + "cursor": "dummy-bucket-5", + "node": { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-5", + "storageClass": null, + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-3", + "node": { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-3", + "storageClass": "STANDARD", + "tags": [] + } + }, + { + "cursor": "dummy-bucket-4", + "node": { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-4", + "storageClass": "STANDARD", + "tags": [] + } + }, + { + "cursor": "dummy-bucket-5", + "node": { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-5", + "storageClass": "STANDARD", + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + } +] diff --git a/connector/testdata/bucket/query/relay-limit-3-6/request.json b/connector/testdata/bucket/query/relay-limit-3-6/request.json new file mode 100644 index 0000000..e1a0a07 --- /dev/null +++ b/connector/testdata/bucket/query/relay-limit-3-6/request.json @@ -0,0 +1,126 @@ +{ + "arguments": { + "first": { + "type": "literal", + "value": 3 + }, + "after": { + "type": "literal", + "value": "dummy-bucket-2" + }, + "where": { + "type": "literal", + "value": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "dummy" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection": "storageBucketConnections", + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/bucket/query/relay-limit-3/expected.json b/connector/testdata/bucket/query/relay-limit-3/expected.json new file mode 100644 index 0000000..ecfe1bb --- /dev/null +++ b/connector/testdata/bucket/query/relay-limit-3/expected.json @@ -0,0 +1,125 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-0", + "node": { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-0", + "storageClass": null, + "tags": [] + } + }, + { + "cursor": "dummy-bucket-1", + "node": { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-1", + "storageClass": null, + "tags": [] + } + }, + { + "cursor": "dummy-bucket-2", + "node": { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-2", + "storageClass": null, + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-0", + "node": { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-0", + "storageClass": null, + "tags": [] + } + }, + { + "cursor": "dummy-bucket-1", + "node": { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-1", + "storageClass": null, + "tags": [] + } + }, + { + "cursor": "dummy-bucket-2", + "node": { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-2", + "storageClass": null, + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-0", + "node": { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-0", + "storageClass": "STANDARD", + "tags": [] + } + }, + { + "cursor": "dummy-bucket-1", + "node": { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-1", + "storageClass": "STANDARD", + "tags": [] + } + }, + { + "cursor": "dummy-bucket-2", + "node": { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-2", + "storageClass": "STANDARD", + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + } +] diff --git a/connector/testdata/bucket/query/relay-limit-3/request.json b/connector/testdata/bucket/query/relay-limit-3/request.json new file mode 100644 index 0000000..3d32aea --- /dev/null +++ b/connector/testdata/bucket/query/relay-limit-3/request.json @@ -0,0 +1,124 @@ +{ + "arguments": { + "first": { + "type": "literal", + "value": 3 + }, + "after": { + "type": "literal", + "value": null + }, + "prefix": { + "type": "literal", + "value": "dummy" + }, + "where": { + "type": "literal", + "value": { + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection": "storageBucketConnections", + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/bucket/query/relay-limit-9-12/expected.json b/connector/testdata/bucket/query/relay-limit-9-12/expected.json new file mode 100644 index 0000000..2baddc2 --- /dev/null +++ b/connector/testdata/bucket/query/relay-limit-9-12/expected.json @@ -0,0 +1,65 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-9", + "node": { + "clientId": "minio", + "etag": null, + "name": "dummy-bucket-9", + "storageClass": null, + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-9", + "node": { + "clientId": "azblob", + "etag": null, + "name": "dummy-bucket-9", + "storageClass": null, + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "dummy-bucket-9", + "node": { + "clientId": "gcs", + "etag": "RVRhZw==", + "name": "dummy-bucket-9", + "storageClass": "STANDARD", + "tags": [] + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + } +] diff --git a/connector/testdata/bucket/query/relay-limit-9-12/request.json b/connector/testdata/bucket/query/relay-limit-9-12/request.json new file mode 100644 index 0000000..147c020 --- /dev/null +++ b/connector/testdata/bucket/query/relay-limit-9-12/request.json @@ -0,0 +1,126 @@ +{ + "arguments": { + "first": { + "type": "literal", + "value": 3 + }, + "after": { + "type": "literal", + "value": "dummy-bucket-8" + }, + "where": { + "type": "literal", + "value": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "dummy" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection": "storageBucketConnections", + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/bucket/query/relay-no-result-2/expected.json b/connector/testdata/bucket/query/relay-no-result-2/expected.json new file mode 100644 index 0000000..2a35071 --- /dev/null +++ b/connector/testdata/bucket/query/relay-no-result-2/expected.json @@ -0,0 +1,7 @@ +[ + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + } +] diff --git a/connector/testdata/bucket/query/relay-no-result-2/request.json b/connector/testdata/bucket/query/relay-no-result-2/request.json new file mode 100644 index 0000000..8484fd8 --- /dev/null +++ b/connector/testdata/bucket/query/relay-no-result-2/request.json @@ -0,0 +1,122 @@ +{ + "arguments": { + "first": { + "type": "literal", + "value": 3 + }, + "after": { + "type": "literal", + "value": null + }, + "where": { + "type": "literal", + "value": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "dummy" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" + } + } + }, + "variables": [{ "$clientId": "not-found" }], + "collection": "storageBucketConnections", + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/bucket/query/relay-no-result-3/expected.json b/connector/testdata/bucket/query/relay-no-result-3/expected.json new file mode 100644 index 0000000..995103f --- /dev/null +++ b/connector/testdata/bucket/query/relay-no-result-3/expected.json @@ -0,0 +1,17 @@ +[ + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + }, + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + }, + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + } +] diff --git a/connector/testdata/bucket/query/relay-no-result-3/request.json b/connector/testdata/bucket/query/relay-no-result-3/request.json new file mode 100644 index 0000000..ce5e78e --- /dev/null +++ b/connector/testdata/bucket/query/relay-no-result-3/request.json @@ -0,0 +1,124 @@ +{ + "arguments": { + "first": { + "type": "literal", + "value": 3 + }, + "prefix": { + "type": "literal", + "value": "abcxyz" + }, + "after": { + "type": "literal", + "value": null + }, + "where": { + "type": "literal", + "value": { + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection": "storageBucketConnections", + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/bucket/query/relay-no-result/expected.json b/connector/testdata/bucket/query/relay-no-result/expected.json new file mode 100644 index 0000000..995103f --- /dev/null +++ b/connector/testdata/bucket/query/relay-no-result/expected.json @@ -0,0 +1,17 @@ +[ + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + }, + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + }, + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + } +] diff --git a/connector/testdata/bucket/query/relay-no-result/request.json b/connector/testdata/bucket/query/relay-no-result/request.json new file mode 100644 index 0000000..aaa92d5 --- /dev/null +++ b/connector/testdata/bucket/query/relay-no-result/request.json @@ -0,0 +1,126 @@ +{ + "arguments": { + "first": { + "type": "literal", + "value": 3 + }, + "after": { + "type": "literal", + "value": null + }, + "where": { + "type": "literal", + "value": { + "expressions": [ + { + "column": { "type": "column", "name": "name" }, + "operator": "_starts_with", + "type": "binary_comparison_operator", + "value": { "type": "scalar", "value": "abcxyz" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ], + "type": "and" + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection": "storageBucketConnections", + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + }, + "tags": { + "column": "tags", + "fields": { + "fields": { + "fields": { + "key": { + "column": "key", + "type": "column" + }, + "value": { + "column": "value", + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/filter-contains/expected.json b/connector/testdata/object/query/filter-contains/expected.json index b44851b..40852e9 100644 --- a/connector/testdata/object/query/filter-contains/expected.json +++ b/connector/testdata/object/query/filter-contains/expected.json @@ -2,66 +2,36 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/2000s/movies.json", - "size": 2472795, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "STANDARD" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/2000s/movies.json", - "size": 2472795, - "storageClass": "Hot" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "Hot" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/2000s/movies.json", - "size": 2472795, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "STANDARD" } ] } diff --git a/connector/testdata/object/query/filter-contains/request.json b/connector/testdata/object/query/filter-contains/request.json index 51bec3a..7e8820e 100644 --- a/connector/testdata/object/query/filter-contains/request.json +++ b/connector/testdata/object/query/filter-contains/request.json @@ -2,43 +2,9 @@ "collection": "storageObjects", "arguments": { "hierarchy": { "type": "literal", "value": false }, - "first": { "type": "literal", "value": 3 }, "after": { "type": "literal", "value": "movies/1920s/movies.json" - }, - "prefix": { "type": "literal", "value": "movies" }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_icontains", - "value": { "type": "scalar", "value": "JSON" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_contains", - "value": { "type": "scalar", "value": "2000" } - } - ] - } } }, "variables": [ @@ -49,77 +15,60 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_icontains", + "value": { "type": "scalar", "value": "JSON" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_contains", + "value": { "type": "scalar", "value": "2000" } + } + ] } } } diff --git a/connector/testdata/object/query/no-result-2/expected.json b/connector/testdata/object/query/no-result-2/expected.json index 2a35071..fe5f05a 100644 --- a/connector/testdata/object/query/no-result-2/expected.json +++ b/connector/testdata/object/query/no-result-2/expected.json @@ -1,7 +1 @@ -[ - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - } -] +[{ "rows": [] }] diff --git a/connector/testdata/object/query/no-result-2/request.json b/connector/testdata/object/query/no-result-2/request.json index a160b00..c310ee2 100644 --- a/connector/testdata/object/query/no-result-2/request.json +++ b/connector/testdata/object/query/no-result-2/request.json @@ -1,117 +1,63 @@ { "collection": "storageObjects", "arguments": { - "first": { "type": "literal", "value": 3 }, "after": { "type": "literal", "value": "movies/1990s/movies.json" - }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_starts_with", - "value": { "type": "scalar", "value": "movies" } - } - ] - } } }, "variables": [{ "$clientId": "not-found" }], "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies" } + } + ] } } } diff --git a/connector/testdata/object/query/no-result-3/expected.json b/connector/testdata/object/query/no-result-3/expected.json index 995103f..02b840a 100644 --- a/connector/testdata/object/query/no-result-3/expected.json +++ b/connector/testdata/object/query/no-result-3/expected.json @@ -1,17 +1 @@ -[ - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - }, - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - }, - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - } -] +[{ "rows": [] }, { "rows": [] }, { "rows": [] }] diff --git a/connector/testdata/object/query/no-result-3/request.json b/connector/testdata/object/query/no-result-3/request.json index a7e196b..7579b1b 100644 --- a/connector/testdata/object/query/no-result-3/request.json +++ b/connector/testdata/object/query/no-result-3/request.json @@ -1,34 +1,9 @@ { "collection": "storageObjects", "arguments": { - "first": { "type": "literal", "value": 3 }, "after": { "type": "literal", "value": "movies/1990s/movies.json" - }, - "prefix": { - "type": "literal", - "value": "not-found" - }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - } - ] - } } }, "variables": [ @@ -39,81 +14,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "not-found" } + } + ] } } } diff --git a/connector/testdata/object/query/no-result/expected.json b/connector/testdata/object/query/no-result/expected.json index 995103f..02b840a 100644 --- a/connector/testdata/object/query/no-result/expected.json +++ b/connector/testdata/object/query/no-result/expected.json @@ -1,17 +1 @@ -[ - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - }, - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - }, - { - "rows": [ - { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } - ] - } -] +[{ "rows": [] }, { "rows": [] }, { "rows": [] }] diff --git a/connector/testdata/object/query/no-result/request.json b/connector/testdata/object/query/no-result/request.json index 003ab0d..7579b1b 100644 --- a/connector/testdata/object/query/no-result/request.json +++ b/connector/testdata/object/query/no-result/request.json @@ -1,36 +1,9 @@ { "collection": "storageObjects", "arguments": { - "first": { "type": "literal", "value": 3 }, "after": { "type": "literal", "value": "movies/1990s/movies.json" - }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_starts_with", - "value": { "type": "scalar", "value": "not-found" } - } - ] - } } }, "variables": [ @@ -41,81 +14,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "etag": { - "column": "etag", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "not-found" } + } + ] } } } diff --git a/connector/testdata/object/query/non-recursive-file/expected.json b/connector/testdata/object/query/non-recursive-file/expected.json index 032f8c4..9800e92 100644 --- a/connector/testdata/object/query/non-recursive-file/expected.json +++ b/connector/testdata/object/query/non-recursive-file/expected.json @@ -2,66 +2,36 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1920s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/1920s/movies.json", - "size": 3463423, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "STANDARD" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1920s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/1920s/movies.json", - "size": 3463423, - "storageClass": "Hot" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "Hot" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1920s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/1920s/movies.json", - "size": 3463423, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "STANDARD" } ] } diff --git a/connector/testdata/object/query/non-recursive-file/request.json b/connector/testdata/object/query/non-recursive-file/request.json index dfb6fae..79587ff 100644 --- a/connector/testdata/object/query/non-recursive-file/request.json +++ b/connector/testdata/object/query/non-recursive-file/request.json @@ -1,34 +1,7 @@ { "collection": "storageObjects", "arguments": { - "hierarchy": { "type": "literal", "value": true }, - "first": { "type": "literal", "value": 3 }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_starts_with", - "value": { "type": "scalar", "value": "movies/1920s/" } - } - ] - } - } + "hierarchy": { "type": "literal", "value": true } }, "variables": [ { "$clientId": "minio" }, @@ -38,77 +11,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies/1920s/" } + } + ] } } } diff --git a/connector/testdata/object/query/non-recursive-folder-2/expected.json b/connector/testdata/object/query/non-recursive-folder-2/expected.json index 41a783d..a3f94b7 100644 --- a/connector/testdata/object/query/non-recursive-folder-2/expected.json +++ b/connector/testdata/object/query/non-recursive-folder-2/expected.json @@ -2,132 +2,84 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1930s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": true, - "name": "movies/1930s/", - "size": 0, - "storageClass": null - } - }, - { - "cursor": "movies/1940s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": true, - "name": "movies/1940s/", - "size": 0, - "storageClass": null - } - }, - { - "cursor": "movies/1950s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": true, - "name": "movies/1950s/", - "size": 0, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1930s/", + "size": 0, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1940s/", + "size": 0, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1950s/", + "size": 0, + "storageClass": null } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1930s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": true, - "name": "movies/1930s/", - "size": null, - "storageClass": null - } - }, - { - "cursor": "movies/1940s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": true, - "name": "movies/1940s/", - "size": null, - "storageClass": null - } - }, - { - "cursor": "movies/1950s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": true, - "name": "movies/1950s/", - "size": null, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1930s/", + "size": null, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1940s/", + "size": null, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1950s/", + "size": null, + "storageClass": null } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1930s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": true, - "name": "movies/1930s/", - "size": 0, - "storageClass": null - } - }, - { - "cursor": "movies/1940s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": true, - "name": "movies/1940s/", - "size": 0, - "storageClass": null - } - }, - { - "cursor": "movies/1950s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": true, - "name": "movies/1950s/", - "size": 0, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1930s/", + "size": 0, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1940s/", + "size": 0, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1950s/", + "size": 0, + "storageClass": null } ] } diff --git a/connector/testdata/object/query/non-recursive-folder-2/request.json b/connector/testdata/object/query/non-recursive-folder-2/request.json index 3e0fac7..cb632f4 100644 --- a/connector/testdata/object/query/non-recursive-folder-2/request.json +++ b/connector/testdata/object/query/non-recursive-folder-2/request.json @@ -2,36 +2,9 @@ "collection": "storageObjects", "arguments": { "hierarchy": { "type": "literal", "value": true }, - "first": { "type": "literal", "value": 3 }, "after": { "type": "literal", "value": "movies/1920s/" - }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_starts_with", - "value": { "type": "scalar", "value": "movies/" } - } - ] - } } }, "variables": [ @@ -42,77 +15,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies/" } + } + ] } } } diff --git a/connector/testdata/object/query/non-recursive-folder-3/expected.json b/connector/testdata/object/query/non-recursive-folder-3/expected.json index 58b0bcc..c105044 100644 --- a/connector/testdata/object/query/non-recursive-folder-3/expected.json +++ b/connector/testdata/object/query/non-recursive-folder-3/expected.json @@ -2,66 +2,36 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": true, - "name": "movies/2000s/", - "size": 0, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/2000s/", + "size": 0, + "storageClass": null } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": true, - "name": "movies/2000s/", - "size": null, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/2000s/", + "size": null, + "storageClass": null } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": true, - "name": "movies/2000s/", - "size": 0, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/2000s/", + "size": 0, + "storageClass": null } ] } diff --git a/connector/testdata/object/query/non-recursive-folder-3/request.json b/connector/testdata/object/query/non-recursive-folder-3/request.json index 9c37053..4ba3df9 100644 --- a/connector/testdata/object/query/non-recursive-folder-3/request.json +++ b/connector/testdata/object/query/non-recursive-folder-3/request.json @@ -2,36 +2,9 @@ "collection": "storageObjects", "arguments": { "hierarchy": { "type": "literal", "value": true }, - "first": { "type": "literal", "value": 3 }, "after": { "type": "literal", "value": "movies/1990s/" - }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_starts_with", - "value": { "type": "scalar", "value": "movies/" } - } - ] - } } }, "variables": [ @@ -42,77 +15,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies/" } + } + ] } } } diff --git a/connector/testdata/object/query/non-recursive-folder/expected.json b/connector/testdata/object/query/non-recursive-folder/expected.json index 08b52f2..27d46cc 100644 --- a/connector/testdata/object/query/non-recursive-folder/expected.json +++ b/connector/testdata/object/query/non-recursive-folder/expected.json @@ -2,132 +2,84 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1900s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": true, - "name": "movies/1900s/", - "size": 0, - "storageClass": null - } - }, - { - "cursor": "movies/1910s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": true, - "name": "movies/1910s/", - "size": 0, - "storageClass": null - } - }, - { - "cursor": "movies/1920s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": true, - "name": "movies/1920s/", - "size": 0, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1900s/", + "size": 0, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1910s/", + "size": 0, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1920s/", + "size": 0, + "storageClass": null } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1900s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": true, - "name": "movies/1900s/", - "size": null, - "storageClass": null - } - }, - { - "cursor": "movies/1910s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": true, - "name": "movies/1910s/", - "size": null, - "storageClass": null - } - }, - { - "cursor": "movies/1920s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": true, - "name": "movies/1920s/", - "size": null, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1900s/", + "size": null, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1910s/", + "size": null, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1920s/", + "size": null, + "storageClass": null } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1900s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": true, - "name": "movies/1900s/", - "size": 0, - "storageClass": null - } - }, - { - "cursor": "movies/1910s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": true, - "name": "movies/1910s/", - "size": 0, - "storageClass": null - } - }, - { - "cursor": "movies/1920s/", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": true, - "name": "movies/1920s/", - "size": 0, - "storageClass": null - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1900s/", + "size": 0, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1910s/", + "size": 0, + "storageClass": null + }, + { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1920s/", + "size": 0, + "storageClass": null } ] } diff --git a/connector/testdata/object/query/non-recursive-folder/request.json b/connector/testdata/object/query/non-recursive-folder/request.json index 3c30597..30499b1 100644 --- a/connector/testdata/object/query/non-recursive-folder/request.json +++ b/connector/testdata/object/query/non-recursive-folder/request.json @@ -1,34 +1,7 @@ { "collection": "storageObjects", "arguments": { - "hierarchy": { "type": "literal", "value": true }, - "first": { "type": "literal", "value": 3 }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_starts_with", - "value": { "type": "scalar", "value": "movies/" } - } - ] - } - } + "hierarchy": { "type": "literal", "value": true } }, "variables": [ { "$clientId": "minio" }, @@ -38,77 +11,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies/" } + } + ] } } } diff --git a/connector/testdata/object/query/recursive-limit-3-6/expected.json b/connector/testdata/object/query/recursive-limit-3-6/expected.json index eb6d2d4..12da22c 100644 --- a/connector/testdata/object/query/recursive-limit-3-6/expected.json +++ b/connector/testdata/object/query/recursive-limit-3-6/expected.json @@ -2,132 +2,84 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1930s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/1930s/movies.json", - "size": 2921862, - "storageClass": "STANDARD" - } - }, - { - "cursor": "movies/1940s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/1940s/movies.json", - "size": 2972875, - "storageClass": "STANDARD" - } - }, - { - "cursor": "movies/1950s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/1950s/movies.json", - "size": 2123294, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1930s/movies.json", + "size": 2921862, + "storageClass": "STANDARD" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1940s/movies.json", + "size": 2972875, + "storageClass": "STANDARD" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1950s/movies.json", + "size": 2123294, + "storageClass": "STANDARD" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1930s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/1930s/movies.json", - "size": 2921862, - "storageClass": "Hot" - } - }, - { - "cursor": "movies/1940s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/1940s/movies.json", - "size": 2972875, - "storageClass": "Hot" - } - }, - { - "cursor": "movies/1950s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/1950s/movies.json", - "size": 2123294, - "storageClass": "Hot" - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1930s/movies.json", + "size": 2921862, + "storageClass": "Hot" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1940s/movies.json", + "size": 2972875, + "storageClass": "Hot" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1950s/movies.json", + "size": 2123294, + "storageClass": "Hot" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1930s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/1930s/movies.json", - "size": 2921862, - "storageClass": "STANDARD" - } - }, - { - "cursor": "movies/1940s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/1940s/movies.json", - "size": 2972875, - "storageClass": "STANDARD" - } - }, - { - "cursor": "movies/1950s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/1950s/movies.json", - "size": 2123294, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1930s/movies.json", + "size": 2921862, + "storageClass": "STANDARD" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1940s/movies.json", + "size": 2972875, + "storageClass": "STANDARD" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1950s/movies.json", + "size": 2123294, + "storageClass": "STANDARD" } ] } diff --git a/connector/testdata/object/query/recursive-limit-3-6/request.json b/connector/testdata/object/query/recursive-limit-3-6/request.json index 46fb3bc..e87e71f 100644 --- a/connector/testdata/object/query/recursive-limit-3-6/request.json +++ b/connector/testdata/object/query/recursive-limit-3-6/request.json @@ -2,36 +2,9 @@ "collection": "storageObjects", "arguments": { "hierarchy": { "type": "literal", "value": false }, - "first": { "type": "literal", "value": 3 }, "after": { "type": "literal", "value": "movies/1920s/movies.json" - }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_starts_with", - "value": { "type": "scalar", "value": "movies" } - } - ] - } } }, "variables": [ @@ -42,77 +15,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies" } + } + ] } } } diff --git a/connector/testdata/object/query/recursive-limit-3/expected.json b/connector/testdata/object/query/recursive-limit-3/expected.json index e1ff49e..853b436 100644 --- a/connector/testdata/object/query/recursive-limit-3/expected.json +++ b/connector/testdata/object/query/recursive-limit-3/expected.json @@ -2,132 +2,84 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1900s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/1900s/movies.json", - "size": 100041, - "storageClass": "STANDARD" - } - }, - { - "cursor": "movies/1910s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/1910s/movies.json", - "size": 2007693, - "storageClass": "STANDARD" - } - }, - { - "cursor": "movies/1920s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/1920s/movies.json", - "size": 3463423, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1900s/movies.json", + "size": 100041, + "storageClass": "STANDARD" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1910s/movies.json", + "size": 2007693, + "storageClass": "STANDARD" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "STANDARD" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1900s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/1900s/movies.json", - "size": 100041, - "storageClass": "Hot" - } - }, - { - "cursor": "movies/1910s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/1910s/movies.json", - "size": 2007693, - "storageClass": "Hot" - } - }, - { - "cursor": "movies/1920s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/1920s/movies.json", - "size": 3463423, - "storageClass": "Hot" - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1900s/movies.json", + "size": 100041, + "storageClass": "Hot" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1910s/movies.json", + "size": 2007693, + "storageClass": "Hot" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "Hot" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/1900s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/1900s/movies.json", - "size": 100041, - "storageClass": "STANDARD" - } - }, - { - "cursor": "movies/1910s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/1910s/movies.json", - "size": 2007693, - "storageClass": "STANDARD" - } - }, - { - "cursor": "movies/1920s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/1920s/movies.json", - "size": 3463423, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": true } - } + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1900s/movies.json", + "size": 100041, + "storageClass": "STANDARD" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1910s/movies.json", + "size": 2007693, + "storageClass": "STANDARD" + }, + { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "STANDARD" } ] } diff --git a/connector/testdata/object/query/recursive-limit-3/request.json b/connector/testdata/object/query/recursive-limit-3/request.json index 0a3fa09..d58bfc2 100644 --- a/connector/testdata/object/query/recursive-limit-3/request.json +++ b/connector/testdata/object/query/recursive-limit-3/request.json @@ -1,24 +1,7 @@ { "collection": "storageObjects", "arguments": { - "hierarchy": { "type": "literal", "value": false }, - "first": { "type": "literal", "value": 3 }, - "bucket": { "type": "literal", "value": "dummy-bucket-0" }, - "prefix": { "type": "literal", "value": "movies" }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - } - ] - } - } + "hierarchy": { "type": "literal", "value": false } }, "variables": [ { "$clientId": "minio" }, @@ -28,77 +11,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies" } + } + ] } } } diff --git a/connector/testdata/object/query/recursive-limit-9-12/expected.json b/connector/testdata/object/query/recursive-limit-9-12/expected.json index b44851b..40852e9 100644 --- a/connector/testdata/object/query/recursive-limit-9-12/expected.json +++ b/connector/testdata/object/query/recursive-limit-9-12/expected.json @@ -2,66 +2,36 @@ { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "minio", - "isDirectory": false, - "name": "movies/2000s/movies.json", - "size": 2472795, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "STANDARD" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "azblob", - "isDirectory": false, - "name": "movies/2000s/movies.json", - "size": 2472795, - "storageClass": "Hot" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "Hot" } ] }, { "rows": [ { - "__value": { - "edges": [ - { - "cursor": "movies/2000s/movies.json", - "node": { - "bucket": "dummy-bucket-0", - "clientId": "gcs", - "isDirectory": false, - "name": "movies/2000s/movies.json", - "size": 2472795, - "storageClass": "STANDARD" - } - } - ], - "pageInfo": { "hasNextPage": false } - } + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "STANDARD" } ] } diff --git a/connector/testdata/object/query/recursive-limit-9-12/request.json b/connector/testdata/object/query/recursive-limit-9-12/request.json index a9a5764..776a6fe 100644 --- a/connector/testdata/object/query/recursive-limit-9-12/request.json +++ b/connector/testdata/object/query/recursive-limit-9-12/request.json @@ -2,36 +2,9 @@ "collection": "storageObjects", "arguments": { "hierarchy": { "type": "literal", "value": false }, - "first": { "type": "literal", "value": 3 }, "after": { "type": "literal", "value": "movies/1990s/movies.json" - }, - "where": { - "type": "literal", - "value": { - "type": "and", - "expressions": [ - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "clientId", "path": [] }, - "operator": "_eq", - "value": { "type": "variable", "name": "$clientId" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "bucket", "path": [] }, - "operator": "_eq", - "value": { "type": "scalar", "value": "dummy-bucket-0" } - }, - { - "type": "binary_comparison_operator", - "column": { "type": "column", "name": "object", "path": [] }, - "operator": "_starts_with", - "value": { "type": "scalar", "value": "movies" } - } - ] - } } }, "variables": [ @@ -42,77 +15,54 @@ "collection_relationships": {}, "query": { "fields": { - "__value": { - "column": "__value", - "fields": { - "fields": { - "edges": { - "column": "edges", - "fields": { - "fields": { - "fields": { - "cursor": { - "column": "cursor", - "type": "column" - }, - "node": { - "column": "node", - "fields": { - "fields": { - "bucket": { - "column": "bucket", - "type": "column" - }, - "clientId": { - "column": "clientId", - "type": "column" - }, - "isDirectory": { - "column": "isDirectory", - "type": "column" - }, - "name": { - "column": "name", - "type": "column" - }, - "size": { - "column": "size", - "type": "column" - }, - "storageClass": { - "column": "storageClass", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, - "type": "array" - }, - "type": "column" - }, - "pageInfo": { - "column": "pageInfo", - "fields": { - "fields": { - "hasNextPage": { - "column": "hasNextPage", - "type": "column" - } - }, - "type": "object" - }, - "type": "column" - } - }, - "type": "object" - }, + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", "type": "column" } + }, + "limit": 3, + "predicate": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies" } + } + ] } } } diff --git a/connector/testdata/object/query/relay-filter-contains/expected.json b/connector/testdata/object/query/relay-filter-contains/expected.json new file mode 100644 index 0000000..b44851b --- /dev/null +++ b/connector/testdata/object/query/relay-filter-contains/expected.json @@ -0,0 +1,68 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "Hot" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + } +] diff --git a/connector/testdata/object/query/relay-filter-contains/request.json b/connector/testdata/object/query/relay-filter-contains/request.json new file mode 100644 index 0000000..78ff823 --- /dev/null +++ b/connector/testdata/object/query/relay-filter-contains/request.json @@ -0,0 +1,125 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "hierarchy": { "type": "literal", "value": false }, + "first": { "type": "literal", "value": 3 }, + "after": { + "type": "literal", + "value": "movies/1920s/movies.json" + }, + "prefix": { "type": "literal", "value": "movies" }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_icontains", + "value": { "type": "scalar", "value": "JSON" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_contains", + "value": { "type": "scalar", "value": "2000" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-no-result-2/expected.json b/connector/testdata/object/query/relay-no-result-2/expected.json new file mode 100644 index 0000000..2a35071 --- /dev/null +++ b/connector/testdata/object/query/relay-no-result-2/expected.json @@ -0,0 +1,7 @@ +[ + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + } +] diff --git a/connector/testdata/object/query/relay-no-result-2/request.json b/connector/testdata/object/query/relay-no-result-2/request.json new file mode 100644 index 0000000..60424e0 --- /dev/null +++ b/connector/testdata/object/query/relay-no-result-2/request.json @@ -0,0 +1,117 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "first": { "type": "literal", "value": 3 }, + "after": { + "type": "literal", + "value": "movies/1990s/movies.json" + }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies" } + } + ] + } + } + }, + "variables": [{ "$clientId": "not-found" }], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-no-result-3/expected.json b/connector/testdata/object/query/relay-no-result-3/expected.json new file mode 100644 index 0000000..995103f --- /dev/null +++ b/connector/testdata/object/query/relay-no-result-3/expected.json @@ -0,0 +1,17 @@ +[ + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + }, + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + }, + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + } +] diff --git a/connector/testdata/object/query/relay-no-result-3/request.json b/connector/testdata/object/query/relay-no-result-3/request.json new file mode 100644 index 0000000..5105bc9 --- /dev/null +++ b/connector/testdata/object/query/relay-no-result-3/request.json @@ -0,0 +1,119 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "first": { "type": "literal", "value": 3 }, + "after": { + "type": "literal", + "value": "movies/1990s/movies.json" + }, + "prefix": { + "type": "literal", + "value": "not-found" + }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-no-result/expected.json b/connector/testdata/object/query/relay-no-result/expected.json new file mode 100644 index 0000000..995103f --- /dev/null +++ b/connector/testdata/object/query/relay-no-result/expected.json @@ -0,0 +1,17 @@ +[ + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + }, + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + }, + { + "rows": [ + { "__value": { "edges": [], "pageInfo": { "hasNextPage": false } } } + ] + } +] diff --git a/connector/testdata/object/query/relay-no-result/request.json b/connector/testdata/object/query/relay-no-result/request.json new file mode 100644 index 0000000..ae81d69 --- /dev/null +++ b/connector/testdata/object/query/relay-no-result/request.json @@ -0,0 +1,121 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "first": { "type": "literal", "value": 3 }, + "after": { + "type": "literal", + "value": "movies/1990s/movies.json" + }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "not-found" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "etag": { + "column": "etag", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-non-recursive-file/expected.json b/connector/testdata/object/query/relay-non-recursive-file/expected.json new file mode 100644 index 0000000..032f8c4 --- /dev/null +++ b/connector/testdata/object/query/relay-non-recursive-file/expected.json @@ -0,0 +1,68 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1920s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1920s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "Hot" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1920s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + } +] diff --git a/connector/testdata/object/query/relay-non-recursive-file/request.json b/connector/testdata/object/query/relay-non-recursive-file/request.json new file mode 100644 index 0000000..54241ab --- /dev/null +++ b/connector/testdata/object/query/relay-non-recursive-file/request.json @@ -0,0 +1,114 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "hierarchy": { "type": "literal", "value": true }, + "first": { "type": "literal", "value": 3 }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies/1920s/" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-non-recursive-folder-2/expected.json b/connector/testdata/object/query/relay-non-recursive-folder-2/expected.json new file mode 100644 index 0000000..41a783d --- /dev/null +++ b/connector/testdata/object/query/relay-non-recursive-folder-2/expected.json @@ -0,0 +1,134 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1930s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1930s/", + "size": 0, + "storageClass": null + } + }, + { + "cursor": "movies/1940s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1940s/", + "size": 0, + "storageClass": null + } + }, + { + "cursor": "movies/1950s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1950s/", + "size": 0, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1930s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1930s/", + "size": null, + "storageClass": null + } + }, + { + "cursor": "movies/1940s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1940s/", + "size": null, + "storageClass": null + } + }, + { + "cursor": "movies/1950s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1950s/", + "size": null, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1930s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1930s/", + "size": 0, + "storageClass": null + } + }, + { + "cursor": "movies/1940s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1940s/", + "size": 0, + "storageClass": null + } + }, + { + "cursor": "movies/1950s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1950s/", + "size": 0, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + } +] diff --git a/connector/testdata/object/query/relay-non-recursive-folder-2/request.json b/connector/testdata/object/query/relay-non-recursive-folder-2/request.json new file mode 100644 index 0000000..e8a4628 --- /dev/null +++ b/connector/testdata/object/query/relay-non-recursive-folder-2/request.json @@ -0,0 +1,118 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "hierarchy": { "type": "literal", "value": true }, + "first": { "type": "literal", "value": 3 }, + "after": { + "type": "literal", + "value": "movies/1920s/" + }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies/" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-non-recursive-folder-3/expected.json b/connector/testdata/object/query/relay-non-recursive-folder-3/expected.json new file mode 100644 index 0000000..58b0bcc --- /dev/null +++ b/connector/testdata/object/query/relay-non-recursive-folder-3/expected.json @@ -0,0 +1,68 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/2000s/", + "size": 0, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/2000s/", + "size": null, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/2000s/", + "size": 0, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + } +] diff --git a/connector/testdata/object/query/relay-non-recursive-folder-3/request.json b/connector/testdata/object/query/relay-non-recursive-folder-3/request.json new file mode 100644 index 0000000..64b968e --- /dev/null +++ b/connector/testdata/object/query/relay-non-recursive-folder-3/request.json @@ -0,0 +1,118 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "hierarchy": { "type": "literal", "value": true }, + "first": { "type": "literal", "value": 3 }, + "after": { + "type": "literal", + "value": "movies/1990s/" + }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies/" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-non-recursive-folder/expected.json b/connector/testdata/object/query/relay-non-recursive-folder/expected.json new file mode 100644 index 0000000..08b52f2 --- /dev/null +++ b/connector/testdata/object/query/relay-non-recursive-folder/expected.json @@ -0,0 +1,134 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1900s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1900s/", + "size": 0, + "storageClass": null + } + }, + { + "cursor": "movies/1910s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1910s/", + "size": 0, + "storageClass": null + } + }, + { + "cursor": "movies/1920s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": true, + "name": "movies/1920s/", + "size": 0, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1900s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1900s/", + "size": null, + "storageClass": null + } + }, + { + "cursor": "movies/1910s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1910s/", + "size": null, + "storageClass": null + } + }, + { + "cursor": "movies/1920s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": true, + "name": "movies/1920s/", + "size": null, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1900s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1900s/", + "size": 0, + "storageClass": null + } + }, + { + "cursor": "movies/1910s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1910s/", + "size": 0, + "storageClass": null + } + }, + { + "cursor": "movies/1920s/", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": true, + "name": "movies/1920s/", + "size": 0, + "storageClass": null + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + } +] diff --git a/connector/testdata/object/query/relay-non-recursive-folder/request.json b/connector/testdata/object/query/relay-non-recursive-folder/request.json new file mode 100644 index 0000000..3260339 --- /dev/null +++ b/connector/testdata/object/query/relay-non-recursive-folder/request.json @@ -0,0 +1,114 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "hierarchy": { "type": "literal", "value": true }, + "first": { "type": "literal", "value": 3 }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies/" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-recursive-limit-3-6/expected.json b/connector/testdata/object/query/relay-recursive-limit-3-6/expected.json new file mode 100644 index 0000000..eb6d2d4 --- /dev/null +++ b/connector/testdata/object/query/relay-recursive-limit-3-6/expected.json @@ -0,0 +1,134 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1930s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1930s/movies.json", + "size": 2921862, + "storageClass": "STANDARD" + } + }, + { + "cursor": "movies/1940s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1940s/movies.json", + "size": 2972875, + "storageClass": "STANDARD" + } + }, + { + "cursor": "movies/1950s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1950s/movies.json", + "size": 2123294, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1930s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1930s/movies.json", + "size": 2921862, + "storageClass": "Hot" + } + }, + { + "cursor": "movies/1940s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1940s/movies.json", + "size": 2972875, + "storageClass": "Hot" + } + }, + { + "cursor": "movies/1950s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1950s/movies.json", + "size": 2123294, + "storageClass": "Hot" + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1930s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1930s/movies.json", + "size": 2921862, + "storageClass": "STANDARD" + } + }, + { + "cursor": "movies/1940s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1940s/movies.json", + "size": 2972875, + "storageClass": "STANDARD" + } + }, + { + "cursor": "movies/1950s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1950s/movies.json", + "size": 2123294, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + } +] diff --git a/connector/testdata/object/query/relay-recursive-limit-3-6/request.json b/connector/testdata/object/query/relay-recursive-limit-3-6/request.json new file mode 100644 index 0000000..6ad7bb5 --- /dev/null +++ b/connector/testdata/object/query/relay-recursive-limit-3-6/request.json @@ -0,0 +1,118 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "hierarchy": { "type": "literal", "value": false }, + "first": { "type": "literal", "value": 3 }, + "after": { + "type": "literal", + "value": "movies/1920s/movies.json" + }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-recursive-limit-3/expected.json b/connector/testdata/object/query/relay-recursive-limit-3/expected.json new file mode 100644 index 0000000..e1ff49e --- /dev/null +++ b/connector/testdata/object/query/relay-recursive-limit-3/expected.json @@ -0,0 +1,134 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1900s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1900s/movies.json", + "size": 100041, + "storageClass": "STANDARD" + } + }, + { + "cursor": "movies/1910s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1910s/movies.json", + "size": 2007693, + "storageClass": "STANDARD" + } + }, + { + "cursor": "movies/1920s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1900s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1900s/movies.json", + "size": 100041, + "storageClass": "Hot" + } + }, + { + "cursor": "movies/1910s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1910s/movies.json", + "size": 2007693, + "storageClass": "Hot" + } + }, + { + "cursor": "movies/1920s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "Hot" + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/1900s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1900s/movies.json", + "size": 100041, + "storageClass": "STANDARD" + } + }, + { + "cursor": "movies/1910s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1910s/movies.json", + "size": 2007693, + "storageClass": "STANDARD" + } + }, + { + "cursor": "movies/1920s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/1920s/movies.json", + "size": 3463423, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": true } + } + } + ] + } +] diff --git a/connector/testdata/object/query/relay-recursive-limit-3/request.json b/connector/testdata/object/query/relay-recursive-limit-3/request.json new file mode 100644 index 0000000..459ee4c --- /dev/null +++ b/connector/testdata/object/query/relay-recursive-limit-3/request.json @@ -0,0 +1,104 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "hierarchy": { "type": "literal", "value": false }, + "first": { "type": "literal", "value": 3 }, + "bucket": { "type": "literal", "value": "dummy-bucket-0" }, + "prefix": { "type": "literal", "value": "movies" }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/testdata/object/query/relay-recursive-limit-9-12/expected.json b/connector/testdata/object/query/relay-recursive-limit-9-12/expected.json new file mode 100644 index 0000000..b44851b --- /dev/null +++ b/connector/testdata/object/query/relay-recursive-limit-9-12/expected.json @@ -0,0 +1,68 @@ +[ + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "minio", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "azblob", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "Hot" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + }, + { + "rows": [ + { + "__value": { + "edges": [ + { + "cursor": "movies/2000s/movies.json", + "node": { + "bucket": "dummy-bucket-0", + "clientId": "gcs", + "isDirectory": false, + "name": "movies/2000s/movies.json", + "size": 2472795, + "storageClass": "STANDARD" + } + } + ], + "pageInfo": { "hasNextPage": false } + } + } + ] + } +] diff --git a/connector/testdata/object/query/relay-recursive-limit-9-12/request.json b/connector/testdata/object/query/relay-recursive-limit-9-12/request.json new file mode 100644 index 0000000..a9ebf4c --- /dev/null +++ b/connector/testdata/object/query/relay-recursive-limit-9-12/request.json @@ -0,0 +1,118 @@ +{ + "collection": "storageObjectConnections", + "arguments": { + "hierarchy": { "type": "literal", "value": false }, + "first": { "type": "literal", "value": 3 }, + "after": { + "type": "literal", + "value": "movies/1990s/movies.json" + }, + "where": { + "type": "literal", + "value": { + "type": "and", + "expressions": [ + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "clientId", "path": [] }, + "operator": "_eq", + "value": { "type": "variable", "name": "$clientId" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "bucket", "path": [] }, + "operator": "_eq", + "value": { "type": "scalar", "value": "dummy-bucket-0" } + }, + { + "type": "binary_comparison_operator", + "column": { "type": "column", "name": "name", "path": [] }, + "operator": "_starts_with", + "value": { "type": "scalar", "value": "movies" } + } + ] + } + } + }, + "variables": [ + { "$clientId": "minio" }, + { "$clientId": "azblob" }, + { "$clientId": "gcs" } + ], + "collection_relationships": {}, + "query": { + "fields": { + "__value": { + "column": "__value", + "fields": { + "fields": { + "edges": { + "column": "edges", + "fields": { + "fields": { + "fields": { + "cursor": { + "column": "cursor", + "type": "column" + }, + "node": { + "column": "node", + "fields": { + "fields": { + "bucket": { + "column": "bucket", + "type": "column" + }, + "clientId": { + "column": "clientId", + "type": "column" + }, + "isDirectory": { + "column": "isDirectory", + "type": "column" + }, + "name": { + "column": "name", + "type": "column" + }, + "size": { + "column": "size", + "type": "column" + }, + "storageClass": { + "column": "storageClass", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "array" + }, + "type": "column" + }, + "pageInfo": { + "column": "pageInfo", + "fields": { + "fields": { + "hasNextPage": { + "column": "hasNextPage", + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + }, + "type": "object" + }, + "type": "column" + } + } + } +} diff --git a/connector/types/configuration.go b/connector/types/configuration.go index cda48d6..bd23760 100644 --- a/connector/types/configuration.go +++ b/connector/types/configuration.go @@ -19,6 +19,8 @@ type Configuration struct { Concurrency ConcurrencySettings `json:"concurrency,omitempty" yaml:"concurrency,omitempty"` // Common runtime settings for all clients. Runtime storage.RuntimeSettings `json:"runtime" yaml:"runtime"` + // Schema generator settings. + Generator GeneratorSettings `json:"generator,omitempty" yaml:"generator,omitempty"` } // Validate checks if the configuration is valid. @@ -47,3 +49,9 @@ type ConcurrencySettings struct { // Maximum number of concurrent executions if there are many mutation operations. Mutation int `json:"mutation" jsonschema:"min=1,default=1" yaml:"mutation"` } + +// GeneratorSettings represent settings for schema generation. +type GeneratorSettings struct { + // Generate the connector schema to be compatible with PromptQL. + PromptQLCompatible bool `json:"promptqlCompatible" jsonschema:"default=false" yaml:"promptqlCompatible"` +} diff --git a/docs/objects.md b/docs/objects.md index 1c97f67..dac588b 100644 --- a/docs/objects.md +++ b/docs/objects.md @@ -74,12 +74,16 @@ The response is a base64-encode string. The client must decode the string to get ```gql query DownloadObject { - downloadStorageObject(object: "hello.txt") + downloadStorageObject(object: "hello.txt") { + data + } } # { # "data": { -# "downloadStorageObject": "SGVsbG8gd29ybGQK" +# "downloadStorageObject": { +# "data": "SGVsbG8gd29ybGQK" +# } # } # } ``` @@ -93,12 +97,16 @@ Use the `downloadStorageObjectText` query if you are confident that the object c ```gql query DownloadObjectText { - downloadStorageObjectText(object: "hello.txt") + downloadStorageObjectText(object: "hello.txt") { + data + } } # { # "data": { -# "downloadStorageObjectText": "Hello world\n" +# "downloadStorageObjectText": { +# "data": "Hello world\n" +# } # } # } ``` @@ -111,10 +119,17 @@ You can use either `clientId`, `bucket`, `prefix`, or `where` boolean expression ```graphql query ListObjects { - storageObjects(prefix: "hello", where: { object: { _contains: "world" } }) { - objects { - name - # ... + storageObjectConnections( + prefix: "hello" + where: { object: { _contains: "world" } } + ) { + edges { + cursor + node { + clientId + bucket + # ... + } } } } @@ -125,8 +140,8 @@ query ListObjects { Relay style suits object listing because most cloud storage services only support cursor-based pagination. The object name is used as the cursor ID. ```graphql -query ListObjects { - storageObjects(after: "hello.txt", first: 3) { +query ListObjectConnections { + storageObjectConnections(after: "hello.txt", first: 3) { pageInfo { hasNextPage } @@ -167,6 +182,19 @@ query ListObjects { } ``` +Or you can use the `storageObjects` collection. The response structure is simpler but some argument isn't functional such as sorting. + +```graphql +query ListObjects { + storageObjects(after: "hello.txt", limit: 3) { + clientId + bucket + name + # ... + } +} +``` + ## Multiple clients and buckets You can upload to other buckets or services by specifying `clientId` and `bucket` arguments. diff --git a/go.mod b/go.mod index bade383..83cae78 100644 --- a/go.mod +++ b/go.mod @@ -5,21 +5,21 @@ go 1.23 require ( cloud.google.com/go/storage v1.50.0 github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.0 - github.com/alecthomas/kong v1.7.0 + github.com/alecthomas/kong v1.8.1 github.com/go-viper/mapstructure/v2 v2.2.1 - github.com/hasura/ndc-sdk-go v1.7.1-0.20250203083219-765c8932cef4 + github.com/hasura/ndc-sdk-go v1.7.1-0.20250216162428-dda5ec08bd7f github.com/invopop/jsonschema v0.13.0 github.com/lmittmann/tint v1.0.7 github.com/minio/md5-simd v1.1.2 - github.com/minio/minio-go/v7 v7.0.84 + github.com/minio/minio-go/v7 v7.0.86 go.opentelemetry.io/otel v1.34.0 go.opentelemetry.io/otel/trace v1.34.0 - golang.org/x/sync v0.10.0 - google.golang.org/api v0.219.0 + golang.org/x/sync v0.11.0 + google.golang.org/api v0.221.0 gopkg.in/yaml.v3 v3.0.1 - gotest.tools/v3 v3.5.1 + gotest.tools/v3 v3.5.2 ) require ( @@ -60,6 +60,7 @@ require ( github.com/klauspost/cpuid/v2 v2.2.9 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mailru/easyjson v0.9.0 // indirect + github.com/minio/crc64nvme v1.0.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect @@ -89,15 +90,15 @@ require ( go.opentelemetry.io/otel/sdk/log v0.10.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect - golang.org/x/crypto v0.32.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/text v0.21.0 // indirect - golang.org/x/time v0.9.0 // indirect + golang.org/x/crypto v0.33.0 // indirect + golang.org/x/net v0.35.0 // indirect + golang.org/x/oauth2 v0.26.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/text v0.22.0 // indirect + golang.org/x/time v0.10.0 // indirect google.golang.org/genproto v0.0.0-20250127172529-29210b9bc287 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect google.golang.org/grpc v1.70.0 // indirect - google.golang.org/protobuf v1.36.4 // indirect + google.golang.org/protobuf v1.36.5 // indirect ) diff --git a/go.sum b/go.sum index d8c6671..6d4f78f 100644 --- a/go.sum +++ b/go.sum @@ -22,10 +22,10 @@ cloud.google.com/go/trace v1.11.3 h1:c+I4YFjxRQjvAhRmSsmjpASUKq88chOX854ied0K/pE cloud.google.com/go/trace v1.11.3/go.mod h1:pt7zCYiDSQjC9Y2oqCsh9jF4GStB/hmjrYLsxRR27q8= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1 h1:1mvYtZfWQAnwNah/C+Z+Jb9rQH95LPE2vlmMuWAHJk8= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.1/go.mod h1:75I/mXtme1JyWFtz8GocPHVFyH421IBoZErnO16dd0k= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.1 h1:Bk5uOhSAenHyR5P61D/NzeQCv+4fEVV8mOkJ82NqpWw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.1/go.mod h1:QZ4pw3or1WPmRBxf0cHd1tknzrT54WPBOQoGutCPvSU= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.6.0 h1:PiSrjRPpkQNjrM8H0WwKMnZUdu1RGMtd/LdGKUrOo+c= @@ -46,8 +46,8 @@ github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapp github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.50.0/go.mod h1:otE2jQekW/PqXk1Awf5lmfokJx4uwuqcj1ab5SpGeW0= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/kong v1.7.0 h1:MnT8+5JxFDCvISeI6vgd/mFbAJwueJ/pqQNzZMsiqZE= -github.com/alecthomas/kong v1.7.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= +github.com/alecthomas/kong v1.8.1 h1:6aamvWBE/REnR/BCq10EcozmcpUPc5aGI1lPAWdB0EE= +github.com/alecthomas/kong v1.8.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= @@ -107,8 +107,10 @@ github.com/googleapis/gax-go/v2 v2.14.1 h1:hb0FFeiPaQskmvakKu5EbCbpntQn48jyHuvrk github.com/googleapis/gax-go/v2 v2.14.1/go.mod h1:Hb/NubMaVM88SrNkvl8X/o8XWwDJEPqouaLeN2IUxoA= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0 h1:VD1gqscl4nYs1YxVuSdemTrSgTKrwOWDK0FVFMqm+Cg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.0/go.mod h1:4EgsQoS4TOhJizV+JTFg40qx1Ofh3XmXEQNBpgvNT40= -github.com/hasura/ndc-sdk-go v1.7.1-0.20250203083219-765c8932cef4 h1:OYcBsDPBMe1/0Sr5B1TMguI5wTsfOCUSwgIiTZzQFYs= -github.com/hasura/ndc-sdk-go v1.7.1-0.20250203083219-765c8932cef4/go.mod h1:79hEYe4HuPwFKi6aWjUDo9l/hhCiYFVEykjJsF1abg0= +github.com/hasura/ndc-sdk-go v1.7.1-0.20250214145323-260a6ba510e8 h1:GVBgmb+lcV745JUz1Aa7eayEKD2prTnrPEbseEmV11g= +github.com/hasura/ndc-sdk-go v1.7.1-0.20250214145323-260a6ba510e8/go.mod h1:1P1AsL24ll6TO0Qnn7oxivkM+uJSL5wC8mrormhu/7I= +github.com/hasura/ndc-sdk-go v1.7.1-0.20250216162428-dda5ec08bd7f h1:PnfP8KojtFuRg/fh0iT5lnKW4elMwN340NPpQG/ckA4= +github.com/hasura/ndc-sdk-go v1.7.1-0.20250216162428-dda5ec08bd7f/go.mod h1:1P1AsL24ll6TO0Qnn7oxivkM+uJSL5wC8mrormhu/7I= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= @@ -130,10 +132,12 @@ github.com/lmittmann/tint v1.0.7 h1:D/0OqWZ0YOGZ6AyC+5Y2kD8PBEzBk6rFHVSfOqCkF9Y= github.com/lmittmann/tint v1.0.7/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/minio/crc64nvme v1.0.0 h1:MeLcBkCTD4pAoU7TciAfwsfxgkhM2u5hCe48hSEVFr0= +github.com/minio/crc64nvme v1.0.0/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg= github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34= github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM= -github.com/minio/minio-go/v7 v7.0.84 h1:D1HVmAF8JF8Bpi6IU4V9vIEj+8pc+xU88EWMs2yed0E= -github.com/minio/minio-go/v7 v7.0.84/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY= +github.com/minio/minio-go/v7 v7.0.86 h1:DcgQ0AUjLJzRH6y/HrxiZ8CXarA70PAIufXHodP4s+k= +github.com/minio/minio-go/v7 v7.0.86/go.mod h1:VbfO4hYwUu3Of9WqGLBZ8vl3Hxnxo4ngxK4hzQDf4x4= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -208,37 +212,37 @@ go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE= +golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -google.golang.org/api v0.219.0 h1:nnKIvxKs/06jWawp2liznTBnMRQBEPpGo7I+oEypTX0= -google.golang.org/api v0.219.0/go.mod h1:K6OmjGm+NtLrIkHxv1U3a0qIf/0JOvAHd5O/6AoyKYE= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4= +golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +google.golang.org/api v0.221.0 h1:qzaJfLhDsbMeFee8zBRdt/Nc+xmOuafD/dbdgGfutOU= +google.golang.org/api v0.221.0/go.mod h1:7sOU2+TL4TxUTdbi0gWgAIg7tH5qBXxoyhtL+9x3biQ= google.golang.org/genproto v0.0.0-20250127172529-29210b9bc287 h1:WoUI1G0DQ648FKvSl756SKxHQR/bI+y4HyyIQfxMWI8= google.golang.org/genproto v0.0.0-20250127172529-29210b9bc287/go.mod h1:wkQ2Aj/xvshAUDtO/JHvu9y+AaN9cqs28QuSVSHtZSY= google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287 h1:A2ni10G3UlplFrWdCDJTl7D7mJ7GSRm37S+PDimaKRw= google.golang.org/genproto/googleapis/api v0.0.0-20250127172529-29210b9bc287/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287 h1:J1H9f+LEdWAfHcez/4cvaVBox7cOYT+IU6rgqj5x++8= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250127172529-29210b9bc287/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= -google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= -google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= diff --git a/jsonschema/configuration.schema.json b/jsonschema/configuration.schema.json index 0cbe53c..9e171fd 100644 --- a/jsonschema/configuration.schema.json +++ b/jsonschema/configuration.schema.json @@ -268,7 +268,7 @@ "description": "the path of a file containing a Kubernetes service account token" }, "audience": { - "type": "#/$defs/EnvString", + "$ref": "#/$defs/EnvString", "description": "Audience to use when requesting tokens for Azure Active Directory authentication" }, "disableInstanceDiscovery": { @@ -451,6 +451,9 @@ }, "runtime": { "$ref": "#/$defs/RuntimeSettings" + }, + "generator": { + "$ref": "#/$defs/GeneratorSettings" } }, "additionalProperties": false, @@ -483,6 +486,19 @@ }, "type": "object" }, + "GeneratorSettings": { + "properties": { + "promptqlCompatible": { + "type": "boolean", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "promptqlCompatible" + ] + }, "RuntimeSettings": { "properties": { "maxDownloadSizeMBs": { diff --git a/tests/configuration/configuration.yaml b/tests/configuration/configuration.yaml index a201a44..b76aec8 100644 --- a/tests/configuration/configuration.yaml +++ b/tests/configuration/configuration.yaml @@ -99,3 +99,5 @@ clients: concurrency: query: 10 mutation: 10 +generator: + promptqlCompatible: true diff --git a/tests/engine/app/metadata/ComposeStorageObject.hml b/tests/engine/app/metadata/ComposeStorageObject.hml index 18b4a2a..366fbca 100644 --- a/tests/engine/app/metadata/ComposeStorageObject.hml +++ b/tests/engine/app/metadata/ComposeStorageObject.hml @@ -10,7 +10,7 @@ definition: - name: legalHold type: Boolean - name: metadata - type: Json + type: "[StorageKeyValue!]" - name: mode type: StorageRetentionMode - name: object @@ -20,7 +20,7 @@ definition: - name: size type: Int64 - name: tags - type: Json + type: "[StorageKeyValue!]" graphql: typeName: StorageCopyDestOptions inputTypeName: StorageCopyDestOptionsInput diff --git a/tests/engine/app/metadata/CreateStorageBucket.hml b/tests/engine/app/metadata/CreateStorageBucket.hml index 31f10c9..54683ff 100644 --- a/tests/engine/app/metadata/CreateStorageBucket.hml +++ b/tests/engine/app/metadata/CreateStorageBucket.hml @@ -1,9 +1,36 @@ +--- +kind: ObjectType +version: v1 +definition: + name: SuccessResponse + description: represents a common successful response structure. + fields: + - name: success + type: Boolean! + graphql: + typeName: SuccessResponse + inputTypeName: SuccessResponseInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: SuccessResponse + +--- +kind: TypePermissions +version: v1 +definition: + typeName: SuccessResponse + permissions: + - role: admin + output: + allowedFields: + - success + --- kind: Command version: v1 definition: name: CreateStorageBucket - outputType: Boolean! + outputType: SuccessResponse! arguments: - name: clientId type: StorageClientId @@ -14,7 +41,7 @@ definition: - name: region type: String - name: tags - type: Json + type: "[StorageKeyValue!]" source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/DownloadStorageObject.hml b/tests/engine/app/metadata/DownloadStorageObject.hml index 3c692ab..057d184 100644 --- a/tests/engine/app/metadata/DownloadStorageObject.hml +++ b/tests/engine/app/metadata/DownloadStorageObject.hml @@ -2,80 +2,50 @@ kind: ObjectType version: v1 definition: - name: StorageObjectFilter + name: DownloadStorageObjectResponse + description: represents the object data response in base64-encode string format. fields: - - name: bucket - type: StorageBucketName! - - name: clientId - type: StorageClientId! - - name: object - type: StorageStringFilter! + - name: data + type: Bytes graphql: - typeName: StorageObjectFilter - inputTypeName: StorageObjectFilterInput + typeName: DownloadStorageObjectResponse + inputTypeName: DownloadStorageObjectResponseInput dataConnectorTypeMapping: - dataConnectorName: storage - dataConnectorObjectType: StorageObjectFilter + dataConnectorObjectType: DownloadStorageObjectResponse --- kind: TypePermissions version: v1 definition: - typeName: StorageObjectFilter + typeName: DownloadStorageObjectResponse permissions: - role: admin output: allowedFields: - - bucket - - clientId - - object - ---- -kind: BooleanExpressionType -version: v1 -definition: - name: StorageObjectFilterBoolExp - operand: - object: - type: StorageObjectFilter - comparableFields: - - fieldName: bucket - booleanExpressionType: StorageBucketNameBoolExp - - fieldName: clientId - booleanExpressionType: StorageClientIdBoolExp - - fieldName: object - booleanExpressionType: StorageStringFilterBoolExp - comparableRelationships: [] - logicalOperators: - enable: true - isNull: - enable: true - graphql: - typeName: StorageObjectFilterBoolExp + - data --- kind: Command version: v1 definition: name: DownloadStorageObject - outputType: Bytes + outputType: DownloadStorageObjectResponse! arguments: - name: bucket type: String - name: clientId type: StorageClientId - name: headers - type: Json + type: "[StorageKeyValue!]" - name: object type: String! - name: partNumber type: Int32 - name: requestParams - type: Json + type: "[StorageKeyValue!]" - name: versionId type: String - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/DownloadStorageObjectText.hml b/tests/engine/app/metadata/DownloadStorageObjectText.hml index 3312c46..d955497 100644 --- a/tests/engine/app/metadata/DownloadStorageObjectText.hml +++ b/tests/engine/app/metadata/DownloadStorageObjectText.hml @@ -1,26 +1,51 @@ +--- +kind: ObjectType +version: v1 +definition: + name: DownloadStorageObjectTextResponse + description: represents the object data response in string format. + fields: + - name: data + type: String + graphql: + typeName: DownloadStorageObjectTextResponse + inputTypeName: DownloadStorageObjectTextResponseInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: DownloadStorageObjectTextResponse + +--- +kind: TypePermissions +version: v1 +definition: + typeName: DownloadStorageObjectTextResponse + permissions: + - role: admin + output: + allowedFields: + - data + --- kind: Command version: v1 definition: name: DownloadStorageObjectText - outputType: String + outputType: DownloadStorageObjectTextResponse! arguments: - name: bucket type: String - name: clientId type: StorageClientId - name: headers - type: Json + type: "[StorageKeyValue!]" - name: object type: String! - name: partNumber type: Int32 - name: requestParams - type: Json + type: "[StorageKeyValue!]" - name: versionId type: String - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/RemoveIncompleteStorageUpload.hml b/tests/engine/app/metadata/RemoveIncompleteStorageUpload.hml index 5960bcc..64946a9 100644 --- a/tests/engine/app/metadata/RemoveIncompleteStorageUpload.hml +++ b/tests/engine/app/metadata/RemoveIncompleteStorageUpload.hml @@ -3,7 +3,7 @@ kind: Command version: v1 definition: name: RemoveIncompleteStorageUpload - outputType: Boolean! + outputType: SuccessResponse! arguments: - name: bucket type: String diff --git a/tests/engine/app/metadata/RemoveStorageBucket.hml b/tests/engine/app/metadata/RemoveStorageBucket.hml index 234dd87..b2d8c0e 100644 --- a/tests/engine/app/metadata/RemoveStorageBucket.hml +++ b/tests/engine/app/metadata/RemoveStorageBucket.hml @@ -3,7 +3,7 @@ kind: Command version: v1 definition: name: RemoveStorageBucket - outputType: Boolean! + outputType: SuccessResponse! arguments: - name: bucket type: String diff --git a/tests/engine/app/metadata/RemoveStorageObject.hml b/tests/engine/app/metadata/RemoveStorageObject.hml index b655e10..d315359 100644 --- a/tests/engine/app/metadata/RemoveStorageObject.hml +++ b/tests/engine/app/metadata/RemoveStorageObject.hml @@ -3,7 +3,7 @@ kind: Command version: v1 definition: name: RemoveStorageObject - outputType: Boolean! + outputType: SuccessResponse! arguments: - name: bucket type: String @@ -19,8 +19,6 @@ definition: type: Boolean - name: versionId type: String - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/RemoveStorageObjects.hml b/tests/engine/app/metadata/RemoveStorageObjects.hml index 1f26cce..232020d 100644 --- a/tests/engine/app/metadata/RemoveStorageObjects.hml +++ b/tests/engine/app/metadata/RemoveStorageObjects.hml @@ -6,7 +6,7 @@ definition: description: the container of Multi Delete S3 API error. fields: - name: error - type: Json + type: String! - name: objectName type: String! - name: versionId @@ -52,8 +52,6 @@ definition: type: Boolean - name: prefix type: String - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/RestoreStorageObject.hml b/tests/engine/app/metadata/RestoreStorageObject.hml index 8c53669..9f8d0a2 100644 --- a/tests/engine/app/metadata/RestoreStorageObject.hml +++ b/tests/engine/app/metadata/RestoreStorageObject.hml @@ -3,7 +3,7 @@ kind: Command version: v1 definition: name: RestoreStorageObject - outputType: Boolean! + outputType: SuccessResponse! arguments: - name: bucket type: String @@ -11,8 +11,6 @@ definition: type: StorageClientId - name: object type: String! - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/StorageBucket.hml b/tests/engine/app/metadata/StorageBucket.hml index eb36995..dc33d3f 100644 --- a/tests/engine/app/metadata/StorageBucket.hml +++ b/tests/engine/app/metadata/StorageBucket.hml @@ -1,769 +1,3 @@ ---- -kind: ObjectType -version: v1 -definition: - name: BucketAutoclass - fields: - - name: enabled - type: Boolean! - - name: terminalStorageClass - type: String! - - name: terminalStorageClassUpdateTime - type: TimestampTz! - - name: toggleTime - type: TimestampTz! - graphql: - typeName: BucketAutoclass - inputTypeName: BucketAutoclassInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: BucketAutoclass - ---- -kind: TypePermissions -version: v1 -definition: - typeName: BucketAutoclass - permissions: - - role: admin - output: - allowedFields: - - enabled - - terminalStorageClass - - terminalStorageClassUpdateTime - - toggleTime - ---- -kind: ObjectType -version: v1 -definition: - name: BucketCors - description: is the bucket's Cross-Origin Resource Sharing (CORS) configuration. - fields: - - name: maxAge - type: Duration! - - name: methods - type: "[String!]!" - - name: origins - type: "[String!]!" - - name: responseHeaders - type: "[String!]!" - graphql: - typeName: BucketCors - inputTypeName: BucketCorsInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: BucketCors - ---- -kind: TypePermissions -version: v1 -definition: - typeName: BucketCors - permissions: - - role: admin - output: - allowedFields: - - maxAge - - methods - - origins - - responseHeaders - ---- -kind: ObjectType -version: v1 -definition: - name: CustomPlacementConfig - description: holds the bucket's custom placement configuration for Custom Dual - Regions. See https://cloud.google.com/storage/docs/locations#location-dr for - more information. - fields: - - name: dataLocations - type: "[String!]!" - graphql: - typeName: CustomPlacementConfig - inputTypeName: CustomPlacementConfigInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: CustomPlacementConfig - fieldMapping: - dataLocations: - column: - name: DataLocations - ---- -kind: TypePermissions -version: v1 -definition: - typeName: CustomPlacementConfig - permissions: - - role: admin - output: - allowedFields: - - dataLocations - ---- -kind: ObjectType -version: v1 -definition: - name: ServerSideEncryptionConfiguration - description: is the default encryption configuration structure. - fields: - - name: kmsMasterKeyId - type: String - - name: sseAlgorithm - type: String - graphql: - typeName: ServerSideEncryptionConfiguration - inputTypeName: ServerSideEncryptionConfigurationInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ServerSideEncryptionConfiguration - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ServerSideEncryptionConfiguration - permissions: - - role: admin - output: - allowedFields: - - kmsMasterKeyId - - sseAlgorithm - ---- -kind: ObjectType -version: v1 -definition: - name: BucketHierarchicalNamespace - fields: - - name: enabled - type: Boolean! - graphql: - typeName: BucketHierarchicalNamespace - inputTypeName: BucketHierarchicalNamespaceInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: BucketHierarchicalNamespace - ---- -kind: TypePermissions -version: v1 -definition: - typeName: BucketHierarchicalNamespace - permissions: - - role: admin - output: - allowedFields: - - enabled - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectAbortIncompleteMultipartUpload - fields: - - name: daysAfterInitiation - type: Int32 - graphql: - typeName: ObjectAbortIncompleteMultipartUpload - inputTypeName: ObjectAbortIncompleteMultipartUploadInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectAbortIncompleteMultipartUpload - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectAbortIncompleteMultipartUpload - permissions: - - role: admin - output: - allowedFields: - - daysAfterInitiation - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleAllVersionsExpiration - description: represents AllVersionsExpiration actions element in an ILM policy - fields: - - name: days - type: Int32 - - name: deleteMarker - type: Boolean - graphql: - typeName: ObjectLifecycleAllVersionsExpiration - inputTypeName: ObjectLifecycleAllVersionsExpirationInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleAllVersionsExpiration - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleAllVersionsExpiration - permissions: - - role: admin - output: - allowedFields: - - days - - deleteMarker - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleDelMarkerExpiration - fields: - - name: days - type: Int32 - graphql: - typeName: ObjectLifecycleDelMarkerExpiration - inputTypeName: ObjectLifecycleDelMarkerExpirationInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleDelMarkerExpiration - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleDelMarkerExpiration - permissions: - - role: admin - output: - allowedFields: - - days - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleExpiration - description: expiration details of lifecycle configuration - fields: - - name: date - type: Date - - name: days - type: Int32 - - name: expiredObjectAllVersions - type: Boolean - - name: expiredObjectDeleteMarker - type: Boolean - graphql: - typeName: ObjectLifecycleExpiration - inputTypeName: ObjectLifecycleExpirationInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleExpiration - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleExpiration - permissions: - - role: admin - output: - allowedFields: - - date - - days - - expiredObjectAllVersions - - expiredObjectDeleteMarker - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleFilter - description: will be used in selecting rule(s) for lifecycle configuration - fields: - - name: matchesPrefix - type: "[String!]" - - name: matchesStorageClasses - type: "[String!]" - - name: matchesSuffix - type: "[String!]" - - name: objectSizeGreaterThan - type: Int64 - - name: objectSizeLessThan - type: Int64 - - name: tags - type: Json - graphql: - typeName: ObjectLifecycleFilter - inputTypeName: ObjectLifecycleFilterInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleFilter - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleFilter - permissions: - - role: admin - output: - allowedFields: - - matchesPrefix - - matchesStorageClasses - - matchesSuffix - - objectSizeGreaterThan - - objectSizeLessThan - - tags - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleNoncurrentVersionExpiration - description: "- Specifies when noncurrent object versions expire. Upon - expiration, server permanently deletes the noncurrent object versions. Set - this lifecycle configuration action on a bucket that has versioning enabled - (or suspended) to request server delete noncurrent object versions at a - specific period in the object's lifetime." - fields: - - name: newerNoncurrentVersions - type: Int32 - - name: noncurrentDays - type: Int32 - graphql: - typeName: ObjectLifecycleNoncurrentVersionExpiration - inputTypeName: ObjectLifecycleNoncurrentVersionExpirationInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleNoncurrentVersionExpiration - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleNoncurrentVersionExpiration - permissions: - - role: admin - output: - allowedFields: - - newerNoncurrentVersions - - noncurrentDays - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleNoncurrentVersionTransition - description: sets this action to request server to transition noncurrent object - versions to different set storage classes at a specific period in the - object's lifetime. - fields: - - name: newerNoncurrentVersions - type: Int32 - - name: noncurrentDays - type: Int32 - - name: storageClass - type: String - graphql: - typeName: ObjectLifecycleNoncurrentVersionTransition - inputTypeName: ObjectLifecycleNoncurrentVersionTransitionInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleNoncurrentVersionTransition - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleNoncurrentVersionTransition - permissions: - - role: admin - output: - allowedFields: - - newerNoncurrentVersions - - noncurrentDays - - storageClass - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleTransition - description: transition details of lifecycle configuration - fields: - - name: date - type: Date - - name: days - type: Int32 - - name: storageClass - type: String - graphql: - typeName: ObjectLifecycleTransition - inputTypeName: ObjectLifecycleTransitionInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleTransition - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleTransition - permissions: - - role: admin - output: - allowedFields: - - date - - days - - storageClass - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleRule - description: represents a single rule in lifecycle configuration - fields: - - name: abortIncompleteMultipartUpload - type: ObjectAbortIncompleteMultipartUpload - - name: allVersionsExpiration - type: ObjectLifecycleAllVersionsExpiration - - name: delMarkerExpiration - type: ObjectLifecycleDelMarkerExpiration - - name: enabled - type: Boolean - - name: expiration - type: ObjectLifecycleExpiration - - name: filter - type: "[ObjectLifecycleFilter!]" - - name: id - type: String - - name: noncurrentVersionExpiration - type: ObjectLifecycleNoncurrentVersionExpiration - - name: noncurrentVersionTransition - type: ObjectLifecycleNoncurrentVersionTransition - - name: prefix - type: String - - name: transition - type: ObjectLifecycleTransition - graphql: - typeName: ObjectLifecycleRule - inputTypeName: ObjectLifecycleRuleInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleRule - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleRule - permissions: - - role: admin - output: - allowedFields: - - abortIncompleteMultipartUpload - - allVersionsExpiration - - delMarkerExpiration - - enabled - - expiration - - filter - - id - - noncurrentVersionExpiration - - noncurrentVersionTransition - - prefix - - transition - ---- -kind: ObjectType -version: v1 -definition: - name: ObjectLifecycleConfiguration - description: is a collection of lifecycle Rule objects. - fields: - - name: rules - type: "[ObjectLifecycleRule!]!" - graphql: - typeName: ObjectLifecycleConfiguration - inputTypeName: ObjectLifecycleConfigurationInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: ObjectLifecycleConfiguration - ---- -kind: TypePermissions -version: v1 -definition: - typeName: ObjectLifecycleConfiguration - permissions: - - role: admin - output: - allowedFields: - - rules - ---- -kind: ObjectType -version: v1 -definition: - name: BucketLogging - description: holds the bucket's logging configuration, which defines the - destination bucket and optional name prefix for the current bucket's logs. - fields: - - name: logBucket - type: String! - - name: logObjectPrefix - type: String! - graphql: - typeName: BucketLogging - inputTypeName: BucketLoggingInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: BucketLogging - ---- -kind: TypePermissions -version: v1 -definition: - typeName: BucketLogging - permissions: - - role: admin - output: - allowedFields: - - logBucket - - logObjectPrefix - ---- -kind: ObjectType -version: v1 -definition: - name: StorageObjectLockConfig - description: represents the object lock configuration in given bucket - fields: - - name: enabled - type: Boolean! - - name: mode - type: StorageRetentionMode - - name: unit - type: StorageRetentionValidityUnit - - name: validity - type: Int32 - graphql: - typeName: StorageObjectLockConfig - inputTypeName: StorageObjectLockConfigInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageObjectLockConfig - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageObjectLockConfig - permissions: - - role: admin - output: - allowedFields: - - enabled - - mode - - unit - - validity - ---- -kind: ObjectType -version: v1 -definition: - name: StorageObjectSoftDeletePolicy - description: contains the bucket's soft delete policy, which defines the period - of time that soft-deleted objects will be retained, and cannot be - permanently deleted. - fields: - - name: effectiveTime - type: TimestampTz! - - name: retentionDuration - type: Duration! - graphql: - typeName: StorageObjectSoftDeletePolicy - inputTypeName: StorageObjectSoftDeletePolicyInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageObjectSoftDeletePolicy - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageObjectSoftDeletePolicy - permissions: - - role: admin - output: - allowedFields: - - effectiveTime - - retentionDuration - ---- -kind: ObjectType -version: v1 -definition: - name: StorageBucketVersioningConfiguration - description: is the versioning configuration structure - fields: - - name: enabled - type: Boolean! - - name: excludeFolders - type: Boolean - - name: excludedPrefixes - type: "[String!]" - - name: mfaDelete - type: String - graphql: - typeName: StorageBucketVersioningConfiguration - inputTypeName: StorageBucketVersioningConfigurationInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageBucketVersioningConfiguration - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageBucketVersioningConfiguration - permissions: - - role: admin - output: - allowedFields: - - enabled - - excludeFolders - - excludedPrefixes - - mfaDelete - ---- -kind: ObjectType -version: v1 -definition: - name: BucketWebsite - description: holds the bucket's website configuration, controlling how the - service behaves when accessing bucket contents as a web site. See - https://cloud.google.com/storage/docs/static-website for more information. - fields: - - name: mainPageSuffix - type: String! - - name: notFoundPage - type: String - graphql: - typeName: BucketWebsite - inputTypeName: BucketWebsiteInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: BucketWebsite - ---- -kind: TypePermissions -version: v1 -definition: - typeName: BucketWebsite - permissions: - - role: admin - output: - allowedFields: - - mainPageSuffix - - notFoundPage - ---- -kind: ObjectType -version: v1 -definition: - name: StorageBucket - description: the container for bucket metadata. - fields: - - name: autoclass - type: BucketAutoclass - - name: clientId - type: String! - - name: cors - type: "[BucketCors!]" - - name: creationTime - type: TimestampTz - - name: customPlacementConfig - type: CustomPlacementConfig - - name: defaultEventBasedHold - type: Boolean - - name: encryption - type: ServerSideEncryptionConfiguration - - name: etag - type: String - - name: hierarchicalNamespace - type: BucketHierarchicalNamespace - - name: lastModified - type: TimestampTz - - name: lifecycle - type: ObjectLifecycleConfiguration - - name: locationType - type: String - - name: logging - type: BucketLogging - - name: name - type: String! - - name: objectLock - type: StorageObjectLockConfig - - name: region - type: String - - name: requesterPays - type: Boolean - - name: rpo - type: GoogleStorageRpo - - name: softDeletePolicy - type: StorageObjectSoftDeletePolicy - - name: storageClass - type: String - - name: tags - type: Json - - name: versioning - type: StorageBucketVersioningConfiguration - - name: website - type: BucketWebsite - graphql: - typeName: StorageBucket - inputTypeName: StorageBucketInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageBucket - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageBucket - permissions: - - role: admin - output: - allowedFields: - - autoclass - - clientId - - cors - - creationTime - - customPlacementConfig - - defaultEventBasedHold - - encryption - - etag - - hierarchicalNamespace - - lastModified - - lifecycle - - locationType - - logging - - name - - objectLock - - region - - requesterPays - - rpo - - softDeletePolicy - - storageClass - - tags - - versioning - - website - --- kind: Command version: v1 diff --git a/tests/engine/app/metadata/StorageBucketConnections.hml b/tests/engine/app/metadata/StorageBucketConnections.hml new file mode 100644 index 0000000..e4c6968 --- /dev/null +++ b/tests/engine/app/metadata/StorageBucketConnections.hml @@ -0,0 +1,171 @@ +--- +kind: ObjectType +version: v1 +definition: + name: StorageBucketFilter + fields: + - name: clientId + type: StorageClientId! + - name: name + type: StorageStringFilter! + graphql: + typeName: StorageBucketFilter + inputTypeName: StorageBucketFilterInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageBucketFilter + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageBucketFilter + permissions: + - role: admin + output: + allowedFields: + - clientId + - name + +--- +kind: BooleanExpressionType +version: v1 +definition: + name: StorageBucketFilterBoolExp + operand: + object: + type: StorageBucketFilter + comparableFields: + - fieldName: clientId + booleanExpressionType: StorageClientIdBoolExp + - fieldName: name + booleanExpressionType: StorageStringFilterBoolExp + comparableRelationships: [] + logicalOperators: + enable: true + isNull: + enable: true + graphql: + typeName: StorageBucketFilterBoolExp + +--- +kind: ObjectType +version: v1 +definition: + name: StorageConnectionEdgeStorageBucket + description: the connection information of the relay pagination response. + fields: + - name: cursor + type: String! + - name: node + type: StorageBucket! + graphql: + typeName: StorageConnectionEdgeStorageBucket + inputTypeName: StorageConnectionEdgeStorageBucketInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageConnectionEdge_StorageBucket + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageConnectionEdgeStorageBucket + permissions: + - role: admin + output: + allowedFields: + - cursor + - node + +--- +kind: ObjectType +version: v1 +definition: + name: StoragePaginationInfo + description: holds the pagination information. + fields: + - name: hasNextPage + type: Boolean! + graphql: + typeName: StoragePaginationInfo + inputTypeName: StoragePaginationInfoInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StoragePaginationInfo + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StoragePaginationInfo + permissions: + - role: admin + output: + allowedFields: + - hasNextPage + +--- +kind: ObjectType +version: v1 +definition: + name: StorageConnectionStorageBucket + fields: + - name: edges + type: "[StorageConnectionEdgeStorageBucket!]!" + - name: pageInfo + type: StoragePaginationInfo! + graphql: + typeName: StorageConnectionStorageBucket + inputTypeName: StorageConnectionStorageBucketInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageConnection_StorageBucket + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageConnectionStorageBucket + permissions: + - role: admin + output: + allowedFields: + - edges + - pageInfo + +--- +kind: Command +version: v1 +definition: + name: StorageBucketConnections + outputType: StorageConnectionStorageBucket! + arguments: + - name: after + type: String + - name: clientId + type: StorageClientId + - name: first + type: Int32 + - name: prefix + type: String + - name: where + type: StorageBucketFilterBoolExp + source: + dataConnectorName: storage + dataConnectorCommand: + function: storageBucketConnections + graphql: + rootFieldName: storageBucketConnections + rootFieldKind: Query + description: list all buckets using the relay style. + +--- +kind: CommandPermissions +version: v1 +definition: + commandName: StorageBucketConnections + permissions: + - role: admin + allowExecution: true + diff --git a/tests/engine/app/metadata/StorageBucketExists.hml b/tests/engine/app/metadata/StorageBucketExists.hml index e91378e..49ef07b 100644 --- a/tests/engine/app/metadata/StorageBucketExists.hml +++ b/tests/engine/app/metadata/StorageBucketExists.hml @@ -1,9 +1,36 @@ +--- +kind: ObjectType +version: v1 +definition: + name: ExistsResponse + description: represents a common existing response structure. + fields: + - name: exists + type: Boolean! + graphql: + typeName: ExistsResponse + inputTypeName: ExistsResponseInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ExistsResponse + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ExistsResponse + permissions: + - role: admin + output: + allowedFields: + - exists + --- kind: Command version: v1 definition: name: StorageBucketExists - outputType: Boolean! + outputType: ExistsResponse! arguments: - name: bucket type: String diff --git a/tests/engine/app/metadata/StorageBuckets.hml b/tests/engine/app/metadata/StorageBuckets.hml index f0749d8..b4d8dc1 100644 --- a/tests/engine/app/metadata/StorageBuckets.hml +++ b/tests/engine/app/metadata/StorageBuckets.hml @@ -2,170 +2,903 @@ kind: ObjectType version: v1 definition: - name: StorageBucketFilter + name: BucketAutoclass fields: - - name: bucket - type: StorageStringFilter! - - name: clientId - type: StorageClientId! + - name: enabled + type: Boolean! + - name: terminalStorageClass + type: String! + - name: terminalStorageClassUpdateTime + type: TimestampTz! + - name: toggleTime + type: TimestampTz! graphql: - typeName: StorageBucketFilter - inputTypeName: StorageBucketFilterInput + typeName: BucketAutoclass + inputTypeName: BucketAutoclassInput dataConnectorTypeMapping: - dataConnectorName: storage - dataConnectorObjectType: StorageBucketFilter + dataConnectorObjectType: BucketAutoclass --- kind: TypePermissions version: v1 definition: - typeName: StorageBucketFilter + typeName: BucketAutoclass permissions: - role: admin output: allowedFields: - - bucket - - clientId + - enabled + - terminalStorageClass + - terminalStorageClassUpdateTime + - toggleTime --- -kind: BooleanExpressionType +kind: ObjectType version: v1 definition: - name: StorageBucketFilterBoolExp - operand: - object: - type: StorageBucketFilter - comparableFields: - - fieldName: bucket - booleanExpressionType: StorageStringFilterBoolExp - - fieldName: clientId - booleanExpressionType: StorageClientIdBoolExp - comparableRelationships: [] - logicalOperators: - enable: true - isNull: - enable: true + name: BucketCors + description: is the bucket's Cross-Origin Resource Sharing (CORS) configuration. + fields: + - name: maxAge + type: DurationString! + - name: methods + type: "[String!]!" + - name: origins + type: "[String!]!" + - name: responseHeaders + type: "[String!]!" + graphql: + typeName: BucketCors + inputTypeName: BucketCorsInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: BucketCors + +--- +kind: TypePermissions +version: v1 +definition: + typeName: BucketCors + permissions: + - role: admin + output: + allowedFields: + - maxAge + - methods + - origins + - responseHeaders + +--- +kind: ObjectType +version: v1 +definition: + name: CustomPlacementConfig + description: holds the bucket's custom placement configuration for Custom Dual + Regions. See https://cloud.google.com/storage/docs/locations#location-dr for + more information. + fields: + - name: dataLocations + type: "[String!]!" + graphql: + typeName: CustomPlacementConfig + inputTypeName: CustomPlacementConfigInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: CustomPlacementConfig + fieldMapping: + dataLocations: + column: + name: DataLocations + +--- +kind: TypePermissions +version: v1 +definition: + typeName: CustomPlacementConfig + permissions: + - role: admin + output: + allowedFields: + - dataLocations + +--- +kind: ObjectType +version: v1 +definition: + name: ServerSideEncryptionConfiguration + description: is the default encryption configuration structure. + fields: + - name: kmsMasterKeyId + type: String + - name: sseAlgorithm + type: String + graphql: + typeName: ServerSideEncryptionConfiguration + inputTypeName: ServerSideEncryptionConfigurationInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ServerSideEncryptionConfiguration + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ServerSideEncryptionConfiguration + permissions: + - role: admin + output: + allowedFields: + - kmsMasterKeyId + - sseAlgorithm + +--- +kind: ObjectType +version: v1 +definition: + name: BucketHierarchicalNamespace + fields: + - name: enabled + type: Boolean! + graphql: + typeName: BucketHierarchicalNamespace + inputTypeName: BucketHierarchicalNamespaceInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: BucketHierarchicalNamespace + +--- +kind: TypePermissions +version: v1 +definition: + typeName: BucketHierarchicalNamespace + permissions: + - role: admin + output: + allowedFields: + - enabled + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectAbortIncompleteMultipartUpload + fields: + - name: daysAfterInitiation + type: Int32 + graphql: + typeName: ObjectAbortIncompleteMultipartUpload + inputTypeName: ObjectAbortIncompleteMultipartUploadInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectAbortIncompleteMultipartUpload + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectAbortIncompleteMultipartUpload + permissions: + - role: admin + output: + allowedFields: + - daysAfterInitiation + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectLifecycleAllVersionsExpiration + description: represents AllVersionsExpiration actions element in an ILM policy + fields: + - name: days + type: Int32 + - name: deleteMarker + type: Boolean + graphql: + typeName: ObjectLifecycleAllVersionsExpiration + inputTypeName: ObjectLifecycleAllVersionsExpirationInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleAllVersionsExpiration + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleAllVersionsExpiration + permissions: + - role: admin + output: + allowedFields: + - days + - deleteMarker + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectLifecycleDelMarkerExpiration + fields: + - name: days + type: Int32 + graphql: + typeName: ObjectLifecycleDelMarkerExpiration + inputTypeName: ObjectLifecycleDelMarkerExpirationInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleDelMarkerExpiration + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleDelMarkerExpiration + permissions: + - role: admin + output: + allowedFields: + - days + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectLifecycleExpiration + description: expiration details of lifecycle configuration + fields: + - name: date + type: Date + - name: days + type: Int32 + - name: expiredObjectAllVersions + type: Boolean + - name: expiredObjectDeleteMarker + type: Boolean + graphql: + typeName: ObjectLifecycleExpiration + inputTypeName: ObjectLifecycleExpirationInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleExpiration + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleExpiration + permissions: + - role: admin + output: + allowedFields: + - date + - days + - expiredObjectAllVersions + - expiredObjectDeleteMarker + +--- +kind: ObjectType +version: v1 +definition: + name: StorageKeyValue + description: represent a key-value string pair + fields: + - name: key + type: String! + - name: value + type: String! + graphql: + typeName: StorageKeyValue + inputTypeName: StorageKeyValueInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageKeyValue + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageKeyValue + permissions: + - role: admin + output: + allowedFields: + - key + - value + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectLifecycleFilter + description: will be used in selecting rule(s) for lifecycle configuration + fields: + - name: matchesPrefix + type: "[String!]" + - name: matchesStorageClasses + type: "[String!]" + - name: matchesSuffix + type: "[String!]" + - name: objectSizeGreaterThan + type: Int64 + - name: objectSizeLessThan + type: Int64 + - name: tags + type: "[StorageKeyValue!]" + graphql: + typeName: ObjectLifecycleFilter + inputTypeName: ObjectLifecycleFilterInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleFilter + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleFilter + permissions: + - role: admin + output: + allowedFields: + - matchesPrefix + - matchesStorageClasses + - matchesSuffix + - objectSizeGreaterThan + - objectSizeLessThan + - tags + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectLifecycleNoncurrentVersionExpiration + description: "- Specifies when noncurrent object versions expire. Upon + expiration, server permanently deletes the noncurrent object versions. Set + this lifecycle configuration action on a bucket that has versioning enabled + (or suspended) to request server delete noncurrent object versions at a + specific period in the object's lifetime." + fields: + - name: newerNoncurrentVersions + type: Int32 + - name: noncurrentDays + type: Int32 + graphql: + typeName: ObjectLifecycleNoncurrentVersionExpiration + inputTypeName: ObjectLifecycleNoncurrentVersionExpirationInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleNoncurrentVersionExpiration + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleNoncurrentVersionExpiration + permissions: + - role: admin + output: + allowedFields: + - newerNoncurrentVersions + - noncurrentDays + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectLifecycleNoncurrentVersionTransition + description: sets this action to request server to transition noncurrent object + versions to different set storage classes at a specific period in the + object's lifetime. + fields: + - name: newerNoncurrentVersions + type: Int32 + - name: noncurrentDays + type: Int32 + - name: storageClass + type: String + graphql: + typeName: ObjectLifecycleNoncurrentVersionTransition + inputTypeName: ObjectLifecycleNoncurrentVersionTransitionInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleNoncurrentVersionTransition + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleNoncurrentVersionTransition + permissions: + - role: admin + output: + allowedFields: + - newerNoncurrentVersions + - noncurrentDays + - storageClass + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectLifecycleTransition + description: transition details of lifecycle configuration + fields: + - name: date + type: Date + - name: days + type: Int32 + - name: storageClass + type: String graphql: - typeName: StorageBucketFilterBoolExp + typeName: ObjectLifecycleTransition + inputTypeName: ObjectLifecycleTransitionInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleTransition + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleTransition + permissions: + - role: admin + output: + allowedFields: + - date + - days + - storageClass + +--- +kind: ObjectType +version: v1 +definition: + name: ObjectLifecycleRule + description: represents a single rule in lifecycle configuration + fields: + - name: abortIncompleteMultipartUpload + type: ObjectAbortIncompleteMultipartUpload + - name: allVersionsExpiration + type: ObjectLifecycleAllVersionsExpiration + - name: delMarkerExpiration + type: ObjectLifecycleDelMarkerExpiration + - name: enabled + type: Boolean + - name: expiration + type: ObjectLifecycleExpiration + - name: filter + type: "[ObjectLifecycleFilter!]" + - name: id + type: String + - name: noncurrentVersionExpiration + type: ObjectLifecycleNoncurrentVersionExpiration + - name: noncurrentVersionTransition + type: ObjectLifecycleNoncurrentVersionTransition + - name: prefix + type: String + - name: transition + type: ObjectLifecycleTransition + graphql: + typeName: ObjectLifecycleRule + inputTypeName: ObjectLifecycleRuleInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleRule + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleRule + permissions: + - role: admin + output: + allowedFields: + - abortIncompleteMultipartUpload + - allVersionsExpiration + - delMarkerExpiration + - enabled + - expiration + - filter + - id + - noncurrentVersionExpiration + - noncurrentVersionTransition + - prefix + - transition --- kind: ObjectType version: v1 definition: - name: StorageConnectionEdgeStorageBucket - description: the connection information of the relay pagination response. + name: ObjectLifecycleConfiguration + description: is a collection of lifecycle Rule objects. fields: - - name: cursor + - name: rules + type: "[ObjectLifecycleRule!]!" + graphql: + typeName: ObjectLifecycleConfiguration + inputTypeName: ObjectLifecycleConfigurationInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: ObjectLifecycleConfiguration + +--- +kind: TypePermissions +version: v1 +definition: + typeName: ObjectLifecycleConfiguration + permissions: + - role: admin + output: + allowedFields: + - rules + +--- +kind: ObjectType +version: v1 +definition: + name: BucketLogging + description: holds the bucket's logging configuration, which defines the + destination bucket and optional name prefix for the current bucket's logs. + fields: + - name: logBucket + type: String! + - name: logObjectPrefix type: String! - - name: node - type: StorageBucket! graphql: - typeName: StorageConnectionEdgeStorageBucket - inputTypeName: StorageConnectionEdgeStorageBucketInput + typeName: BucketLogging + inputTypeName: BucketLoggingInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: BucketLogging + +--- +kind: TypePermissions +version: v1 +definition: + typeName: BucketLogging + permissions: + - role: admin + output: + allowedFields: + - logBucket + - logObjectPrefix + +--- +kind: ObjectType +version: v1 +definition: + name: StorageObjectLockConfig + description: represents the object lock configuration in given bucket + fields: + - name: enabled + type: Boolean! + - name: mode + type: StorageRetentionMode + - name: unit + type: StorageRetentionValidityUnit + - name: validity + type: Int32 + graphql: + typeName: StorageObjectLockConfig + inputTypeName: StorageObjectLockConfigInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageObjectLockConfig + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageObjectLockConfig + permissions: + - role: admin + output: + allowedFields: + - enabled + - mode + - unit + - validity + +--- +kind: ObjectType +version: v1 +definition: + name: StorageObjectSoftDeletePolicy + description: contains the bucket's soft delete policy, which defines the period + of time that soft-deleted objects will be retained, and cannot be + permanently deleted. + fields: + - name: effectiveTime + type: TimestampTz! + - name: retentionDuration + type: DurationString! + graphql: + typeName: StorageObjectSoftDeletePolicy + inputTypeName: StorageObjectSoftDeletePolicyInput dataConnectorTypeMapping: - dataConnectorName: storage - dataConnectorObjectType: StorageConnectionEdge_StorageBucket + dataConnectorObjectType: StorageObjectSoftDeletePolicy --- kind: TypePermissions version: v1 definition: - typeName: StorageConnectionEdgeStorageBucket + typeName: StorageObjectSoftDeletePolicy permissions: - role: admin output: allowedFields: - - cursor - - node + - effectiveTime + - retentionDuration --- kind: ObjectType version: v1 definition: - name: StoragePaginationInfo - description: holds the pagination information. + name: StorageBucketVersioningConfiguration + description: is the versioning configuration structure fields: - - name: hasNextPage + - name: enabled type: Boolean! + - name: excludeFolders + type: Boolean + - name: excludedPrefixes + type: "[String!]" + - name: mfaDelete + type: String graphql: - typeName: StoragePaginationInfo - inputTypeName: StoragePaginationInfoInput + typeName: StorageBucketVersioningConfiguration + inputTypeName: StorageBucketVersioningConfigurationInput dataConnectorTypeMapping: - dataConnectorName: storage - dataConnectorObjectType: StoragePaginationInfo + dataConnectorObjectType: StorageBucketVersioningConfiguration --- kind: TypePermissions version: v1 definition: - typeName: StoragePaginationInfo + typeName: StorageBucketVersioningConfiguration permissions: - role: admin output: allowedFields: - - hasNextPage + - enabled + - excludeFolders + - excludedPrefixes + - mfaDelete --- kind: ObjectType version: v1 definition: - name: StorageConnectionStorageBucket + name: BucketWebsite + description: holds the bucket's website configuration, controlling how the + service behaves when accessing bucket contents as a web site. See + https://cloud.google.com/storage/docs/static-website for more information. fields: - - name: edges - type: "[StorageConnectionEdgeStorageBucket!]!" - - name: pageInfo - type: StoragePaginationInfo! + - name: mainPageSuffix + type: String! + - name: notFoundPage + type: String graphql: - typeName: StorageConnectionStorageBucket - inputTypeName: StorageConnectionStorageBucketInput + typeName: BucketWebsite + inputTypeName: BucketWebsiteInput dataConnectorTypeMapping: - dataConnectorName: storage - dataConnectorObjectType: StorageConnection_StorageBucket + dataConnectorObjectType: BucketWebsite --- kind: TypePermissions version: v1 definition: - typeName: StorageConnectionStorageBucket + typeName: BucketWebsite permissions: - role: admin output: allowedFields: - - edges - - pageInfo + - mainPageSuffix + - notFoundPage --- -kind: Command +kind: ObjectType version: v1 +definition: + name: StorageBucket + description: the container for bucket metadata. + fields: + - name: autoclass + type: BucketAutoclass + - name: clientId + type: StorageClientId! + - name: cors + type: "[BucketCors!]" + - name: creationTime + type: TimestampTz + - name: customPlacementConfig + type: CustomPlacementConfig + - name: defaultEventBasedHold + type: Boolean + - name: encryption + type: ServerSideEncryptionConfiguration + - name: etag + type: String + - name: hierarchicalNamespace + type: BucketHierarchicalNamespace + - name: lastModified + type: TimestampTz + - name: lifecycle + type: ObjectLifecycleConfiguration + - name: locationType + type: String + - name: logging + type: BucketLogging + - name: name + type: StorageStringFilter! + - name: objectLock + type: StorageObjectLockConfig + - name: region + type: String + - name: requesterPays + type: Boolean + - name: rpo + type: GoogleStorageRpo + - name: softDeletePolicy + type: StorageObjectSoftDeletePolicy + - name: storageClass + type: String + - name: tags + type: "[StorageKeyValue!]" + - name: versioning + type: StorageBucketVersioningConfiguration + - name: website + type: BucketWebsite + graphql: + typeName: StorageBucket + inputTypeName: StorageBucketInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageBucket + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageBucket + permissions: + - role: admin + output: + allowedFields: + - autoclass + - clientId + - cors + - creationTime + - customPlacementConfig + - defaultEventBasedHold + - encryption + - etag + - hierarchicalNamespace + - lastModified + - lifecycle + - locationType + - logging + - name + - objectLock + - region + - requesterPays + - rpo + - softDeletePolicy + - storageClass + - tags + - versioning + - website + +--- +kind: BooleanExpressionType +version: v1 +definition: + name: StorageBucketBoolExp + operand: + object: + type: StorageBucket + comparableFields: + - fieldName: clientId + booleanExpressionType: StorageClientIdBoolExp + - fieldName: creationTime + booleanExpressionType: TimestampTzBoolExp + - fieldName: defaultEventBasedHold + booleanExpressionType: BooleanBoolExp + - fieldName: etag + booleanExpressionType: StringBoolExp + - fieldName: lastModified + booleanExpressionType: TimestampTzBoolExp + - fieldName: locationType + booleanExpressionType: StringBoolExp + - fieldName: name + booleanExpressionType: StorageStringFilterBoolExp + - fieldName: region + booleanExpressionType: StringBoolExp + - fieldName: requesterPays + booleanExpressionType: BooleanBoolExp + - fieldName: rpo + booleanExpressionType: GoogleStorageRpoBoolExp + - fieldName: storageClass + booleanExpressionType: StringBoolExp + comparableRelationships: [] + logicalOperators: + enable: true + isNull: + enable: true + graphql: + typeName: StorageBucketBoolExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: StorageBucketOrderByExp + operand: + object: + orderedType: StorageBucket + orderableFields: + - fieldName: clientId + orderByExpression: StorageClientIdOrderByExp + - fieldName: creationTime + orderByExpression: TimestampTzOrderByExp + - fieldName: defaultEventBasedHold + orderByExpression: BooleanOrderByExp + - fieldName: etag + orderByExpression: StringOrderByExp + - fieldName: lastModified + orderByExpression: TimestampTzOrderByExp + - fieldName: locationType + orderByExpression: StringOrderByExp + - fieldName: name + orderByExpression: StorageStringFilterOrderByExp + - fieldName: region + orderByExpression: StringOrderByExp + - fieldName: requesterPays + orderByExpression: BooleanOrderByExp + - fieldName: rpo + orderByExpression: GoogleStorageRpoOrderByExp + - fieldName: storageClass + orderByExpression: StringOrderByExp + orderableRelationships: [] + graphql: + expressionTypeName: StorageBucketOrderByExp + +--- +kind: Model +version: v2 definition: name: StorageBuckets - outputType: StorageConnectionStorageBucket! + objectType: StorageBucket arguments: - name: after type: String - - name: clientId - type: StorageClientId - - name: first - type: Int32 - - name: prefix - type: String - - name: where - type: StorageBucketFilterBoolExp source: dataConnectorName: storage - dataConnectorCommand: - function: storageBuckets + collection: storageBuckets + filterExpressionType: StorageBucketBoolExp + orderByExpression: StorageBucketOrderByExp graphql: - rootFieldName: storageBuckets - rootFieldKind: Query - description: list all buckets. + selectMany: + queryRootField: storageBuckets + subscription: + rootField: storageBuckets + selectUniques: [] + argumentsInputType: StorageBucketsArguments + description: List storage buckets --- -kind: CommandPermissions +kind: ModelPermissions version: v1 definition: - commandName: StorageBuckets + modelName: StorageBuckets permissions: - role: admin - allowExecution: true + select: + filter: null + allowSubscriptions: true diff --git a/tests/engine/app/metadata/StorageDeletedObjects.hml b/tests/engine/app/metadata/StorageDeletedObjects.hml index ee4095e..65c197a 100644 --- a/tests/engine/app/metadata/StorageDeletedObjects.hml +++ b/tests/engine/app/metadata/StorageDeletedObjects.hml @@ -1,378 +1,3 @@ ---- -kind: ObjectType -version: v1 -definition: - name: StorageObjectCopyInfo - description: holds the copy information if the object was copied from another object. - fields: - - name: completionTime - type: TimestampTz - - name: id - type: String! - - name: progress - type: String - - name: source - type: String - - name: status - type: String - - name: statusDescription - type: String - graphql: - typeName: StorageObjectCopyInfo - inputTypeName: StorageObjectCopyInfoInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageObjectCopyInfo - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageObjectCopyInfo - permissions: - - role: admin - output: - allowedFields: - - completionTime - - id - - progress - - source - - status - - statusDescription - ---- -kind: ObjectType -version: v1 -definition: - name: StorageGrantee - description: represents the person being granted permissions. - fields: - - name: displayName - type: String - - name: id - type: String - - name: uri - type: String - graphql: - typeName: StorageGrantee - inputTypeName: StorageGranteeInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageGrantee - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageGrantee - permissions: - - role: admin - output: - allowedFields: - - displayName - - id - - uri - ---- -kind: ObjectType -version: v1 -definition: - name: StorageGrant - description: holds grant information. - fields: - - name: grantee - type: StorageGrantee - - name: permission - type: String - graphql: - typeName: StorageGrant - inputTypeName: StorageGrantInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageGrant - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageGrant - permissions: - - role: admin - output: - allowedFields: - - grantee - - permission - ---- -kind: ObjectType -version: v1 -definition: - name: StorageOwner - description: name. - fields: - - name: id - type: String - - name: name - type: String - graphql: - typeName: StorageOwner - inputTypeName: StorageOwnerInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageOwner - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageOwner - permissions: - - role: admin - output: - allowedFields: - - id - - name - ---- -kind: ObjectType -version: v1 -definition: - name: StorageRestoreInfo - description: contains information of the restore operation of an archived object. - fields: - - name: expiryTime - type: TimestampTz - - name: ongoingRestore - type: Boolean! - graphql: - typeName: StorageRestoreInfo - inputTypeName: StorageRestoreInfoInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageRestoreInfo - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageRestoreInfo - permissions: - - role: admin - output: - allowedFields: - - expiryTime - - ongoingRestore - ---- -kind: ObjectType -version: v1 -definition: - name: StorageObject - description: container for object metadata. - fields: - - name: accessTierChangeTime - type: TimestampTz - - name: accessTierInferred - type: Boolean - - name: acl - type: Json - - name: archiveStatus - type: String - - name: blobSequenceNumber - type: Int64 - - name: blobType - type: String - - name: bucket - type: String! - - name: cacheControl - type: String - - name: checksumCrc32 - type: String - - name: checksumCrc32C - type: String - - name: checksumCrc64Nvme - type: String - - name: checksumSha1 - type: String - - name: checksumSha256 - type: String - - name: clientId - type: String! - - name: contentDisposition - type: String - - name: contentEncoding - type: String - - name: contentLanguage - type: String - - name: contentMd5 - type: String - - name: contentType - type: String - - name: copy - type: StorageObjectCopyInfo - - name: creationTime - type: TimestampTz - - name: customerProvidedKeySha256 - type: String - - name: deleted - type: Boolean - - name: deletedTime - type: TimestampTz - - name: destinationSnapshot - type: String - - name: etag - type: String - - name: expiration - type: TimestampTz - - name: expirationRuleId - type: String - - name: expires - type: TimestampTz - - name: grant - type: "[StorageGrant!]" - - name: group - type: String - - name: incrementalCopy - type: Boolean - - name: isDirectory - type: Boolean! - - name: isLatest - type: Boolean - - name: kmsKeyName - type: String - - name: lastAccessTime - type: TimestampTz - - name: lastModified - type: TimestampTz! - - name: leaseDuration - type: String - - name: leaseState - type: String - - name: leaseStatus - type: String - - name: legalHold - type: Boolean - - name: mediaLink - type: String - - name: metadata - type: Json - - name: name - type: String! - - name: owner - type: StorageOwner - - name: permissions - type: String - - name: rawMetadata - type: Json - - name: rehydratePriority - type: String - - name: remainingRetentionDays - type: Int32 - - name: replicationReady - type: Boolean - - name: replicationStatus - type: StorageObjectReplicationStatus - - name: resourceType - type: String - - name: restore - type: StorageRestoreInfo - - name: retentionMode - type: String - - name: retentionUntilDate - type: TimestampTz - - name: sealed - type: Boolean - - name: serverEncrypted - type: Boolean - - name: size - type: Int64 - - name: storageClass - type: String - - name: tagCount - type: Int32 - - name: tags - type: Json - - name: versionId - type: String - graphql: - typeName: StorageObject - inputTypeName: StorageObjectInput - dataConnectorTypeMapping: - - dataConnectorName: storage - dataConnectorObjectType: StorageObject - ---- -kind: TypePermissions -version: v1 -definition: - typeName: StorageObject - permissions: - - role: admin - output: - allowedFields: - - accessTierChangeTime - - accessTierInferred - - acl - - archiveStatus - - blobSequenceNumber - - blobType - - bucket - - cacheControl - - checksumCrc32 - - checksumCrc32C - - checksumCrc64Nvme - - checksumSha1 - - checksumSha256 - - clientId - - contentDisposition - - contentEncoding - - contentLanguage - - contentMd5 - - contentType - - copy - - creationTime - - customerProvidedKeySha256 - - deleted - - deletedTime - - destinationSnapshot - - etag - - expiration - - expirationRuleId - - expires - - grant - - group - - incrementalCopy - - isDirectory - - isLatest - - kmsKeyName - - lastAccessTime - - lastModified - - leaseDuration - - leaseState - - leaseStatus - - legalHold - - mediaLink - - metadata - - name - - owner - - permissions - - rawMetadata - - rehydratePriority - - remainingRetentionDays - - replicationReady - - replicationStatus - - resourceType - - restore - - retentionMode - - retentionUntilDate - - sealed - - serverEncrypted - - size - - storageClass - - tagCount - - tags - - versionId - --- kind: ObjectType version: v1 @@ -422,8 +47,6 @@ definition: type: Boolean - name: prefix type: String - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/StorageObject.hml b/tests/engine/app/metadata/StorageObject.hml index d7f72e5..d9c4774 100644 --- a/tests/engine/app/metadata/StorageObject.hml +++ b/tests/engine/app/metadata/StorageObject.hml @@ -10,17 +10,15 @@ definition: - name: clientId type: StorageClientId - name: headers - type: Json + type: "[StorageKeyValue!]" - name: object type: String! - name: partNumber type: Int32 - name: requestParams - type: Json + type: "[StorageKeyValue!]" - name: versionId type: String - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/StorageObjectConnections.hml b/tests/engine/app/metadata/StorageObjectConnections.hml new file mode 100644 index 0000000..5321a12 --- /dev/null +++ b/tests/engine/app/metadata/StorageObjectConnections.hml @@ -0,0 +1,153 @@ +--- +kind: ObjectType +version: v1 +definition: + name: StorageObjectFilter + fields: + - name: bucket + type: StorageBucketName! + - name: clientId + type: StorageClientId! + - name: name + type: StorageStringFilter! + graphql: + typeName: StorageObjectFilter + inputTypeName: StorageObjectFilterInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageObjectFilter + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageObjectFilter + permissions: + - role: admin + output: + allowedFields: + - bucket + - clientId + - name + +--- +kind: BooleanExpressionType +version: v1 +definition: + name: StorageObjectFilterBoolExp + operand: + object: + type: StorageObjectFilter + comparableFields: + - fieldName: bucket + booleanExpressionType: StorageBucketNameBoolExp + - fieldName: clientId + booleanExpressionType: StorageClientIdBoolExp + - fieldName: name + booleanExpressionType: StorageStringFilterBoolExp + comparableRelationships: [] + logicalOperators: + enable: true + isNull: + enable: true + graphql: + typeName: StorageObjectFilterBoolExp + +--- +kind: ObjectType +version: v1 +definition: + name: StorageConnectionEdgeStorageObject + description: the connection information of the relay pagination response. + fields: + - name: cursor + type: String! + - name: node + type: StorageObject! + graphql: + typeName: StorageConnectionEdgeStorageObject + inputTypeName: StorageConnectionEdgeStorageObjectInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageConnectionEdge_StorageObject + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageConnectionEdgeStorageObject + permissions: + - role: admin + output: + allowedFields: + - cursor + - node + +--- +kind: ObjectType +version: v1 +definition: + name: StorageConnectionStorageObject + fields: + - name: edges + type: "[StorageConnectionEdgeStorageObject!]!" + - name: pageInfo + type: StoragePaginationInfo! + graphql: + typeName: StorageConnectionStorageObject + inputTypeName: StorageConnectionStorageObjectInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageConnection_StorageObject + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageConnectionStorageObject + permissions: + - role: admin + output: + allowedFields: + - edges + - pageInfo + +--- +kind: Command +version: v1 +definition: + name: StorageObjectConnections + outputType: StorageConnectionStorageObject! + arguments: + - name: after + type: String + - name: bucket + type: String + - name: clientId + type: StorageClientId + - name: first + type: Int32 + - name: hierarchy + type: Boolean + - name: prefix + type: String + - name: where + type: StorageObjectFilterBoolExp + source: + dataConnectorName: storage + dataConnectorCommand: + function: storageObjectConnections + graphql: + rootFieldName: storageObjectConnections + rootFieldKind: Query + description: lists objects in a bucket using the relay style. + +--- +kind: CommandPermissions +version: v1 +definition: + commandName: StorageObjectConnections + permissions: + - role: admin + allowExecution: true + diff --git a/tests/engine/app/metadata/StorageObjects.hml b/tests/engine/app/metadata/StorageObjects.hml index ac7296a..53a116b 100644 --- a/tests/engine/app/metadata/StorageObjects.hml +++ b/tests/engine/app/metadata/StorageObjects.hml @@ -2,97 +2,660 @@ kind: ObjectType version: v1 definition: - name: StorageConnectionEdgeStorageObject - description: the connection information of the relay pagination response. + name: StorageObjectCopyInfo + description: holds the copy information if the object was copied from another object. fields: - - name: cursor + - name: completionTime + type: TimestampTz + - name: id type: String! - - name: node - type: StorageObject! + - name: progress + type: String + - name: source + type: String + - name: status + type: String + - name: statusDescription + type: String graphql: - typeName: StorageConnectionEdgeStorageObject - inputTypeName: StorageConnectionEdgeStorageObjectInput + typeName: StorageObjectCopyInfo + inputTypeName: StorageObjectCopyInfoInput dataConnectorTypeMapping: - dataConnectorName: storage - dataConnectorObjectType: StorageConnectionEdge_StorageObject + dataConnectorObjectType: StorageObjectCopyInfo --- kind: TypePermissions version: v1 definition: - typeName: StorageConnectionEdgeStorageObject + typeName: StorageObjectCopyInfo permissions: - role: admin output: allowedFields: - - cursor - - node + - completionTime + - id + - progress + - source + - status + - statusDescription --- kind: ObjectType version: v1 definition: - name: StorageConnectionStorageObject + name: StorageGrantee + description: represents the person being granted permissions. fields: - - name: edges - type: "[StorageConnectionEdgeStorageObject!]!" - - name: pageInfo - type: StoragePaginationInfo! + - name: displayName + type: String + - name: id + type: String + - name: uri + type: String graphql: - typeName: StorageConnectionStorageObject - inputTypeName: StorageConnectionStorageObjectInput + typeName: StorageGrantee + inputTypeName: StorageGranteeInput dataConnectorTypeMapping: - dataConnectorName: storage - dataConnectorObjectType: StorageConnection_StorageObject + dataConnectorObjectType: StorageGrantee --- kind: TypePermissions version: v1 definition: - typeName: StorageConnectionStorageObject + typeName: StorageGrantee permissions: - role: admin output: allowedFields: - - edges - - pageInfo + - displayName + - id + - uri --- -kind: Command +kind: ObjectType version: v1 definition: - name: StorageObjects - outputType: StorageConnectionStorageObject! - arguments: - - name: after + name: StorageGrant + description: holds grant information. + fields: + - name: grantee + type: StorageGrantee + - name: permission + type: String + graphql: + typeName: StorageGrant + inputTypeName: StorageGrantInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageGrant + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageGrant + permissions: + - role: admin + output: + allowedFields: + - grantee + - permission + +--- +kind: ObjectType +version: v1 +definition: + name: StorageOwner + description: name. + fields: + - name: id + type: String + - name: name + type: String + graphql: + typeName: StorageOwner + inputTypeName: StorageOwnerInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageOwner + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageOwner + permissions: + - role: admin + output: + allowedFields: + - id + - name + +--- +kind: ObjectType +version: v1 +definition: + name: StorageRestoreInfo + description: contains information of the restore operation of an archived object. + fields: + - name: expiryTime + type: TimestampTz + - name: ongoingRestore + type: Boolean! + graphql: + typeName: StorageRestoreInfo + inputTypeName: StorageRestoreInfoInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageRestoreInfo + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageRestoreInfo + permissions: + - role: admin + output: + allowedFields: + - expiryTime + - ongoingRestore + +--- +kind: ObjectType +version: v1 +definition: + name: StorageObject + description: container for object metadata. + fields: + - name: accessTierChangeTime + type: TimestampTz + - name: accessTierInferred + type: Boolean + - name: acl + type: Json + - name: archiveStatus + type: String + - name: blobSequenceNumber + type: Int64 + - name: blobType type: String - name: bucket + type: StorageBucketName! + - name: cacheControl + type: String + - name: checksumCrc32 + type: String + - name: checksumCrc32C + type: String + - name: checksumCrc64Nvme + type: String + - name: checksumSha1 + type: String + - name: checksumSha256 type: String - name: clientId - type: StorageClientId - - name: first + type: StorageClientId! + - name: contentDisposition + type: String + - name: contentEncoding + type: String + - name: contentLanguage + type: String + - name: contentMd5 + type: String + - name: contentType + type: String + - name: copy + type: StorageObjectCopyInfo + - name: creationTime + type: TimestampTz + - name: customerProvidedKeySha256 + type: String + - name: deleted + type: Boolean + - name: deletedTime + type: TimestampTz + - name: destinationSnapshot + type: String + - name: etag + type: String + - name: expiration + type: TimestampTz + - name: expirationRuleId + type: String + - name: expires + type: TimestampTz + - name: grant + type: "[StorageGrant!]" + - name: group + type: String + - name: incrementalCopy + type: Boolean + - name: isDirectory + type: Boolean! + - name: isLatest + type: Boolean + - name: kmsKeyName + type: String + - name: lastAccessTime + type: TimestampTz + - name: lastModified + type: TimestampTz! + - name: leaseDuration + type: String + - name: leaseState + type: String + - name: leaseStatus + type: String + - name: legalHold + type: Boolean + - name: mediaLink + type: String + - name: metadata + type: "[StorageKeyValue!]" + - name: name + type: StorageStringFilter! + - name: owner + type: StorageOwner + - name: permissions + type: String + - name: rawMetadata + type: "[StorageKeyValue!]" + - name: rehydratePriority + type: String + - name: remainingRetentionDays type: Int32 - - name: hierarchy + - name: replicationReady + type: Boolean + - name: replicationStatus + type: StorageObjectReplicationStatus + - name: resourceType + type: String + - name: restore + type: StorageRestoreInfo + - name: retentionMode + type: String + - name: retentionUntilDate + type: TimestampTz + - name: sealed + type: Boolean + - name: serverEncrypted type: Boolean - - name: prefix + - name: size + type: Int64 + - name: storageClass type: String - - name: where - type: StorageObjectFilterBoolExp + - name: tagCount + type: Int32 + - name: tags + type: "[StorageKeyValue!]" + - name: versionId + type: String + graphql: + typeName: StorageObject + inputTypeName: StorageObjectInput + dataConnectorTypeMapping: + - dataConnectorName: storage + dataConnectorObjectType: StorageObject + +--- +kind: TypePermissions +version: v1 +definition: + typeName: StorageObject + permissions: + - role: admin + output: + allowedFields: + - accessTierChangeTime + - accessTierInferred + - acl + - archiveStatus + - blobSequenceNumber + - blobType + - bucket + - cacheControl + - checksumCrc32 + - checksumCrc32C + - checksumCrc64Nvme + - checksumSha1 + - checksumSha256 + - clientId + - contentDisposition + - contentEncoding + - contentLanguage + - contentMd5 + - contentType + - copy + - creationTime + - customerProvidedKeySha256 + - deleted + - deletedTime + - destinationSnapshot + - etag + - expiration + - expirationRuleId + - expires + - grant + - group + - incrementalCopy + - isDirectory + - isLatest + - kmsKeyName + - lastAccessTime + - lastModified + - leaseDuration + - leaseState + - leaseStatus + - legalHold + - mediaLink + - metadata + - name + - owner + - permissions + - rawMetadata + - rehydratePriority + - remainingRetentionDays + - replicationReady + - replicationStatus + - resourceType + - restore + - retentionMode + - retentionUntilDate + - sealed + - serverEncrypted + - size + - storageClass + - tagCount + - tags + - versionId + +--- +kind: BooleanExpressionType +version: v1 +definition: + name: StorageObjectBoolExp + operand: + object: + type: StorageObject + comparableFields: + - fieldName: accessTierChangeTime + booleanExpressionType: TimestampTzBoolExp + - fieldName: accessTierInferred + booleanExpressionType: BooleanBoolExp + - fieldName: acl + booleanExpressionType: JsonBoolExp + - fieldName: archiveStatus + booleanExpressionType: StringBoolExp + - fieldName: blobSequenceNumber + booleanExpressionType: Int64BoolExp + - fieldName: blobType + booleanExpressionType: StringBoolExp + - fieldName: bucket + booleanExpressionType: StorageBucketNameBoolExp + - fieldName: cacheControl + booleanExpressionType: StringBoolExp + - fieldName: checksumCrc32 + booleanExpressionType: StringBoolExp + - fieldName: checksumCrc32C + booleanExpressionType: StringBoolExp + - fieldName: checksumCrc64Nvme + booleanExpressionType: StringBoolExp + - fieldName: checksumSha1 + booleanExpressionType: StringBoolExp + - fieldName: checksumSha256 + booleanExpressionType: StringBoolExp + - fieldName: clientId + booleanExpressionType: StorageClientIdBoolExp + - fieldName: contentDisposition + booleanExpressionType: StringBoolExp + - fieldName: contentEncoding + booleanExpressionType: StringBoolExp + - fieldName: contentLanguage + booleanExpressionType: StringBoolExp + - fieldName: contentMd5 + booleanExpressionType: StringBoolExp + - fieldName: contentType + booleanExpressionType: StringBoolExp + - fieldName: creationTime + booleanExpressionType: TimestampTzBoolExp + - fieldName: customerProvidedKeySha256 + booleanExpressionType: StringBoolExp + - fieldName: deleted + booleanExpressionType: BooleanBoolExp + - fieldName: deletedTime + booleanExpressionType: TimestampTzBoolExp + - fieldName: destinationSnapshot + booleanExpressionType: StringBoolExp + - fieldName: etag + booleanExpressionType: StringBoolExp + - fieldName: expiration + booleanExpressionType: TimestampTzBoolExp + - fieldName: expirationRuleId + booleanExpressionType: StringBoolExp + - fieldName: expires + booleanExpressionType: TimestampTzBoolExp + - fieldName: group + booleanExpressionType: StringBoolExp + - fieldName: incrementalCopy + booleanExpressionType: BooleanBoolExp + - fieldName: isDirectory + booleanExpressionType: BooleanBoolExp + - fieldName: isLatest + booleanExpressionType: BooleanBoolExp + - fieldName: kmsKeyName + booleanExpressionType: StringBoolExp + - fieldName: lastAccessTime + booleanExpressionType: TimestampTzBoolExp + - fieldName: lastModified + booleanExpressionType: TimestampTzBoolExp + - fieldName: leaseDuration + booleanExpressionType: StringBoolExp + - fieldName: leaseState + booleanExpressionType: StringBoolExp + - fieldName: leaseStatus + booleanExpressionType: StringBoolExp + - fieldName: legalHold + booleanExpressionType: BooleanBoolExp + - fieldName: mediaLink + booleanExpressionType: StringBoolExp + - fieldName: name + booleanExpressionType: StorageStringFilterBoolExp + - fieldName: permissions + booleanExpressionType: StringBoolExp + - fieldName: rehydratePriority + booleanExpressionType: StringBoolExp + - fieldName: remainingRetentionDays + booleanExpressionType: Int32BoolExp + - fieldName: replicationReady + booleanExpressionType: BooleanBoolExp + - fieldName: replicationStatus + booleanExpressionType: StorageObjectReplicationStatusBoolExp + - fieldName: resourceType + booleanExpressionType: StringBoolExp + - fieldName: retentionMode + booleanExpressionType: StringBoolExp + - fieldName: retentionUntilDate + booleanExpressionType: TimestampTzBoolExp + - fieldName: sealed + booleanExpressionType: BooleanBoolExp + - fieldName: serverEncrypted + booleanExpressionType: BooleanBoolExp + - fieldName: size + booleanExpressionType: Int64BoolExp + - fieldName: storageClass + booleanExpressionType: StringBoolExp + - fieldName: tagCount + booleanExpressionType: Int32BoolExp + - fieldName: versionId + booleanExpressionType: StringBoolExp + comparableRelationships: [] + logicalOperators: + enable: true + isNull: + enable: true + graphql: + typeName: StorageObjectBoolExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: StorageObjectOrderByExp + operand: + object: + orderedType: StorageObject + orderableFields: + - fieldName: accessTierChangeTime + orderByExpression: TimestampTzOrderByExp + - fieldName: accessTierInferred + orderByExpression: BooleanOrderByExp + - fieldName: acl + orderByExpression: JsonOrderByExp + - fieldName: archiveStatus + orderByExpression: StringOrderByExp + - fieldName: blobSequenceNumber + orderByExpression: Int64OrderByExp + - fieldName: blobType + orderByExpression: StringOrderByExp + - fieldName: bucket + orderByExpression: StorageBucketNameOrderByExp + - fieldName: cacheControl + orderByExpression: StringOrderByExp + - fieldName: checksumCrc32 + orderByExpression: StringOrderByExp + - fieldName: checksumCrc32C + orderByExpression: StringOrderByExp + - fieldName: checksumCrc64Nvme + orderByExpression: StringOrderByExp + - fieldName: checksumSha1 + orderByExpression: StringOrderByExp + - fieldName: checksumSha256 + orderByExpression: StringOrderByExp + - fieldName: clientId + orderByExpression: StorageClientIdOrderByExp + - fieldName: contentDisposition + orderByExpression: StringOrderByExp + - fieldName: contentEncoding + orderByExpression: StringOrderByExp + - fieldName: contentLanguage + orderByExpression: StringOrderByExp + - fieldName: contentMd5 + orderByExpression: StringOrderByExp + - fieldName: contentType + orderByExpression: StringOrderByExp + - fieldName: creationTime + orderByExpression: TimestampTzOrderByExp + - fieldName: customerProvidedKeySha256 + orderByExpression: StringOrderByExp + - fieldName: deleted + orderByExpression: BooleanOrderByExp + - fieldName: deletedTime + orderByExpression: TimestampTzOrderByExp + - fieldName: destinationSnapshot + orderByExpression: StringOrderByExp + - fieldName: etag + orderByExpression: StringOrderByExp + - fieldName: expiration + orderByExpression: TimestampTzOrderByExp + - fieldName: expirationRuleId + orderByExpression: StringOrderByExp + - fieldName: expires + orderByExpression: TimestampTzOrderByExp + - fieldName: group + orderByExpression: StringOrderByExp + - fieldName: incrementalCopy + orderByExpression: BooleanOrderByExp + - fieldName: isDirectory + orderByExpression: BooleanOrderByExp + - fieldName: isLatest + orderByExpression: BooleanOrderByExp + - fieldName: kmsKeyName + orderByExpression: StringOrderByExp + - fieldName: lastAccessTime + orderByExpression: TimestampTzOrderByExp + - fieldName: lastModified + orderByExpression: TimestampTzOrderByExp + - fieldName: leaseDuration + orderByExpression: StringOrderByExp + - fieldName: leaseState + orderByExpression: StringOrderByExp + - fieldName: leaseStatus + orderByExpression: StringOrderByExp + - fieldName: legalHold + orderByExpression: BooleanOrderByExp + - fieldName: mediaLink + orderByExpression: StringOrderByExp + - fieldName: name + orderByExpression: StorageStringFilterOrderByExp + - fieldName: permissions + orderByExpression: StringOrderByExp + - fieldName: rehydratePriority + orderByExpression: StringOrderByExp + - fieldName: remainingRetentionDays + orderByExpression: Int32OrderByExp + - fieldName: replicationReady + orderByExpression: BooleanOrderByExp + - fieldName: replicationStatus + orderByExpression: StorageObjectReplicationStatusOrderByExp + - fieldName: resourceType + orderByExpression: StringOrderByExp + - fieldName: retentionMode + orderByExpression: StringOrderByExp + - fieldName: retentionUntilDate + orderByExpression: TimestampTzOrderByExp + - fieldName: sealed + orderByExpression: BooleanOrderByExp + - fieldName: serverEncrypted + orderByExpression: BooleanOrderByExp + - fieldName: size + orderByExpression: Int64OrderByExp + - fieldName: storageClass + orderByExpression: StringOrderByExp + - fieldName: tagCount + orderByExpression: Int32OrderByExp + - fieldName: versionId + orderByExpression: StringOrderByExp + orderableRelationships: [] + graphql: + expressionTypeName: StorageObjectOrderByExp + +--- +kind: Model +version: v2 +definition: + name: StorageObjects + objectType: StorageObject + arguments: + - name: after + type: String + - name: hierarchy + type: Boolean source: dataConnectorName: storage - dataConnectorCommand: - function: storageObjects + collection: storageObjects + filterExpressionType: StorageObjectBoolExp + orderByExpression: StorageObjectOrderByExp graphql: - rootFieldName: storageObjects - rootFieldKind: Query - description: lists objects in a bucket. + selectMany: + queryRootField: storageObjects + subscription: + rootField: storageObjects + selectUniques: [] + argumentsInputType: StorageObjectsArguments + description: List storage objects --- -kind: CommandPermissions +kind: ModelPermissions version: v1 definition: - commandName: StorageObjects + modelName: StorageObjects permissions: - role: admin - allowExecution: true + select: + filter: null + allowSubscriptions: true diff --git a/tests/engine/app/metadata/StoragePresignedDownloadUrl.hml b/tests/engine/app/metadata/StoragePresignedDownloadUrl.hml index f28ee3f..3fe8b15 100644 --- a/tests/engine/app/metadata/StoragePresignedDownloadUrl.hml +++ b/tests/engine/app/metadata/StoragePresignedDownloadUrl.hml @@ -6,7 +6,7 @@ definition: description: holds the presigned URL and expiry information. fields: - name: expiredAt - type: String! + type: TimestampTz! - name: url type: String! graphql: @@ -40,13 +40,11 @@ definition: - name: clientId type: StorageClientId - name: expiry - type: Duration + type: DurationString - name: object type: String! - name: requestParams - type: Json - - name: where - type: StorageObjectFilterBoolExp + type: "[StorageKeyValue!]" source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/StoragePresignedUploadUrl.hml b/tests/engine/app/metadata/StoragePresignedUploadUrl.hml index 69949a0..91d3fb5 100644 --- a/tests/engine/app/metadata/StoragePresignedUploadUrl.hml +++ b/tests/engine/app/metadata/StoragePresignedUploadUrl.hml @@ -10,11 +10,9 @@ definition: - name: clientId type: StorageClientId - name: expiry - type: Duration + type: DurationString - name: object type: String! - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/UpdateStorageBucket.hml b/tests/engine/app/metadata/UpdateStorageBucket.hml index c09b47a..c24466f 100644 --- a/tests/engine/app/metadata/UpdateStorageBucket.hml +++ b/tests/engine/app/metadata/UpdateStorageBucket.hml @@ -36,7 +36,7 @@ kind: Command version: v1 definition: name: UpdateStorageBucket - outputType: Boolean! + outputType: SuccessResponse! arguments: - name: bucket type: String @@ -49,7 +49,7 @@ definition: - name: objectLock type: SetStorageObjectLockConfig - name: tags - type: Json + type: "[StorageKeyValue!]" - name: versioningEnabled type: Boolean source: diff --git a/tests/engine/app/metadata/UpdateStorageObject.hml b/tests/engine/app/metadata/UpdateStorageObject.hml index 472eb4d..f585c81 100644 --- a/tests/engine/app/metadata/UpdateStorageObject.hml +++ b/tests/engine/app/metadata/UpdateStorageObject.hml @@ -36,7 +36,7 @@ kind: Command version: v1 definition: name: UpdateStorageObject - outputType: Boolean! + outputType: SuccessResponse! arguments: - name: bucket type: String @@ -45,17 +45,15 @@ definition: - name: legalHold type: Boolean - name: metadata - type: Json + type: "[StorageKeyValue!]" - name: object type: String! - name: retention type: SetStorageObjectRetentionOptions - name: tags - type: Json + type: "[StorageKeyValue!]" - name: versionId type: String - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/UploadStorageObject.hml b/tests/engine/app/metadata/UploadStorageObject.hml index 1328495..b1bf66e 100644 --- a/tests/engine/app/metadata/UploadStorageObject.hml +++ b/tests/engine/app/metadata/UploadStorageObject.hml @@ -63,7 +63,7 @@ definition: - name: legalHold type: Boolean - name: metadata - type: Json + type: "[StorageKeyValue!]" - name: numThreads type: Int32 - name: partSize @@ -75,7 +75,7 @@ definition: - name: storageClass type: String - name: tags - type: Json + type: "[StorageKeyValue!]" - name: websiteRedirectLocation type: String graphql: @@ -132,8 +132,6 @@ definition: type: String! - name: options type: PutStorageObjectOptions - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/UploadStorageObjectText.hml b/tests/engine/app/metadata/UploadStorageObjectText.hml index 8a753e5..5c461ce 100644 --- a/tests/engine/app/metadata/UploadStorageObjectText.hml +++ b/tests/engine/app/metadata/UploadStorageObjectText.hml @@ -15,8 +15,6 @@ definition: type: String! - name: options type: PutStorageObjectOptions - - name: where - type: StorageObjectFilterBoolExp source: dataConnectorName: storage dataConnectorCommand: diff --git a/tests/engine/app/metadata/storage-types.hml b/tests/engine/app/metadata/storage-types.hml index abc4287..3e99177 100644 --- a/tests/engine/app/metadata/storage-types.hml +++ b/tests/engine/app/metadata/storage-types.hml @@ -8,6 +8,54 @@ definition: graphql: comparisonExpressionTypeName: StringComparisonExp +--- +kind: DataConnectorScalarRepresentation +version: v1 +definition: + dataConnectorName: storage + dataConnectorScalarType: Boolean + representation: Boolean + graphql: + comparisonExpressionTypeName: BooleanComparisonExp + +--- +kind: ScalarType +version: v1 +definition: + name: TimestampTz + graphql: + typeName: TimestampTz + +--- +kind: BooleanExpressionType +version: v1 +definition: + name: TimestampTzBoolExp + operand: + scalar: + type: TimestampTz + comparisonOperators: [] + dataConnectorOperatorMapping: + - dataConnectorName: storage + dataConnectorScalarType: TimestampTZ + operatorMapping: {} + logicalOperators: + enable: true + isNull: + enable: true + graphql: + typeName: TimestampTzBoolExp + +--- +kind: DataConnectorScalarRepresentation +version: v1 +definition: + dataConnectorName: storage + dataConnectorScalarType: TimestampTZ + representation: TimestampTz + graphql: + comparisonExpressionTypeName: TimestampTzComparisonExp + --- kind: ScalarType version: v1 @@ -52,39 +100,39 @@ definition: kind: ScalarType version: v1 definition: - name: Json + name: DurationString graphql: - typeName: Json + typeName: DurationString --- kind: BooleanExpressionType version: v1 definition: - name: JsonBoolExp + name: DurationStringBoolExp operand: scalar: - type: Json + type: DurationString comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: JSON + dataConnectorScalarType: DurationString operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: JsonBoolExp + typeName: DurationStringBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: JSON - representation: Json + dataConnectorScalarType: DurationString + representation: DurationString graphql: - comparisonExpressionTypeName: JsonComparisonExp + comparisonExpressionTypeName: DurationStringComparisonExp --- kind: ScalarType @@ -128,41 +176,77 @@ definition: kind: ScalarType version: v1 definition: - name: StorageBucketName + name: Date graphql: - typeName: StorageBucketName + typeName: Date --- kind: BooleanExpressionType version: v1 definition: - name: StorageBucketNameBoolExp + name: DateBoolExp operand: scalar: - type: StorageBucketName - comparisonOperators: - - name: _eq - argumentType: StorageBucketName! + type: Date + comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: StorageBucketName + dataConnectorScalarType: Date operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: StorageBucketNameBoolExp + typeName: DateBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: StorageBucketName - representation: StorageBucketName + dataConnectorScalarType: Date + representation: Date graphql: - comparisonExpressionTypeName: StorageBucketNameComparisonExp + comparisonExpressionTypeName: DateComparisonExp + +--- +kind: ScalarType +version: v1 +definition: + name: Int64 + graphql: + typeName: Int64 + +--- +kind: BooleanExpressionType +version: v1 +definition: + name: Int64BoolExp + operand: + scalar: + type: Int64 + comparisonOperators: [] + dataConnectorOperatorMapping: + - dataConnectorName: storage + dataConnectorScalarType: Int64 + operatorMapping: {} + logicalOperators: + enable: true + isNull: + enable: true + graphql: + typeName: Int64BoolExp + +--- +kind: DataConnectorScalarRepresentation +version: v1 +definition: + dataConnectorName: storage + dataConnectorScalarType: Int64 + representation: Int64 + graphql: + comparisonExpressionTypeName: Int64ComparisonExp --- kind: ScalarType @@ -214,353 +298,452 @@ definition: kind: ScalarType version: v1 definition: - name: Bytes + name: StorageRetentionMode graphql: - typeName: Bytes + typeName: StorageRetentionMode --- kind: BooleanExpressionType version: v1 definition: - name: BytesBoolExp + name: StorageRetentionModeBoolExp operand: scalar: - type: Bytes + type: StorageRetentionMode comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: Bytes + dataConnectorScalarType: StorageRetentionMode operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: BytesBoolExp - ---- -kind: DataConnectorScalarRepresentation -version: v1 -definition: - dataConnectorName: storage - dataConnectorScalarType: Bytes - representation: Bytes - graphql: - comparisonExpressionTypeName: BytesComparisonExp + typeName: StorageRetentionModeBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: Boolean - representation: Boolean + dataConnectorScalarType: StorageRetentionMode + representation: StorageRetentionMode graphql: - comparisonExpressionTypeName: BooleanComparisonExp + comparisonExpressionTypeName: StorageRetentionModeComparisonExp --- kind: ScalarType version: v1 definition: - name: TimestampTz + name: StorageRetentionValidityUnit graphql: - typeName: TimestampTz + typeName: StorageRetentionValidityUnit --- kind: BooleanExpressionType version: v1 definition: - name: TimestampTzBoolExp + name: StorageRetentionValidityUnitBoolExp operand: scalar: - type: TimestampTz + type: StorageRetentionValidityUnit comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: TimestampTZ + dataConnectorScalarType: StorageRetentionValidityUnit operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: TimestampTzBoolExp + typeName: StorageRetentionValidityUnitBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: TimestampTZ - representation: TimestampTz + dataConnectorScalarType: StorageRetentionValidityUnit + representation: StorageRetentionValidityUnit graphql: - comparisonExpressionTypeName: TimestampTzComparisonExp + comparisonExpressionTypeName: StorageRetentionValidityUnitComparisonExp --- kind: ScalarType version: v1 definition: - name: Duration + name: GoogleStorageRpo graphql: - typeName: Duration + typeName: GoogleStorageRpo --- kind: BooleanExpressionType version: v1 definition: - name: DurationBoolExp + name: GoogleStorageRpoBoolExp operand: scalar: - type: Duration + type: GoogleStorageRpo comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: Duration + dataConnectorScalarType: GoogleStorageRPO operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: DurationBoolExp + typeName: GoogleStorageRpoBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: Duration - representation: Duration + dataConnectorScalarType: GoogleStorageRPO + representation: GoogleStorageRpo graphql: - comparisonExpressionTypeName: DurationComparisonExp + comparisonExpressionTypeName: GoogleStorageRpoComparisonExp --- -kind: ScalarType +kind: BooleanExpressionType version: v1 definition: - name: Date + name: BooleanBoolExp + operand: + scalar: + type: Boolean + comparisonOperators: [] + dataConnectorOperatorMapping: + - dataConnectorName: storage + dataConnectorScalarType: Boolean + operatorMapping: {} + logicalOperators: + enable: true + isNull: + enable: true graphql: - typeName: Date + typeName: BooleanBoolExp --- kind: BooleanExpressionType version: v1 definition: - name: DateBoolExp + name: StringBoolExp operand: scalar: - type: Date + type: String comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: Date + dataConnectorScalarType: String operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: DateBoolExp + typeName: StringBoolExp --- -kind: DataConnectorScalarRepresentation +kind: OrderByExpression version: v1 definition: - dataConnectorName: storage - dataConnectorScalarType: Date - representation: Date + name: StorageClientIdOrderByExp + operand: + scalar: + orderedType: StorageClientId + enableOrderByDirections: + enableAll: true graphql: - comparisonExpressionTypeName: DateComparisonExp + expressionTypeName: StorageClientIdOrderByExp --- -kind: ScalarType +kind: OrderByExpression version: v1 definition: - name: Int64 + name: TimestampTzOrderByExp + operand: + scalar: + orderedType: TimestampTz + enableOrderByDirections: + enableAll: true graphql: - typeName: Int64 + expressionTypeName: TimestampTzOrderByExp --- -kind: BooleanExpressionType +kind: OrderByExpression version: v1 definition: - name: Int64BoolExp + name: BooleanOrderByExp operand: scalar: - type: Int64 - comparisonOperators: [] - dataConnectorOperatorMapping: - - dataConnectorName: storage - dataConnectorScalarType: Int64 - operatorMapping: {} - logicalOperators: - enable: true - isNull: - enable: true + orderedType: Boolean + enableOrderByDirections: + enableAll: true graphql: - typeName: Int64BoolExp + expressionTypeName: BooleanOrderByExp --- -kind: DataConnectorScalarRepresentation +kind: OrderByExpression version: v1 definition: - dataConnectorName: storage - dataConnectorScalarType: Int64 - representation: Int64 + name: StringOrderByExp + operand: + scalar: + orderedType: String + enableOrderByDirections: + enableAll: true graphql: - comparisonExpressionTypeName: Int64ComparisonExp + expressionTypeName: StringOrderByExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: StorageStringFilterOrderByExp + operand: + scalar: + orderedType: StorageStringFilter + enableOrderByDirections: + enableAll: true + graphql: + expressionTypeName: StorageStringFilterOrderByExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: GoogleStorageRpoOrderByExp + operand: + scalar: + orderedType: GoogleStorageRpo + enableOrderByDirections: + enableAll: true + graphql: + expressionTypeName: GoogleStorageRpoOrderByExp --- kind: ScalarType version: v1 definition: - name: StorageRetentionMode + name: Json graphql: - typeName: StorageRetentionMode + typeName: Json --- kind: BooleanExpressionType version: v1 definition: - name: StorageRetentionModeBoolExp + name: JsonBoolExp operand: scalar: - type: StorageRetentionMode + type: Json comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: StorageRetentionMode + dataConnectorScalarType: JSON operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: StorageRetentionModeBoolExp + typeName: JsonBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: StorageRetentionMode - representation: StorageRetentionMode + dataConnectorScalarType: JSON + representation: Json graphql: - comparisonExpressionTypeName: StorageRetentionModeComparisonExp + comparisonExpressionTypeName: JsonComparisonExp --- kind: ScalarType version: v1 definition: - name: StorageRetentionValidityUnit + name: StorageBucketName graphql: - typeName: StorageRetentionValidityUnit + typeName: StorageBucketName --- kind: BooleanExpressionType version: v1 definition: - name: StorageRetentionValidityUnitBoolExp + name: StorageBucketNameBoolExp operand: scalar: - type: StorageRetentionValidityUnit - comparisonOperators: [] + type: StorageBucketName + comparisonOperators: + - name: _eq + argumentType: StorageBucketName! dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: StorageRetentionValidityUnit + dataConnectorScalarType: StorageBucketName operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: StorageRetentionValidityUnitBoolExp + typeName: StorageBucketNameBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: StorageRetentionValidityUnit - representation: StorageRetentionValidityUnit + dataConnectorScalarType: StorageBucketName + representation: StorageBucketName graphql: - comparisonExpressionTypeName: StorageRetentionValidityUnitComparisonExp + comparisonExpressionTypeName: StorageBucketNameComparisonExp --- kind: ScalarType version: v1 definition: - name: GoogleStorageRpo + name: StorageObjectReplicationStatus graphql: - typeName: GoogleStorageRpo + typeName: StorageObjectReplicationStatus --- kind: BooleanExpressionType version: v1 definition: - name: GoogleStorageRpoBoolExp + name: StorageObjectReplicationStatusBoolExp operand: scalar: - type: GoogleStorageRpo + type: StorageObjectReplicationStatus comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: GoogleStorageRPO + dataConnectorScalarType: StorageObjectReplicationStatus operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: GoogleStorageRpoBoolExp + typeName: StorageObjectReplicationStatusBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: GoogleStorageRPO - representation: GoogleStorageRpo + dataConnectorScalarType: StorageObjectReplicationStatus + representation: StorageObjectReplicationStatus graphql: - comparisonExpressionTypeName: GoogleStorageRpoComparisonExp + comparisonExpressionTypeName: StorageObjectReplicationStatusComparisonExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: JsonOrderByExp + operand: + scalar: + orderedType: Json + enableOrderByDirections: + enableAll: true + graphql: + expressionTypeName: JsonOrderByExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: Int64OrderByExp + operand: + scalar: + orderedType: Int64 + enableOrderByDirections: + enableAll: true + graphql: + expressionTypeName: Int64OrderByExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: StorageBucketNameOrderByExp + operand: + scalar: + orderedType: StorageBucketName + enableOrderByDirections: + enableAll: true + graphql: + expressionTypeName: StorageBucketNameOrderByExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: Int32OrderByExp + operand: + scalar: + orderedType: Int32 + enableOrderByDirections: + enableAll: true + graphql: + expressionTypeName: Int32OrderByExp + +--- +kind: OrderByExpression +version: v1 +definition: + name: StorageObjectReplicationStatusOrderByExp + operand: + scalar: + orderedType: StorageObjectReplicationStatus + enableOrderByDirections: + enableAll: true + graphql: + expressionTypeName: StorageObjectReplicationStatusOrderByExp --- kind: ScalarType version: v1 definition: - name: StorageObjectReplicationStatus + name: Bytes graphql: - typeName: StorageObjectReplicationStatus + typeName: Bytes --- kind: BooleanExpressionType version: v1 definition: - name: StorageObjectReplicationStatusBoolExp + name: BytesBoolExp operand: scalar: - type: StorageObjectReplicationStatus + type: Bytes comparisonOperators: [] dataConnectorOperatorMapping: - dataConnectorName: storage - dataConnectorScalarType: StorageObjectReplicationStatus + dataConnectorScalarType: Bytes operatorMapping: {} logicalOperators: enable: true isNull: enable: true graphql: - typeName: StorageObjectReplicationStatusBoolExp + typeName: BytesBoolExp --- kind: DataConnectorScalarRepresentation version: v1 definition: dataConnectorName: storage - dataConnectorScalarType: StorageObjectReplicationStatus - representation: StorageObjectReplicationStatus + dataConnectorScalarType: Bytes + representation: Bytes graphql: - comparisonExpressionTypeName: StorageObjectReplicationStatusComparisonExp + comparisonExpressionTypeName: BytesComparisonExp --- kind: ScalarType diff --git a/tests/engine/app/metadata/storage.hml b/tests/engine/app/metadata/storage.hml index aaa5515..379c3b3 100644 --- a/tests/engine/app/metadata/storage.hml +++ b/tests/engine/app/metadata/storage.hml @@ -19,7 +19,7 @@ definition: comparison_operators: {} Bytes: representation: - type: bytes + type: string aggregate_functions: {} comparison_operators: {} ChecksumType: @@ -41,9 +41,9 @@ definition: type: date aggregate_functions: {} comparison_operators: {} - Duration: + DurationString: representation: - type: json + type: string aggregate_functions: {} comparison_operators: {} GoogleStorageRPO: @@ -175,7 +175,7 @@ definition: maxAge: type: type: named - name: Duration + name: DurationString methods: type: type: array @@ -233,6 +233,31 @@ definition: element_type: type: named name: String + DownloadStorageObjectResponse: + description: represents the object data response in base64-encode string format. + fields: + data: + type: + type: nullable + underlying_type: + type: named + name: Bytes + DownloadStorageObjectTextResponse: + description: represents the object data response in string format. + fields: + data: + type: + type: nullable + underlying_type: + type: named + name: String + ExistsResponse: + description: represents a common existing response structure. + fields: + exists: + type: + type: named + name: Boolean GetStorageObjectOptions: description: are used to specify additional headers or options during GET requests. fields: @@ -240,8 +265,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue partNumber: type: type: nullable @@ -252,8 +279,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versionId: type: type: nullable @@ -337,8 +366,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue ObjectAbortIncompleteMultipartUpload: fields: daysAfterInitiation: @@ -449,8 +480,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue ObjectLifecycleNoncurrentVersionExpiration: description: '- Specifies when noncurrent object versions expire. Upon expiration, server permanently deletes the noncurrent object versions. Set this lifecycle configuration action on a bucket that has versioning enabled (or suspended) to request server delete noncurrent object versions at a specific period in the object''s lifetime.' fields: @@ -587,20 +620,22 @@ definition: type: nullable underlying_type: type: named - name: Duration + name: DurationString requestParams: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue PresignedURLResponse: description: holds the presigned URL and expiry information. fields: expiredAt: type: type: named - name: String + name: TimestampTZ url: type: type: named @@ -715,8 +750,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue numThreads: type: type: nullable @@ -751,8 +788,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue websiteRedirectLocation: type: type: nullable @@ -781,10 +820,8 @@ definition: fields: error: type: - type: nullable - underlying_type: - type: named - name: JSON + type: named + name: String objectName: type: type: named @@ -889,7 +926,7 @@ definition: clientId: type: type: named - name: String + name: StorageClientID cors: type: type: nullable @@ -961,7 +998,7 @@ definition: name: type: type: named - name: String + name: StorageStringFilter objectLock: type: type: nullable @@ -1002,8 +1039,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versioning: type: type: nullable @@ -1033,14 +1072,14 @@ definition: name: StorageClientID StorageBucketFilter: fields: - bucket: - type: - type: named - name: StorageStringFilter clientId: type: type: named name: StorageClientID + name: + type: + type: named + name: StorageStringFilter StorageBucketVersioningConfiguration: description: is the versioning configuration structure fields: @@ -1133,8 +1172,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue mode: type: type: nullable @@ -1161,8 +1202,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue StorageCopySrcOptions: description: represents a source object to be copied, using server-side copying APIs. fields: @@ -1260,6 +1303,17 @@ definition: underlying_type: type: named name: String + StorageKeyValue: + description: represent a key-value string pair + fields: + key: + type: + type: named + name: String + value: + type: + type: named + name: String StorageObject: description: container for object metadata. fields: @@ -1302,7 +1356,7 @@ definition: bucket: type: type: named - name: String + name: StorageBucketName cacheControl: type: type: nullable @@ -1342,7 +1396,7 @@ definition: clientId: type: type: named - name: String + name: StorageClientID contentDisposition: type: type: nullable @@ -1513,12 +1567,14 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue name: type: type: named - name: String + name: StorageStringFilter owner: type: type: nullable @@ -1535,8 +1591,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue rehydratePriority: type: type: nullable @@ -1619,8 +1677,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versionId: type: type: nullable @@ -1707,7 +1767,7 @@ definition: type: type: named name: StorageClientID - object: + name: type: type: named name: StorageStringFilter @@ -1792,7 +1852,7 @@ definition: retentionDuration: type: type: named - name: Duration + name: DurationString StorageOwner: description: name. fields: @@ -1921,6 +1981,13 @@ definition: underlying_type: type: named name: String + SuccessResponse: + description: represents a common successful response structure. + fields: + success: + type: + type: named + name: Boolean UpdateStorageBucketOptions: description: hold update options for the bucket. fields: @@ -1946,8 +2013,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versioningEnabled: type: type: nullable @@ -1967,8 +2036,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue retention: type: type: nullable @@ -1979,15 +2050,47 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versionId: type: type: nullable underlying_type: type: named name: String - collections: [] + collections: + - name: storageBuckets + description: List storage buckets + arguments: + after: + type: + type: nullable + underlying_type: + type: named + name: String + type: StorageBucket + uniqueness_constraints: {} + foreign_keys: {} + - name: storageObjects + description: List storage objects + arguments: + after: + type: + type: nullable + underlying_type: + type: named + name: String + hierarchy: + type: + type: nullable + underlying_type: + type: named + name: Boolean + type: StorageObject + uniqueness_constraints: {} + foreign_keys: {} functions: - name: downloadStorageObject description: returns a stream of the object data. Most of the common errors occur when reading the stream. @@ -2008,8 +2111,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue object: type: type: named @@ -2024,25 +2129,19 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versionId: type: type: nullable underlying_type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: - type: nullable - underlying_type: - type: named - name: Bytes + type: named + name: DownloadStorageObjectResponse - name: downloadStorageObjectText description: returns the object content in plain text. Use this function only if you know exactly the file as an text file. arguments: @@ -2062,8 +2161,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue object: type: type: named @@ -2078,25 +2179,19 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versionId: type: type: nullable underlying_type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: - type: nullable - underlying_type: - type: named - name: String + type: named + name: DownloadStorageObjectTextResponse - name: storageBucket description: gets a bucket by name. arguments: @@ -2117,26 +2212,8 @@ definition: underlying_type: type: named name: StorageBucket - - name: storageBucketExists - description: checks if a bucket exists. - arguments: - bucket: - type: - type: nullable - underlying_type: - type: named - name: String - clientId: - type: - type: nullable - underlying_type: - type: named - name: StorageClientID - result_type: - type: named - name: Boolean - - name: storageBuckets - description: list all buckets. + - name: storageBucketConnections + description: list all buckets using the relay style. arguments: after: type: @@ -2171,6 +2248,24 @@ definition: result_type: type: named name: StorageConnection_StorageBucket + - name: storageBucketExists + description: checks if a bucket exists. + arguments: + bucket: + type: + type: nullable + underlying_type: + type: named + name: String + clientId: + type: + type: nullable + underlying_type: + type: named + name: StorageClientID + result_type: + type: named + name: ExistsResponse - name: storageDeletedObjects description: list deleted objects in a bucket. arguments: @@ -2210,12 +2305,6 @@ definition: underlying_type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: named name: StorageObjectListResults @@ -2264,8 +2353,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue object: type: type: named @@ -2280,27 +2371,23 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versionId: type: type: nullable underlying_type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: nullable underlying_type: type: named name: StorageObject - - name: storageObjects - description: lists objects in a bucket. + - name: storageObjectConnections + description: lists objects in a bucket using the relay style. arguments: after: type: @@ -2367,7 +2454,7 @@ definition: type: nullable underlying_type: type: named - name: Duration + name: DurationString object: type: type: named @@ -2376,14 +2463,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter + type: array + element_type: + type: named + name: StorageKeyValue result_type: type: nullable underlying_type: @@ -2409,17 +2492,11 @@ definition: type: nullable underlying_type: type: named - name: Duration + name: DurationString object: type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: nullable underlying_type: @@ -2497,11 +2574,13 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue result_type: type: named - name: Boolean + name: SuccessResponse - name: removeIncompleteStorageUpload description: removes a partially uploaded object. arguments: @@ -2523,7 +2602,7 @@ definition: name: String result_type: type: named - name: Boolean + name: SuccessResponse - name: removeStorageBucket description: removes a bucket, bucket should be empty to be successfully removed. arguments: @@ -2541,7 +2620,7 @@ definition: name: StorageClientID result_type: type: named - name: Boolean + name: SuccessResponse - name: removeStorageObject description: removes an object with some specified options. arguments: @@ -2585,15 +2664,9 @@ definition: underlying_type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: named - name: Boolean + name: SuccessResponse - name: removeStorageObjects description: remove a list of objects obtained from an input channel. The call sends a delete request to the server up to 1000 objects at a time. The errors observed are sent over the error channel. arguments: @@ -2639,12 +2712,6 @@ definition: underlying_type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: array element_type: @@ -2669,15 +2736,9 @@ definition: type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: named - name: Boolean + name: SuccessResponse - name: updateStorageBucket description: updates the bucket's configuration. arguments: @@ -2715,8 +2776,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versioningEnabled: type: type: nullable @@ -2725,7 +2788,7 @@ definition: name: Boolean result_type: type: named - name: Boolean + name: SuccessResponse - name: updateStorageObject description: updates the object's configuration. arguments: @@ -2751,8 +2814,10 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue object: type: type: named @@ -2767,23 +2832,19 @@ definition: type: type: nullable underlying_type: - type: named - name: JSON + type: array + element_type: + type: named + name: StorageKeyValue versionId: type: type: nullable underlying_type: type: named name: String - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: named - name: Boolean + name: SuccessResponse - name: uploadStorageObject description: uploads object that are less than 128MiB in a single PUT operation. For objects that are greater than 128MiB in size, PutObject seamlessly uploads the object as parts of 128MiB or more depending on the actual file size. The max upload size for an object is 5TB. arguments: @@ -2813,12 +2874,6 @@ definition: underlying_type: type: named name: PutStorageObjectOptions - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: named name: StorageUploadInfo @@ -2851,12 +2906,6 @@ definition: underlying_type: type: named name: PutStorageObjectOptions - where: - type: - type: nullable - underlying_type: - type: predicate - object_type_name: StorageObjectFilter result_type: type: named name: StorageUploadInfo diff --git a/tests/engine/globals/metadata/graphql-config.hml b/tests/engine/globals/metadata/graphql-config.hml index 6dc707f..6ace692 100644 --- a/tests/engine/globals/metadata/graphql-config.hml +++ b/tests/engine/globals/metadata/graphql-config.hml @@ -15,7 +15,16 @@ definition: or: _or not: _not isNull: _is_null - orderByInput: null + orderByInput: + fieldName: order_by + enumDirectionValues: + asc: Asc + desc: Desc + enumTypeNames: + - directions: + - Asc + - Desc + typeName: OrderBy aggregate: filterInputFieldName: filter_input countFieldName: _count