diff --git a/clients/algoliasearch-client-go/.golangci.yml b/clients/algoliasearch-client-go/.golangci.yml index bc7475a054..26b09fa902 100644 --- a/clients/algoliasearch-client-go/.golangci.yml +++ b/clients/algoliasearch-client-go/.golangci.yml @@ -57,6 +57,7 @@ linters: - canonicalheader - mnd - perfsprint + - containedctx # Deprecated - execinquery diff --git a/clients/algoliasearch-client-go/algolia/errs/wait_err.go b/clients/algoliasearch-client-go/algolia/errs/wait_err.go index 5d56267fc7..d825297bf7 100644 --- a/clients/algoliasearch-client-go/algolia/errs/wait_err.go +++ b/clients/algoliasearch-client-go/algolia/errs/wait_err.go @@ -10,18 +10,18 @@ func NewWaitError(msg string) *WaitError { } } -func (e *WaitError) Error() string { +func (e WaitError) Error() string { return e.msg } type WaitKeyUpdateError struct{} -func (e *WaitKeyUpdateError) Error() string { +func (e WaitKeyUpdateError) Error() string { return "`apiKey` is required when waiting for an `update` operation." } type WaitKeyOperationError struct{} -func (e *WaitKeyOperationError) Error() string { +func (e WaitKeyOperationError) Error() string { return "`operation` must be one of `add`, `update` or `delete`." } diff --git a/clients/algoliasearch-client-go/algolia/utils/options.go b/clients/algoliasearch-client-go/algolia/utils/options.go new file mode 100644 index 0000000000..16e4882c8e --- /dev/null +++ b/clients/algoliasearch-client-go/algolia/utils/options.go @@ -0,0 +1,157 @@ +package utils + +import ( + "context" + "net/url" + "time" +) + +type Options struct { + // -- Request options for API calls + Context context.Context + QueryParams url.Values + HeaderParams map[string]string + + // -- ChunkedBatch options + WaitForTasks bool + BatchSize int + + // -- Iterable options + MaxRetries int + Timeout func(int) time.Duration + Aggregator func(any, error) + IterableError *IterableError +} + +// --------- Request options for API calls --------- + +type RequestOption interface { + Apply(*Options) +} + +type requestOption func(*Options) + +func (r requestOption) Apply(o *Options) { + r(o) +} + +func WithContext(ctx context.Context) requestOption { + return requestOption(func(o *Options) { + o.Context = ctx + }) +} + +func WithHeaderParam(key, value string) requestOption { + return requestOption(func(o *Options) { + o.HeaderParams[key] = value + }) +} + +func WithQueryParam(key, value string) requestOption { + return requestOption(func(o *Options) { + o.QueryParams.Add(key, value) + }) +} + +// --------- ChunkedBatch options --------- + +type ChunkedBatchOption interface { + RequestOption + chunkedBatch() +} + +type chunkedBatchOption func(*Options) + +var ( + _ ChunkedBatchOption = (*chunkedBatchOption)(nil) + _ ChunkedBatchOption = (*requestOption)(nil) +) + +func (c chunkedBatchOption) Apply(o *Options) { + c(o) +} + +func (c chunkedBatchOption) chunkedBatch() {} + +func (r requestOption) chunkedBatch() {} + +func WithWaitForTasks(waitForTasks bool) chunkedBatchOption { + return chunkedBatchOption(func(o *Options) { + o.WaitForTasks = waitForTasks + }) +} + +func WithBatchSize(batchSize int) chunkedBatchOption { + return chunkedBatchOption(func(o *Options) { + o.BatchSize = batchSize + }) +} + +// --------- Iterable options ---------. +type IterableOption interface { + RequestOption + iterable() +} + +type iterableOption func(*Options) + +var ( + _ IterableOption = (*iterableOption)(nil) + _ IterableOption = (*requestOption)(nil) +) + +func (i iterableOption) Apply(o *Options) { + i(o) +} + +func (r requestOption) iterable() {} + +func (i iterableOption) iterable() {} + +func WithMaxRetries(maxRetries int) iterableOption { + return iterableOption(func(o *Options) { + o.MaxRetries = maxRetries + }) +} + +func WithTimeout(timeout func(int) time.Duration) iterableOption { + return iterableOption(func(o *Options) { + o.Timeout = timeout + }) +} + +func WithAggregator(aggregator func(any, error)) iterableOption { + return iterableOption(func(o *Options) { + o.Aggregator = aggregator + }) +} + +func WithIterableError(iterableError *IterableError) iterableOption { + return iterableOption(func(o *Options) { + o.IterableError = iterableError + }) +} + +// --------- Helper to convert options --------- + +func ToRequestOptions[T RequestOption](opts []T) []RequestOption { + requestOpts := make([]RequestOption, 0, len(opts)) + + for _, opt := range opts { + requestOpts = append(requestOpts, opt) + } + + return requestOpts +} + +func ToIterableOptions(opts []ChunkedBatchOption) []IterableOption { + iterableOpts := make([]IterableOption, 0, len(opts)) + + for _, opt := range opts { + if opt, ok := opt.(IterableOption); ok { + iterableOpts = append(iterableOpts, opt) + } + } + + return iterableOpts +} diff --git a/clients/algoliasearch-client-go/algolia/utils/utils.go b/clients/algoliasearch-client-go/algolia/utils/utils.go index e5856e48eb..fdd5cee620 100644 --- a/clients/algoliasearch-client-go/algolia/utils/utils.go +++ b/clients/algoliasearch-client-go/algolia/utils/utils.go @@ -3,6 +3,7 @@ package utils import ( "encoding/json" + "fmt" "reflect" "time" @@ -65,54 +66,32 @@ func IsNilOrEmpty(i any) bool { } } -type IterableOptions[T any] struct { - Aggregator func(*T, error) - Timeout func() time.Duration - IterableErr *IterableError[T] +type IterableError struct { + Validate func(any, error) bool + Message func(any, error) string } -type IterableOption[T any] func(*IterableOptions[T]) - -func WithAggregator[T any](aggregator func(*T, error)) IterableOption[T] { - return func(options *IterableOptions[T]) { - options.Aggregator = aggregator - } -} - -func WithTimeout[T any](timeout func() time.Duration) IterableOption[T] { - return func(options *IterableOptions[T]) { - options.Timeout = timeout - } -} - -func WithIterableError[T any](iterableErr *IterableError[T]) IterableOption[T] { - return func(options *IterableOptions[T]) { - options.IterableErr = iterableErr - } -} - -type IterableError[T any] struct { - Validate func(*T, error) bool - Message func(*T, error) string -} - -func CreateIterable[T any](execute func(*T, error) (*T, error), validate func(*T, error) bool, opts ...IterableOption[T]) (*T, error) { - options := IterableOptions[T]{ - Aggregator: nil, - Timeout: func() time.Duration { +func CreateIterable[T any](execute func(*T, error) (*T, error), validate func(*T, error) bool, opts ...IterableOption) (*T, error) { + options := Options{ + MaxRetries: 50, + Timeout: func(_ int) time.Duration { return 1 * time.Second }, - IterableErr: nil, } for _, opt := range opts { - opt(&options) + opt.Apply(&options) } + var executor func(*T, error) (*T, error) + retryCount := 0 + executor = func(previousResponse *T, previousError error) (*T, error) { response, responseErr := execute(previousResponse, previousError) + retryCount++ + if options.Aggregator != nil { options.Aggregator(response, responseErr) } @@ -121,15 +100,21 @@ func CreateIterable[T any](execute func(*T, error) (*T, error), validate func(*T return response, responseErr } - if options.IterableErr != nil && options.IterableErr.Validate(response, responseErr) { - if options.IterableErr.Message != nil { - return nil, errs.NewWaitError(options.IterableErr.Message(response, responseErr)) + if retryCount >= options.MaxRetries { + return nil, errs.NewWaitError(fmt.Sprintf("The maximum number of retries exceeded. (%d/%d)", retryCount, options.MaxRetries)) + } + + if options.IterableError != nil && options.IterableError.Validate(response, responseErr) { + if options.IterableError.Message != nil { + return nil, errs.NewWaitError(options.IterableError.Message(response, responseErr)) } return nil, errs.NewWaitError("an error occurred") } - time.Sleep(options.Timeout()) + fmt.Println("Sleeping for", options.Timeout(retryCount)) + + time.Sleep(options.Timeout(retryCount)) return executor(response, responseErr) } diff --git a/playground/go/ingestion.go b/playground/go/ingestion.go index 778d90e2ad..09058b72af 100644 --- a/playground/go/ingestion.go +++ b/playground/go/ingestion.go @@ -16,7 +16,7 @@ func testIngestion(appID, apiKey string) int { // another example to generate payload for a request. createAuthenticationResponse, err := ingestionClient.CreateAuthentication(ingestionClient.NewApiCreateAuthenticationRequest( &ingestion.AuthenticationCreate{ - Type: ingestion.AUTHENTICATIONTYPE_BASIC, + Type: ingestion.AUTHENTICATION_TYPE_BASIC, Name: fmt.Sprintf("my-authentication-%d", time.Now().Unix()), Input: ingestion.AuthInput{ AuthBasic: &ingestion.AuthBasic{ diff --git a/playground/go/insights.go b/playground/go/insights.go index fe3b9d4676..6dcebd25bb 100644 --- a/playground/go/insights.go +++ b/playground/go/insights.go @@ -14,7 +14,7 @@ func testInsights(appID, apiKey string) int { events := insights.NewInsightsEvents([]insights.EventsItems{ *insights.ClickedObjectIDsAsEventsItems(insights.NewClickedObjectIDs("myEvent", - insights.CLICKEVENT_CLICK, + insights.CLICK_EVENT_CLICK, "test_index", []string{"myObjectID"}, "myToken", diff --git a/playground/go/personalization.go b/playground/go/personalization.go index cb4a028025..74d805c3aa 100644 --- a/playground/go/personalization.go +++ b/playground/go/personalization.go @@ -6,6 +6,7 @@ import ( "time" "github.com/algolia/algoliasearch-client-go/v4/algolia/personalization" + "github.com/algolia/algoliasearch-client-go/v4/algolia/utils" ) func testPersonalization(appID, apiKey string) int { @@ -17,8 +18,9 @@ func testPersonalization(appID, apiKey string) int { defer cancel() // it will fail expectedly because of the very short timeout to showcase the context usage. - deleteUserProfileResponse, err := personalizationClient.DeleteUserProfileWithContext(ctx, + deleteUserProfileResponse, err := personalizationClient.DeleteUserProfile( personalizationClient.NewApiDeleteUserProfileRequest("userToken"), + utils.WithContext(ctx), ) if err != nil { fmt.Printf("request error with DeleteUserProfile: %v\n", err) diff --git a/playground/go/recommend.go b/playground/go/recommend.go index 241c2f9b9e..75d7a8c6bf 100644 --- a/playground/go/recommend.go +++ b/playground/go/recommend.go @@ -4,7 +4,6 @@ import ( "fmt" "github.com/algolia/algoliasearch-client-go/v4/algolia/recommend" - "github.com/algolia/algoliasearch-client-go/v4/algolia/utils" ) func testRecommend(appID, apiKey string) int { @@ -22,11 +21,11 @@ func testRecommend(appID, apiKey string) int { params := &recommend.GetRecommendationsParams{ Requests: []recommend.RecommendationsRequest{ { - RecommendationsQuery: &recommend.RecommendationsQuery{ - Model: recommend.RECOMMENDATIONMODELS_BOUGHT_TOGETHER, + BoughtTogetherQuery: &recommend.BoughtTogetherQuery{ + Model: recommend.FBT_MODEL_BOUGHT_TOGETHER, ObjectID: "test_query", IndexName: "test_index", - Threshold: utils.PtrInt32(0), + Threshold: 0, }, }, }, diff --git a/playground/go/search.go b/playground/go/search.go index f3c90b577e..a975e4caee 100644 --- a/playground/go/search.go +++ b/playground/go/search.go @@ -1,65 +1,66 @@ package main import ( - "fmt" + "context" "github.com/algolia/algoliasearch-client-go/v4/algolia/search" + "github.com/algolia/algoliasearch-client-go/v4/algolia/utils" ) func testSearch(appID, apiKey string) int { - indexName := getEnvWithDefault("SEARCH_INDEX", "test_index") + // indexName := getEnvWithDefault("SEARCH_INDEX", "test_index") searchClient, err := search.NewClient(appID, apiKey) if err != nil { panic(err) } - response, err := searchClient.AddOrUpdateObject( - searchClient.NewApiAddOrUpdateObjectRequest( - indexName, - "1", - map[string]any{ - "name": "Foo", - "age": 42, - "city": "Paris", - }, - ), - ) - if err != nil { - panic(err) - } + res, err := searchClient.WaitForApiKey(search.API_KEY_OPERATION_ADD, "test", &search.ApiKey{}, utils.WithContext(context.Background()), utils.WithMaxRetries(4)) + print(res) + print(err.Error()) - _, err = searchClient.WaitForTask( - indexName, - *response.TaskID, - nil, - nil, - nil, - ) - if err != nil { - panic(err) - } + /* + response, err := searchClient.AddOrUpdateObject( + searchClient.NewApiAddOrUpdateObjectRequest( + indexName, + "1", + map[string]any{ + "name": "Foo", + "age": 42, + "city": "Paris", + }, + ), + ) + if err != nil { + panic(err) + } + + _, err = searchClient.WaitForTask(indexName, *response.TaskID) + if err != nil { + panic(err) + } - searchResponse, err := searchClient.Search( - searchClient.NewApiSearchRequest( - search.NewSearchMethodParams( - []search.SearchQuery{ - *search.SearchForHitsAsSearchQuery( - search.NewSearchForHits( - indexName, - search.WithSearchForHitsQuery("foo"), + searchResponse, err := searchClient.Search( + searchClient.NewApiSearchRequest( + search.NewSearchMethodParams( + []search.SearchQuery{ + *search.SearchForHitsAsSearchQuery( + search.NewSearchForHits( + indexName, + search.WithSearchForHitsQuery("foo"), + ), ), - ), - }, + }, + ), ), - ), - ) - if err != nil { - panic(err) - } + ) + if err != nil { + panic(err) + } - for _, result := range searchResponse.Results { - fmt.Printf("Result: %v", result.SearchResponse) - } + for _, result := range searchResponse.Results { + fmt.Printf("Result: %v", result.SearchResponse) + } + */ return 0 } diff --git a/templates/go/api.mustache b/templates/go/api.mustache index 60dd30f9ba..f7cec9d11e 100644 --- a/templates/go/api.mustache +++ b/templates/go/api.mustache @@ -25,20 +25,6 @@ import ( "github.com/algolia/algoliasearch-client-go/v4/algolia/call" ) -type Option func(url.Values, map[string]string) - -func WithQueryParam(name string, val any) Option { - return func(queryParams url.Values, _ map[string]string) { - queryParams.Set(queryParameterToString(name), queryParameterToString(val)) - } -} - -func WithHeaderParam(name string, val any) Option { - return func(_ url.Values, headers map[string]string) { - headers[name] = parameterToString(val) - } -} - {{#operation}} {{#hasParams}} func (r *{{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request) UnmarshalJSON(b []byte) error { @@ -116,7 +102,6 @@ func (r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/s {{/vendorExtensions}} Request can be constructed by NewApi{{operationId}}Request with parameters below. - @param ctx context.Context - Context of the request {{#allParams}} @param {{paramName}} {{dataType}}{{#description}} - {{{.}}}{{/description}} {{/allParams}} @@ -129,18 +114,12 @@ func (r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/s Deprecated {{/isDeprecated}} */ -func (c *APIClient) {{nickname}}WithHTTPInfo(ctx context.Context, {{#hasParams}}r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request,{{/hasParams}} opts ...Option) (*http.Response, []byte, error) { - var ( - postBody any - ) - +func (c *APIClient) {{nickname}}WithHTTPInfo({{#hasParams}}r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request,{{/hasParams}} opts ...utils.RequestOption) (*http.Response, []byte, error) { {{#vendorExtensions}} requestPath := "{{{path}}}"{{#pathParams}} requestPath = strings.ReplaceAll(requestPath, {{=<% %>=}}"{<%baseName%>}"<%={{ }}=%>, {{#x-is-custom-request}}parameterToString(r.{{paramName}}){{/x-is-custom-request}}{{^x-is-custom-request}}url.PathEscape(parameterToString(r.{{paramName}})){{/x-is-custom-request}}){{/pathParams}} {{/vendorExtensions}} - headers := make(map[string]string) - queryParams := url.Values{} {{#allParams}} {{#required}} {{#isString}} @@ -193,11 +172,17 @@ func (c *APIClient) {{nickname}}WithHTTPInfo(ctx context.Context, {{#hasParams}} {{/required}} {{/allParams}} + options := utils.Options{ + Context: context.Background(), + QueryParams: url.Values{}, + HeaderParams: map[string]string{}, + } + {{#vendorExtensions.x-is-custom-request}} {{#queryParams}} {{^required}}if !utils.IsNilOrEmpty(r.{{paramName}}) { {{/required}} for k, v := range r.{{paramName}} { - queryParams.Set(k, queryParameterToString(v)) + options.QueryParams.Set(k, queryParameterToString(v)) } {{^required}} } {{/required}} {{/queryParams}} @@ -205,31 +190,33 @@ func (c *APIClient) {{nickname}}WithHTTPInfo(ctx context.Context, {{#hasParams}} {{^vendorExtensions.x-is-custom-request}} {{#queryParams}} {{#required}} - queryParams.Set("{{baseName}}", queryParameterToString({{^isFreeFormObject}}{{^isArray}}{{^isPrimitiveType}}{{^isEnumRef}}*{{/isEnumRef}}{{/isPrimitiveType}}{{/isArray}}{{/isFreeFormObject}}r.{{paramName}})) + options.QueryParams.Set("{{baseName}}", queryParameterToString({{^isFreeFormObject}}{{^isArray}}{{^isPrimitiveType}}{{^isEnumRef}}*{{/isEnumRef}}{{/isPrimitiveType}}{{/isArray}}{{/isFreeFormObject}}r.{{paramName}})) {{/required}} {{^required}} if !utils.IsNilOrEmpty(r.{{paramName}}) { - queryParams.Set("{{baseName}}", queryParameterToString({{^isFreeFormObject}}{{^isArray}}{{^isEnumRef}}*{{/isEnumRef}}{{/isArray}}{{/isFreeFormObject}}r.{{paramName}})) + options.QueryParams.Set("{{baseName}}", queryParameterToString({{^isFreeFormObject}}{{^isArray}}{{^isEnumRef}}*{{/isEnumRef}}{{/isArray}}{{/isFreeFormObject}}r.{{paramName}})) } {{/required}} {{/queryParams}} {{/vendorExtensions.x-is-custom-request}} {{#headerParams}} {{#required}} - headers["{{baseName}}"] = parameterToString({{^isFreeFormObject}}{{^isArray}}{{^isPrimitiveType}}{{^isEnumRef}}*{{/isEnumRef}}{{/isPrimitiveType}}{{/isArray}}{{/isFreeFormObject}}r.{{paramName}}) + options.HeaderParams["{{baseName}}"] = parameterToString({{^isFreeFormObject}}{{^isArray}}{{^isPrimitiveType}}{{^isEnumRef}}*{{/isEnumRef}}{{/isPrimitiveType}}{{/isArray}}{{/isFreeFormObject}}r.{{paramName}}) {{/required}} {{^required}} if !utils.IsNilOrEmpty(r.{{paramName}}) { - headers["{{baseName}}"] = parameterToString({{^isFreeFormObject}}{{^isArray}}{{^isEnumRef}}*{{/isEnumRef}}{{/isArray}}{{/isFreeFormObject}}r.{{paramName}}) + options.HeaderParams["{{baseName}}"] = parameterToString({{^isFreeFormObject}}{{^isArray}}{{^isEnumRef}}*{{/isEnumRef}}{{/isArray}}{{/isFreeFormObject}}r.{{paramName}}) } {{/required}} {{/headerParams}} // optional params if any for _, opt := range opts { - opt(queryParams, headers) + opt.Apply(&options) } + var postBody any + {{#bodyParams}} // body params{{^required}} if utils.IsNilOrEmpty(r.{{paramName}}) { @@ -238,7 +225,7 @@ func (c *APIClient) {{nickname}}WithHTTPInfo(ctx context.Context, {{#hasParams}} postBody = r.{{paramName}}{{^required}} } {{/required}} {{/bodyParams}} - req, err := c.prepareRequest(ctx, requestPath, http.Method{{httpMethod}}, postBody, headers, queryParams) + req, err := c.prepareRequest(options.Context, requestPath, http.Method{{httpMethod}}, postBody, options.HeaderParams, options.QueryParams) if err != nil { return nil, nil, err } @@ -246,22 +233,15 @@ func (c *APIClient) {{nickname}}WithHTTPInfo(ctx context.Context, {{#hasParams}} return c.callAPI(req, {{#vendorExtensions}}{{#x-use-read-transporter}}true{{/x-use-read-transporter}}{{^x-use-read-transporter}}false{{/x-use-read-transporter}}{{/vendorExtensions}}) } -/* -{{operationId}} wraps {{nickname}}WithContext using context.Background. -{{> operation_description}} -func (c *APIClient) {{nickname}}({{#hasParams}}r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request,{{/hasParams}} opts ...Option) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}error) { - return c.{{nickname}}WithContext(context.Background(), {{#hasParams}}r,{{/hasParams}} opts...) -} - /* {{operationId}} casts the HTTP response body to a defined struct. {{> operation_description}} -func (c *APIClient) {{nickname}}WithContext(ctx context.Context, {{#hasParams}}r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request,{{/hasParams}} opts ...Option) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}error) { +func (c *APIClient) {{nickname}}({{#hasParams}}r {{#structPrefix}}{{&classname}}{{/structPrefix}}{{^structPrefix}}Api{{/structPrefix}}{{operationId}}Request,{{/hasParams}} opts ...utils.RequestOption) ({{#returnType}}{{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}}, {{/returnType}}error) { {{#returnType}} var returnValue {{^isArray}}{{^returnTypeIsPrimitive}}*{{/returnTypeIsPrimitive}}{{/isArray}}{{{.}}} {{/returnType}} - res, resBody, err := c.{{nickname}}WithHTTPInfo(ctx{{#hasParams}}, r{{/hasParams}}, opts...) + res, resBody, err := c.{{nickname}}WithHTTPInfo({{#hasParams}}r, {{/hasParams}}opts...) if err != nil { return {{#returnType}}returnValue, {{/returnType}}err } diff --git a/templates/go/search_helpers.mustache b/templates/go/search_helpers.mustache index d89cc4a5bd..3cafd5de75 100644 --- a/templates/go/search_helpers.mustache +++ b/templates/go/search_helpers.mustache @@ -2,14 +2,13 @@ SearchForHits calls the `search` method but with certainty that we will only request Algolia records (hits) and not facets. Disclaimer: We don't assert that the parameters you pass to this method only contains `hits` requests to prevent impacting search performances, this helper is purely for typing purposes. - @param ctx context.Context - The context that will be drilled down to the actual request. @param r ApiSearchRequest - Body of the `search` operation. - @param opts ...Option - Optional parameters for the request. + @param opts ...utils.RequestOption - Optional parameters for the request. @return []SearchResponse - List of hits. @return error - Error if any. */ -func (c *APIClient) SearchForHits(ctx context.Context, r ApiSearchRequest, opts ...Option) ([]SearchResponse, error) { - res, err := c.SearchWithContext(ctx, r, opts...) +func (c *APIClient) SearchForHits(r ApiSearchRequest, opts ...utils.RequestOption) ([]SearchResponse, error) { + res, err := c.Search(r, opts...) if err != nil { return nil, err } @@ -29,14 +28,13 @@ func (c *APIClient) SearchForHits(ctx context.Context, r ApiSearchRequest, opts SearchForFacets calls the `search` method but with certainty that we will only request Algolia facets and not records (hits). Disclaimer: We don't assert that the parameters you pass to this method only contains `facets` requests to prevent impacting search performances, this helper is purely for typing purposes. - @param ctx context.Context - The context that will be drilled down to the actual request. @param r ApiSearchRequest - Body of the `search` operation. - @param opts ...Option - Optional parameters for the request. + @param opts ...utils.RequestOption - Optional parameters for the request. @return []SearchForFacetValuesResponse - List of facet hits. @return error - Error if any. */ -func (c *APIClient) SearchForFacets(ctx context.Context, r ApiSearchRequest, opts ...Option) ([]SearchForFacetValuesResponse, error) { - res, err := c.SearchWithContext(ctx, r, opts...) +func (c *APIClient) SearchForFacets(r ApiSearchRequest, opts ...utils.RequestOption) ([]SearchForFacetValuesResponse, error) { + res, err := c.Search(r, opts...) if err != nil { return nil, err } @@ -54,73 +52,28 @@ func (c *APIClient) SearchForFacets(ctx context.Context, r ApiSearchRequest, opt /* WaitForTask waits for a task to be published. -Wraps WaitForTaskWithContext with context.Background(). It returns the task response if the operation was successful. It returns an error if the operation failed. - @param indexName string - Index name. - @param taskID int64 - Task ID. - @param maxRetries *float64 - Maximum number of retries. - @param timeout func(float64) time.Duration - Timeout function. - @param opts ...Option - Optional parameters for the request. - @return *GetTaskResponse - Task response. - @return error - Error if any. -*/ -func (c *APIClient) WaitForTask( - indexName string, - taskID int64, - maxRetries *float64, - timeout func(float64) time.Duration, - opts ...Option, -) (*GetTaskResponse, error) { - return c.WaitForTaskWithContext( - context.Background(), - indexName, - taskID, - maxRetries, - timeout, - opts..., - ) -} - -/* -WaitForTaskWithContext waits for a task to be published. -It returns the task response if the operation was successful. -It returns an error if the operation failed. - - @param ctx context.Context - The context that will be drilled down to the actual request. @param indexName string - Index name. @param taskID int64 - Task ID. - @param maxRetries *float64 - Maximum number of retries. - @param timeout func(float64) time.Duration - Timeout function. - @param opts ...Option - Optional parameters for the request. + @param opts ...utils.IterableOption - Optional parameters for the request. @return *GetTaskResponse - Task response. @return error - Error if any. */ -func (c *APIClient) WaitForTaskWithContext( - ctx context.Context, +func (c *APIClient) WaitForTask( indexName string, taskID int64, - maxRetries *float64, - timeout func(float64) time.Duration, - opts ...Option, + opts ...utils.IterableOption, ) (*GetTaskResponse, error) { - retryCount := float64(0) - - if maxRetries == nil { - maxRetries = new(float64) - *maxRetries = 50 - } - - if timeout == nil { - timeout = func(count float64) time.Duration { - return time.Duration(min(count*0.2, 5)) * time.Second - } - } + // provide a defalut timeout function + opts = append([]utils.IterableOption{utils.WithTimeout(func(count int) time.Duration { + return time.Duration(min(200*count, 5000)) * time.Millisecond + })}, opts...) return utils.CreateIterable( //nolint:wrapcheck func(*GetTaskResponse, error) (*GetTaskResponse, error) { - return c.GetTaskWithContext(ctx, c.NewApiGetTaskRequest(indexName, taskID), opts...) + return c.GetTask(c.NewApiGetTaskRequest(indexName, taskID), utils.ToRequestOptions(opts)...) }, func(response *GetTaskResponse, err error) bool { if err != nil || response == nil { @@ -129,87 +82,32 @@ func (c *APIClient) WaitForTaskWithContext( return response.Status == TASK_STATUS_PUBLISHED }, - func(*GetTaskResponse, error) { - retryCount++ - }, - func() time.Duration { - return timeout(retryCount) - }, - &utils.IterableError[GetTaskResponse]{ - Validate: func(*GetTaskResponse, error) bool { - return retryCount >= *maxRetries - }, - Message: func(*GetTaskResponse, error) string { - return fmt.Sprintf("The maximum number of retries exceeded. (%f/%f)", retryCount, *maxRetries) - }, - }, + opts..., ) } /* WaitForAppTask waits for an application-level task to be published. -Wraps WaitForAppTask with context.Background(). It returns the task response if the operation was successful. It returns an error if the operation failed. @param taskID int64 - Task ID. - @param maxRetries *float64 - Maximum number of retries. - @param timeout func(float64) time.Duration - Timeout function. - @param opts ...Option - Optional parameters for the request. + @param opts ...utils.IterableOption - Optional parameters for the request. @return *GetTaskResponse - Task response. @return error - Error if any. */ func (c *APIClient) WaitForAppTask( taskID int64, - maxRetries *float64, - timeout func(float64) time.Duration, - opts ...Option, -) (*GetTaskResponse, error) { - return c.WaitForAppTaskWithContext( - context.Background(), - taskID, - maxRetries, - timeout, - opts..., - ) -} - -/* -WaitForAppTaskWithContext waits for an application-level task to be published. -It returns the task response if the operation was successful. -It returns an error if the operation failed. - - @param ctx context.Context - The context that will be drilled down to the actual request. - @param taskID int64 - Task ID. - @param maxRetries *float64 - Maximum number of retries. - @param timeout func(float64) time.Duration - Timeout function. - @param opts ...Option - Optional parameters for the request. - @return *GetTaskResponse - Task response. - @return error - Error if any. -*/ -func (c *APIClient) WaitForAppTaskWithContext( - ctx context.Context, - taskID int64, - maxRetries *float64, - timeout func(float64) time.Duration, - opts ...Option, + opts ...utils.IterableOption, ) (*GetTaskResponse, error) { - retryCount := float64(0) - - if maxRetries == nil { - maxRetries = new(float64) - *maxRetries = 50 - } - - if timeout == nil { - timeout = func(count float64) time.Duration { - return time.Duration(min(count*0.2, 5)) * time.Second - } - } + // provide a defalut timeout function + opts = append([]utils.IterableOption{utils.WithTimeout(func(count int) time.Duration { + return time.Duration(min(200*count, 5000)) * time.Millisecond + })}, opts...) return utils.CreateIterable( //nolint:wrapcheck func(*GetTaskResponse, error) (*GetTaskResponse, error) { - return c.GetAppTaskWithContext(ctx, c.NewApiGetAppTaskRequest(taskID), opts...) + return c.GetAppTask(c.NewApiGetAppTaskRequest(taskID), utils.ToRequestOptions(opts)...) }, func(response *GetTaskResponse, err error) bool { if err != nil || response == nil { @@ -218,104 +116,12 @@ func (c *APIClient) WaitForAppTaskWithContext( return response.Status == TASK_STATUS_PUBLISHED }, - func(*GetTaskResponse, error) { - retryCount++ - }, - func() time.Duration { - return timeout(retryCount) - }, - &utils.IterableError[GetTaskResponse]{ - Validate: func(*GetTaskResponse, error) bool { - return retryCount >= *maxRetries - }, - Message: func(*GetTaskResponse, error) string { - return fmt.Sprintf("The maximum number of retries exceeded. (%f/%f)", retryCount, *maxRetries) - }, - }, - ) -} - -/* -WaitForApiKey waits for an API key to be created, deleted or updated. -It returns the API key response if the operation was successful. -It returns an error if the operation failed. - -The operation can be one of the following: - - "add": wait for the API key to be created - - "delete": wait for the API key to be deleted - - "update": wait for the API key to be updated - -If the operation is "update", the apiKey parameter must be set. -If the operation is "delete" or "add", the apiKey parameter is not used. - - @param operation ApiKeyOperation - Operation type - add, delete or update. - @param key string - API key. - @param apiKey *ApiKey - API key structure - required for update operation. - @param opts ...Option - Optional parameters for the request. - @return *GetApiKeyResponse - API key response. - @return error - Error if any. -*/ -func (c *APIClient) WaitForApiKey( - operation ApiKeyOperation, - key string, - apiKey *ApiKey, - opts ...Option, -) (*GetApiKeyResponse, error) { - return c.WaitForApiKeyWithContext( - context.Background(), - operation, - key, - apiKey, - nil, - nil, opts..., ) } /* WaitForApiKey waits for an API key to be created, deleted or updated. -Wraps WaitForApiKeyWithContext with context.Background(). -It returns the API key response if the operation was successful. -It returns an error if the operation failed. - -The operation can be one of the following: - - "add": wait for the API key to be created - - "delete": wait for the API key to be deleted - - "update": wait for the API key to be updated - -If the operation is "update", the apiKey parameter must be set. -If the operation is "delete" or "add", the apiKey parameter is not used. - - @param operation ApiKeyOperation - Operation type - add, delete or update. - @param key string - API key. - @param apiKey *ApiKey - API key structure - required for update operation. - @param maxRetries *float64 - Maximum number of retries. - @param timeout func(float64) time.Duration - Timeout function. - @param opts ...Option - Optional parameters for the request. - @return *GetApiKeyResponse - API key response. - @return error - Error if any. -*/ -func (c *APIClient) WaitForApiKeyWithOptions( - operation ApiKeyOperation, - key string, - apiKey *ApiKey, - maxRetries *float64, - timeout func(float64) time.Duration, - opts ...Option, -) (*GetApiKeyResponse, error) { - return c.WaitForApiKeyWithContext( - context.Background(), - operation, - key, - apiKey, - maxRetries, - timeout, - opts..., - ) -} - -/* -WaitForApiKeyWithContext waits for an API key to be created, deleted or updated. It returns the API key response if the operation was successful. It returns an error if the operation failed. @@ -327,41 +133,27 @@ The operation can be one of the following: If the operation is "update", the apiKey parameter must be set. If the operation is "delete" or "add", the apiKey parameter is not used. - @param ctx context.Context - The context that will be drilled down to the actual request. @param operation ApiKeyOperation - Operation type - add, delete or update. @param key string - API key. @param apiKey *ApiKey - API key structure - required for update operation. - @param maxRetries *float64 - Maximum number of retries. - @param timeout func(float64) time.Duration - Timeout function. - @param opts ...Option - Optional parameters for the request. + @param opts ...utils.IterableOption - Optional parameters for the request. @return *GetApiKeyResponse - API key response. @return error - Error if any. */ -func (c *APIClient) WaitForApiKeyWithContext( - ctx context.Context, +func (c *APIClient) WaitForApiKey( operation ApiKeyOperation, key string, apiKey *ApiKey, - maxRetries *float64, - timeout func(float64) time.Duration, - opts ...Option, + opts ...utils.IterableOption, ) (*GetApiKeyResponse, error) { if operation != API_KEY_OPERATION_ADD && operation != API_KEY_OPERATION_DELETE && operation != API_KEY_OPERATION_UPDATE { return nil, &errs.WaitKeyOperationError{} } - retryCount := float64(0) - - if maxRetries == nil { - maxRetries = new(float64) - *maxRetries = 50 - } - - if timeout == nil { - timeout = func(count float64) time.Duration { - return time.Duration(min(count*0.2, 5)) * time.Second - } - } + // provide a defalut timeout function + opts = append([]utils.IterableOption{utils.WithTimeout(func(count int) time.Duration { + return time.Duration(min(200*count, 5000)) * time.Millisecond + })}, opts...) var validateFunc func(*GetApiKeyResponse, error) bool @@ -440,146 +232,64 @@ func (c *APIClient) WaitForApiKeyWithContext( return utils.CreateIterable( //nolint:wrapcheck func(*GetApiKeyResponse, error) (*GetApiKeyResponse, error) { - return c.GetApiKeyWithContext(ctx, c.NewApiGetApiKeyRequest(key), opts...) + return c.GetApiKey(c.NewApiGetApiKeyRequest(key), utils.ToRequestOptions(opts)...) }, validateFunc, - func(*GetApiKeyResponse, error) { - retryCount += 1 - }, - func() time.Duration { - return timeout(retryCount) - }, - &utils.IterableError[GetApiKeyResponse]{ - Validate: func(*GetApiKeyResponse, error) bool { - return retryCount >= *maxRetries - }, - Message: func(*GetApiKeyResponse, error) string { - return fmt.Sprintf("The maximum number of retries exceeded. (%f/%f)", retryCount, *maxRetries) - }, - }, + opts..., ) } /* BrowseObjects allows to aggregate all the hits returned by the API calls. -Wraps BrowseObjectsWithContext using context.Background. - - @param indexName string - Index name. - @param browseParams BrowseParamsObject - Browse parameters. - @param validate func(*BrowseResponse, error) bool - Validator function. - @param aggregator func(*BrowseResponse) - Aggregator function. - @param opts ...Option - Optional parameters for the request. - @return *BrowseResponse - Browse response. - @return error - Error if any. -*/ -func (c *APIClient) BrowseObjects( - indexName string, - browseParams BrowseParamsObject, - validate func(*BrowseResponse, error) bool, - aggregator func(*BrowseResponse, error), - opts ...Option, -) (*BrowseResponse, error) { - return c.BrowseObjectsWithContext(context.Background(), indexName, browseParams, validate, aggregator, opts...) -} - -/* -BrowseObjectsWithContext allows to aggregate all the hits returned by the API calls. - @param ctx context.Context - The context that will be drilled down to the actual request. @param indexName string - Index name. @param browseParams BrowseParamsObject - Browse parameters. - @param validate func(*BrowseResponse, error) bool - Validator function. - @param aggregator func(*BrowseResponse) - Aggregator function. - @param opts ...Option - Optional parameters for the request. + @param opts ...utils.IterableOption - Optional parameters for the request. @return *BrowseResponse - Browse response. @return error - Error if any. */ -func (c *APIClient) BrowseObjectsWithContext( - ctx context.Context, +func (c *APIClient) BrowseObjects( indexName string, browseParams BrowseParamsObject, - validate func(*BrowseResponse, error) bool, - aggregator func(*BrowseResponse, error), - opts ...Option, + opts ...utils.IterableOption, ) (*BrowseResponse, error) { - if validate == nil { - validate = func(response *BrowseResponse, responseErr error) bool { - return responseErr != nil || response != nil && response.Cursor == nil - } - } - return utils.CreateIterable( //nolint:wrapcheck func(previousResponse *BrowseResponse, previousErr error) (*BrowseResponse, error) { if previousResponse != nil { browseParams.Cursor = previousResponse.Cursor } - return c.BrowseWithContext( - ctx, + return c.Browse( c.NewApiBrowseRequest(indexName).WithBrowseParams(BrowseParamsObjectAsBrowseParams(&browseParams)), - opts..., + utils.ToRequestOptions(opts)..., ) }, - validate, - aggregator, - nil, - nil, + func(response *BrowseResponse, responseErr error) bool { + return responseErr != nil || response != nil && response.Cursor == nil + }, + opts..., ) } /* BrowseRules allows to aggregate all the rules returned by the API calls. -Wraps BrowseRulesWithContext using context.Background. @param indexName string - Index name. @param searchRulesParams SearchRulesParams - Search rules parameters. - @param validate func(*SearchRulesResponse, error) bool - Validator function. - @param aggregator func(*SearchRulesResponse) - Aggregator function. - @param opts ...Option - Optional parameters for the request. + @param opts ...utils.IterableOption - Optional parameters for the request. @return *SearchRulesResponse - Search rules response. @return error - Error if any. */ func (c *APIClient) BrowseRules( indexName string, searchRulesParams SearchRulesParams, - validate func(*SearchRulesResponse, error) bool, - aggregator func(*SearchRulesResponse, error), - opts ...Option, -) (*SearchRulesResponse, error) { - return c.BrowseRulesWithContext(context.Background(), indexName, searchRulesParams, validate, aggregator, opts...) -} - -/* -BrowseRulesWithContext allows to aggregate all the rules returned by the API calls. - - @param ctx context.Context - The context that will be drilled down to the actual request. - @param indexName string - Index name. - @param searchRulesParams SearchRulesParams - Search rules parameters. - @param validate func(*SearchRulesResponse, error) bool - Validator function. - @param aggregator func(*SearchRulesResponse) - Aggregator function. - @param opts ...Option - Optional parameters for the request. - @return *SearchRulesResponse - Search rules response. - @return error - Error if any. -*/ -func (c *APIClient) BrowseRulesWithContext( - ctx context.Context, - indexName string, - searchRulesParams SearchRulesParams, - validate func(*SearchRulesResponse, error) bool, - aggregator func(*SearchRulesResponse, error), - opts ...Option, + opts ...utils.IterableOption, ) (*SearchRulesResponse, error) { hitsPerPage := int32(1000) if searchRulesParams.HitsPerPage != nil { hitsPerPage = *searchRulesParams.HitsPerPage } - if validate == nil { - validate = func(response *SearchRulesResponse, responseErr error) bool { - return responseErr != nil || (response != nil && response.NbHits < hitsPerPage) - } - } - return utils.CreateIterable( //nolint:wrapcheck func(previousResponse *SearchRulesResponse, previousErr error) (*SearchRulesResponse, error) { searchRulesParams.HitsPerPage = &hitsPerPage @@ -592,60 +302,31 @@ func (c *APIClient) BrowseRulesWithContext( searchRulesParams.Page = utils.ToPtr(int32(0)) } - return c.SearchRulesWithContext( - ctx, + return c.SearchRules( c.NewApiSearchRulesRequest(indexName).WithSearchRulesParams(&searchRulesParams), - opts..., + utils.ToRequestOptions(opts)..., ) }, - validate, - aggregator, - nil, - nil, + func(response *SearchRulesResponse, responseErr error) bool { + return responseErr != nil || (response != nil && response.NbHits < hitsPerPage) + }, + opts..., ) } /* BrowseSynonyms allows to aggregate all the synonyms returned by the API calls. -Wraps BrowseSynonymsWithContext using context.Background. @param indexName string - Index name. @param searchSynonymsParams SearchSynonymsParams - Search synonyms parameters. - @param validate func(*SearchSynonymsResponse, error) bool - Validator function. - @param aggregator func(*SearchSynonymsResponse) - Aggregator function. - @param opts ...Option - Optional parameters for the request. + @param opts ...utils.IterableOption - Optional parameters for the request. @return *SearchSynonymsResponse - Search synonyms response. @return error - Error if any. */ func (c *APIClient) BrowseSynonyms( indexName string, searchSynonymsParams SearchSynonymsParams, - validate func(*SearchSynonymsResponse, error) bool, - aggregator func(*SearchSynonymsResponse, error), - opts ...Option, -) (*SearchSynonymsResponse, error) { - return c.BrowseSynonymsWithContext(context.Background(), indexName, searchSynonymsParams, validate, aggregator, opts...) -} - -/* -BrowseSynonymsWithContext allows to aggregate all the synonyms returned by the API calls. - - @param ctx context.Context - The context that will be drilled down to the actual request. - @param indexName string - Index name. - @param searchSynonymsParams SearchSynonymsParams - Search synonyms parameters. - @param validate func(*SearchSynonymsResponse, error) bool - Validator function. - @param aggregator func(*SearchSynonymsResponse) - Aggregator function. - @param opts ...Option - Optional parameters for the request. - @return *SearchSynonymsResponse - Search synonyms response. - @return error - Error if any. -*/ -func (c *APIClient) BrowseSynonymsWithContext( - ctx context.Context, - indexName string, - searchSynonymsParams SearchSynonymsParams, - validate func(*SearchSynonymsResponse, error) bool, - aggregator func(*SearchSynonymsResponse, error), - opts ...Option, + opts ...utils.IterableOption, ) (*SearchSynonymsResponse, error) { hitsPerPage := int32(1000) if searchSynonymsParams.HitsPerPage != nil { @@ -656,12 +337,6 @@ func (c *APIClient) BrowseSynonymsWithContext( searchSynonymsParams.Page = utils.ToPtr(int32(0)) } - if validate == nil { - validate = func(response *SearchSynonymsResponse, responseErr error) bool { - return responseErr != nil || (response != nil && response.NbHits < hitsPerPage) - } - } - return utils.CreateIterable( //nolint:wrapcheck func(previousResponse *SearchSynonymsResponse, previousErr error) (*SearchSynonymsResponse, error) { searchSynonymsParams.HitsPerPage = &hitsPerPage @@ -670,16 +345,15 @@ func (c *APIClient) BrowseSynonymsWithContext( searchSynonymsParams.Page = utils.ToPtr(*searchSynonymsParams.Page + 1) }() - return c.SearchSynonymsWithContext( - ctx, + return c.SearchSynonyms( c.NewApiSearchSynonymsRequest(indexName).WithSearchSynonymsParams(&searchSynonymsParams), - opts..., + utils.ToRequestOptions(opts)..., ) }, - validate, - aggregator, - nil, - nil, + func(response *SearchSynonymsResponse, responseErr error) bool { + return responseErr != nil || (response != nil && response.NbHits < hitsPerPage) + }, + opts..., ) } @@ -780,12 +454,12 @@ func (c *APIClient) GetSecuredApiKeyRemainingValidity(securedApiKey string) (tim // Helper: Saves the given array of objects in the given index. The `chunkedBatch` helper is used under the hood, which creates a `batch` requests with at most 1000 objects in it. -func (c *APIClient) SaveObjects(indexName string, objects []map[string]any, opts ...ChunkedBatchOption) ([]BatchResponse, error) { +func (c *APIClient) SaveObjects(indexName string, objects []map[string]any, opts ...utils.ChunkedBatchOption) ([]BatchResponse, error) { return c.ChunkedBatch(indexName, objects, ACTION_ADD_OBJECT, opts...) } // Helper: Deletes every records for the given objectIDs. The `chunkedBatch` helper is used under the hood, which creates a `batch` requests with at most 1000 objectIDs in it. -func (c *APIClient) DeleteObjects(indexName string, objectIDs []string, opts ...ChunkedBatchOption) ([]BatchResponse, error) { +func (c *APIClient) DeleteObjects(indexName string, objectIDs []string, opts ...utils.ChunkedBatchOption) ([]BatchResponse, error) { objects := make([]map[string]any, 0, len(objectIDs)) for _, id := range objectIDs { @@ -796,7 +470,7 @@ func (c *APIClient) DeleteObjects(indexName string, objectIDs []string, opts ... } // Helper: Replaces object content of all the given objects according to their respective `objectID` field. The `chunkedBatch` helper is used under the hood, which creates a `batch` requests with at most 1000 objects in it. -func (c *APIClient) PartialUpdateObjects(indexName string, objects []map[string]any, createIfNotExists bool, opts ...ChunkedBatchOption) ([]BatchResponse, error) { +func (c *APIClient) PartialUpdateObjects(indexName string, objects []map[string]any, createIfNotExists bool, opts ...utils.ChunkedBatchOption) ([]BatchResponse, error) { var action Action if createIfNotExists { @@ -808,34 +482,15 @@ func (c *APIClient) PartialUpdateObjects(indexName string, objects []map[string] return c.ChunkedBatch(indexName, objects, action, opts...) } -type ChunkedBatchOptions struct { - WaitForTasks bool - BatchSize int -} - -type ChunkedBatchOption func(*ChunkedBatchOptions) - -func WithChunkedBatchWaitForTasks(waitForTasks bool) ChunkedBatchOption { - return func(o *ChunkedBatchOptions) { - o.WaitForTasks = waitForTasks - } -} - -func WithChunkedBatchBatchSize(batchSize int) ChunkedBatchOption { - return func(o *ChunkedBatchOptions) { - o.BatchSize = batchSize - } -} - // ChunkedBatch chunks the given `objects` list in subset of 1000 elements max in order to make it fit in `batch` requests. -func (c *APIClient) ChunkedBatch(indexName string, objects []map[string]any, action Action, opts ...ChunkedBatchOption) ([]BatchResponse, error) { - options := ChunkedBatchOptions{ +func (c *APIClient) ChunkedBatch(indexName string, objects []map[string]any, action Action, opts ...utils.ChunkedBatchOption) ([]BatchResponse, error) { + options := utils.Options{ WaitForTasks: false, BatchSize: 1000, } for _, opt := range opts { - opt(&options) + opt.Apply(&options) } requests := make([]BatchRequest, 0, len(objects)%options.BatchSize) @@ -845,7 +500,7 @@ func (c *APIClient) ChunkedBatch(indexName string, objects []map[string]any, act requests = append(requests, *NewBatchRequest(action, obj)) if len(requests) == options.BatchSize || i == len(objects)-1 { - resp, err := c.Batch(c.NewApiBatchRequest(indexName, NewBatchWriteParams(requests))) + resp, err := c.Batch(c.NewApiBatchRequest(indexName, NewBatchWriteParams(requests)), utils.ToRequestOptions(opts)...) if err != nil { return nil, err } @@ -857,7 +512,7 @@ func (c *APIClient) ChunkedBatch(indexName string, objects []map[string]any, act if options.WaitForTasks { for _, resp := range responses { - _, err := c.WaitForTask(indexName, resp.TaskID, nil, nil) + _, err := c.WaitForTask(indexName, resp.TaskID, utils.ToIterableOptions(opts)...) if err != nil { return nil, err } @@ -869,42 +524,42 @@ func (c *APIClient) ChunkedBatch(indexName string, objects []map[string]any, act // ReplaceAllObjects replaces all objects (records) in the given `indexName` with the given `objects`. A temporary index is created during this process in order to backup your data. // See https://api-clients-automation.netlify.app/docs/contributing/add-new-api-client#5-helpers for implementation details. -func (c *APIClient) ReplaceAllObjects(indexName string, objects []map[string]any, opts ...ChunkedBatchOption) (*ReplaceAllObjectsResponse, error) { +func (c *APIClient) ReplaceAllObjects(indexName string, objects []map[string]any, opts ...utils.ChunkedBatchOption) (*ReplaceAllObjectsResponse, error) { tmpIndexName := fmt.Sprintf("%s_tmp_%d", indexName, time.Now().UnixNano()) - copyResp, err := c.OperationIndex(c.NewApiOperationIndexRequest(indexName, NewOperationIndexParams(OPERATION_TYPE_COPY, tmpIndexName, WithOperationIndexParamsScope([]ScopeType{SCOPE_TYPE_SETTINGS, SCOPE_TYPE_RULES, SCOPE_TYPE_SYNONYMS})))) + copyResp, err := c.OperationIndex(c.NewApiOperationIndexRequest(indexName, NewOperationIndexParams(OPERATION_TYPE_COPY, tmpIndexName, WithOperationIndexParamsScope([]ScopeType{SCOPE_TYPE_SETTINGS, SCOPE_TYPE_RULES, SCOPE_TYPE_SYNONYMS}))), utils.ToRequestOptions(opts)...) if err != nil { return nil, err } - opts = append(opts, WithChunkedBatchWaitForTasks(true)) + opts = append(opts, utils.WithWaitForTasks(true)) batchResp, err := c.ChunkedBatch(tmpIndexName, objects, ACTION_ADD_OBJECT, opts...) if err != nil { return nil, err } - _, err = c.WaitForTask(tmpIndexName, copyResp.TaskID, nil, nil) + _, err = c.WaitForTask(tmpIndexName, copyResp.TaskID, utils.ToIterableOptions(opts)...) if err != nil { return nil, err } - copyResp, err = c.OperationIndex(c.NewApiOperationIndexRequest(indexName, NewOperationIndexParams(OPERATION_TYPE_COPY, tmpIndexName, WithOperationIndexParamsScope([]ScopeType{SCOPE_TYPE_SETTINGS, SCOPE_TYPE_RULES, SCOPE_TYPE_SYNONYMS})))) + copyResp, err = c.OperationIndex(c.NewApiOperationIndexRequest(indexName, NewOperationIndexParams(OPERATION_TYPE_COPY, tmpIndexName, WithOperationIndexParamsScope([]ScopeType{SCOPE_TYPE_SETTINGS, SCOPE_TYPE_RULES, SCOPE_TYPE_SYNONYMS}))), utils.ToRequestOptions(opts)...) if err != nil { return nil, err } - _, err = c.WaitForTask(tmpIndexName, copyResp.TaskID, nil, nil) + _, err = c.WaitForTask(tmpIndexName, copyResp.TaskID, utils.ToIterableOptions(opts)...) if err != nil { return nil, err } - moveResp, err := c.OperationIndex(c.NewApiOperationIndexRequest(tmpIndexName, NewOperationIndexParams(OPERATION_TYPE_MOVE, indexName))) + moveResp, err := c.OperationIndex(c.NewApiOperationIndexRequest(tmpIndexName, NewOperationIndexParams(OPERATION_TYPE_MOVE, indexName)), utils.ToRequestOptions(opts)...) if err != nil { return nil, err } - _, err = c.WaitForTask(tmpIndexName, moveResp.TaskID, nil, nil) + _, err = c.WaitForTask(tmpIndexName, moveResp.TaskID, utils.ToIterableOptions(opts)...) if err != nil { return nil, err }