diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index a0751418..0109d6d0 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -4,25 +4,26 @@ # You can read more on https://github.com/meilisearch/documentation/tree/master/.vuepress/code-samples --- get_one_index_1: |- - client.Indexes().Get("movies") + client.GetIndex("movies") list_all_indexes_1: |- - client.Indexes().List() + client.GetAllIndexes() create_an_index_1: |- - client.Indexes().Create(meilisearch.CreateIndexRequest{ + client.CreateIndex(&meilisearch.IndexConfig{ UID: "movies", PrimaryKey: "movie_id", }) update_an_index_1: |- - response, error := client.Indexes().Get("movies") - client.Indexes().UpdatePrimaryKey(response.UID, "movie_id") + client.Index("movies").UpdateIndex(response.UID, "movie_id") delete_an_index_1: |- - client.Indexes().Delete("movies") + client.DeleteIndex("movies") + // OR + client.Index("movies").Delete() get_one_document_1: |- var a interface{} - client.Documents("movies").Get("25684", &a) + client.Index("movies").GetDocument("25684", &a) get_documents_1: |- var a []interface{} - client.Documents("movies").List(meilisearch.ListDocumentsRequest{ + client.Index("movies").GetDocuments(meilisearch.DocumentsRequest{ Limit: 2, }, &a) add_or_replace_documents_1: |- @@ -35,7 +36,7 @@ add_or_replace_documents_1: |- "release_date": "2019-03-23", }, } - client.Documents("movies").AddOrReplace(documents) + client.Index("movies").AddDocument(documents) add_or_update_documents_1: |- documents := []map[string]interface{}{ { @@ -44,30 +45,30 @@ add_or_update_documents_1: |- "genres": "comedy", }, } - client.Documents("movies").AddOrUpdate(documents) + client.Index("movies").UpdateDocuments(documents) delete_all_documents_1: |- - client.Documents("movies").DeleteAllDocuments() + client.Index("movies").DeleteAllDocuments() delete_one_document_1: |- - client.Documents("movies").Delete("25684") + client.Index("movies").DeleteDocument("25684") delete_documents_1: |- - client.Documents("movies").Deletes([]string{ + client.Index("movies").DeleteDocuments([]string{ "23488", "153738", "437035", "363869", }) search_post_1: |- - client.Search("movies").Search(SearchRequest{ + client.Index("movies").Search(SearchRequest{ Query: "American ninja", }) get_update_1: |- - client.Updates("movies").Get(0) + client.Index("movies").GetUpdateStatus(0) get_all_updates_1: |- - client.Updates("movies").List() + client.Index("movies").GetAllUpdateStatus() get_keys_1: |- - client.Keys().Get() + client.GetKeys() get_settings_1: |- - client.Settings("movies").GetAll() + client.Index("movies").GetSettings() update_settings_1: |- distinctAttribute := "movie_id" settings := meilisearch.Settings{ @@ -103,29 +104,29 @@ update_settings_1: |- "logan": []string{"wolverine"}, }, } - client.Settings("movies").UpdateAll(settings) + client.Index("movies").UpdateSettings(settings) reset_settings_1: |- - client.Settings("movies").ResetAll() + client.Index("movies").ResetSettings() get_synonyms_1: |- - client.Settings("movies").GetSynonyms() + client.Index("movies").GetSynonyms() update_synonyms_1: |- synonyms := map[string][]string{ "wolverine": []string{"xmen", "logan"}, "logan": []string{"wolverine", "xmen"}, "wow": []string{"world of warcraft"}, } - client.Settings("movies").UpdateSynonyms(synonyms) + client.Index("movies").UpdateSynonyms(synonyms) reset_synonyms_1: |- - client.Settings("movies").ResetSynonyms() + client.Index("movies").ResetSynonyms() get_stop_words_1: |- - client.Settings("movies").GetStopWords() + client.Index("movies").GetStopWords() update_stop_words_1: |- stopWords := []string{"of", "the", "to"} - client.Settings("movies").UpdateStopWords(stopWords) + client.Index("movies").UpdateStopWords(stopWords) reset_stop_words_1: |- - client.Settings(indexUID).ResetStopWords() + client.Index("movies").ResetStopWords() get_ranking_rules_1: |- - client.Settings("movies").GetRankingRules() + client.Index("movies").GetRankingRules() update_ranking_rules_1: |- rankingRules := []string{ "typo", @@ -137,38 +138,38 @@ update_ranking_rules_1: |- "asc(release_date)", "desc(rank)", } - client.Settings("movies").UpdateRankingRules(rankingRules) + client.Index("movies").UpdateRankingRules(rankingRules) reset_ranking_rules_1: |- - client.Settings("movies").ResetRankingRules() + client.Index("movies").ResetRankingRules() get_distinct_attribute_1: |- - client.Settings("movies").GetDistinctAttribute() + client.Index("movies").GetDistinctAttribute() update_distinct_attribute_1: |- - client.Settings("movies").UpdateDistinctAttribute("movie_id") + client.Index("movies").UpdateDistinctAttribute("movie_id") reset_distinct_attribute_1: |- - client.Settings("movies").ResetDistinctAttribute() + client.Index("movies").ResetDistinctAttribute() get_searchable_attributes_1: |- - client.Settings("movies").GetSearchableAttributes() + client.Index("movies").GetSearchableAttributes() update_searchable_attributes_1: |- searchableAttributes := []string{ "title", "description", "genre", } - client.Settings("movies").UpdateSearchableAttributes(searchableAttributes) + client.Index("movies").UpdateSearchableAttributes(searchableAttributes) reset_searchable_attributes_1: |- - client.Settings("movies").ResetSearchableAttributes() + client.Index("movies").ResetSearchableAttributes() get_attributes_for_faceting_1: |- - client.Settings("movies").GetAttributesForFaceting() + client.Index("movies").GetAttributesForFaceting() update_attributes_for_faceting_1: |- attributesForFaceting := []string{ "genres", "director", } - client.Settings("movies").UpdateAttributesForFaceting(attributesForFaceting) + client.Index("movies").UpdateAttributesForFaceting(attributesForFaceting) reset_attributes_for_faceting_1: |- - client.Settings("movies").ResetAttributesForFaceting() + client.Index("movies").ResetAttributesForFaceting() get_displayed_attributes_1: |- - client.Settings("movies").GetDisplayedAttributes() + client.Index("movies").GetDisplayedAttributes() update_displayed_attributes_1: |- displayedAttributes := []string{ "title", @@ -176,26 +177,26 @@ update_displayed_attributes_1: |- "genre", "release_date", } - client.Settings("movies").UpdateDisplayedAttributes(displayedAttributes) + client.Index("movies").UpdateDisplayedAttributes(displayedAttributes) reset_displayed_attributes_1: |- - client.Settings("movies").ResetDisplayedAttributes() + client.Index("movies").ResetDisplayedAttributes() get_index_stats_1: |- - client.Stats().Get("movies") + client.Index("movies").GetStats() get_indexes_stats_1: |- - client.Stats().GetAll() + client.GetAllStats() get_health_1: |- - client.Health().Get() + client.Health() get_version_1: |- - client.Version().Get() + client.GetVersion() distinct_attribute_guide_1: |- - client.Settings("jackets").UpdateDistinctAttribute("product_id") + client.Index("movies").UpdateDistinctAttribute("product_id") field_properties_guide_searchable_1: |- searchableAttributes := []string{ "title", "description", "genre", } - client.Settings("movies").UpdateSearchableAttributes(searchableAttributes) + client.Index("movies").UpdateSearchableAttributes(searchableAttributes) field_properties_guide_displayed_1: |- displayedAttributes := []string{ "title", @@ -203,69 +204,69 @@ field_properties_guide_displayed_1: |- "genre", "release_date", } - client.Settings("movies").UpdateDisplayedAttributes(displayedAttributes) + client.Index("movies").UpdateDisplayedAttributes(displayedAttributes) filtering_guide_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "Avengers", Filters: "release_date > \"795484800\"", }) filtering_guide_2: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "Batman", Filters: "release_date > 795484800 AND (director = \"Tim Burton\" OR director = \"Christopher Nolan\")", }) filtering_guide_3: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "horror", Filters: "director = \"Jordan Peele\"", }) filtering_guide_4: |- - results, error := client.Search("books").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "Planet of the Apes", Filters: "rating >= 3 AND (NOT director = \"Tim Burton\"", }) search_parameter_guide_query_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "shifu", }) search_parameter_guide_offset_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "shifu", Offset: 1, }) search_parameter_guide_limit_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "shifu", Limit: 2, }) search_parameter_guide_retrieve_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "shifu", AttributesToRetrieve: []string{"overview", "title"}, }) search_parameter_guide_crop_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "shifu", AttributesToCrop: []string{"overview"}, CropLength: 10, }) search_parameter_guide_highlight_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "shifu", AttributesToHighlight: []string{"overview"}, }) search_parameter_guide_filter_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "n", Filters: "title = Nightshift", }) search_parameter_guide_filter_2: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "n", Filters: "title=\"Kung Fu Panda\"", }) search_parameter_guide_matches_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "n", Filters: "title=\"Kung Fu Panda\"", AttributesToHighlight: []string{"overview"}, @@ -276,10 +277,10 @@ settings_guide_synonyms_1: |- "sweater": []string{"jumper"}, "jumper": []string{"sweater"}, } - client.Settings("tops").UpdateSynonyms(synonyms) + client.Index("movies").UpdateSynonyms(synonyms) settings_guide_stop_words_1: |- stopWords := []string{"the", "a", "an"} - client.Settings("movies").UpdateStopWords(stopWords) + client.Index("movies").UpdateStopWords(stopWords) settings_guide_ranking_rules_1: |- rankingRules := []string{ "typo", @@ -291,16 +292,16 @@ settings_guide_ranking_rules_1: |- "asc(release_date)", "desc(rank)", } - client.Settings("movies").UpdateRankingRules(rankingRules) + client.Index("movies").UpdateRankingRules(rankingRules) settings_guide_distinct_1: |- - client.Settings("jackets").UpdateDistinctAttribute("movie_id") + client.Index("movies").UpdateDistinctAttribute("movie_id") settings_guide_searchable_1: |- searchableAttributes := []string{ "title", "description", "genre", } - client.Settings("movies").UpdateSearchableAttributes(searchableAttributes) + client.Index("movies").UpdateSearchableAttributes(searchableAttributes) settings_guide_displayed_1: |- displayedAttributes := []string{ "title", @@ -308,7 +309,7 @@ settings_guide_displayed_1: |- "genre", "release_date", } - client.Settings("movies").UpdateDisplayedAttributes(displayedAttributes) + client.Index("movies").UpdateDisplayedAttributes(displayedAttributes) documents_guide_add_movie_1: |- documents := []map[string]interface{}{ { @@ -316,15 +317,15 @@ documents_guide_add_movie_1: |- "title": "Amelie Poulain", }, } - client.Documents("movies").AddOrUpdate(documents) + client.Index("movies").AddDocuments(documents) search_guide_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "shifu", Limit: 5, Offset: 10, }) search_guide_2: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "Avengers", Filters: "release_date > \"795484800\"", }) @@ -337,15 +338,15 @@ getting_started_add_documents_md: |- package main import ( - "os" - "encoding/json" - "io/ioutil" + "os" + "encoding/json" + "io/ioutil" - "github.com/meilisearch/meilisearch-go" + "github.com/meilisearch/meilisearch-go" ) func main() { - var client = NewClient(meilisearch.Config{ + client = meilisearch.NewClient(meilisearch.ClientConfig{ Host: "http://127.0.0.1:7700", }) @@ -356,8 +357,7 @@ getting_started_add_documents_md: |- var movies []map[string]interface{} json.Unmarshal(byteValue, &movies) - update, err := client.Documents("movies").AddOrReplace(movies) - + update, err := client.Index("movies").AddDocuments(movies) if err != nil { panic(err) } @@ -367,7 +367,7 @@ getting_started_add_documents_md: |- [About this SDK](https://github.com/meilisearch/meilisearch-go/) getting_started_search_md: |- ```go - results, err := client.Search("movies").Search(meilisearch.SearchRequest{ + results, err := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "botman", }) if err != nil { @@ -377,12 +377,12 @@ getting_started_search_md: |- [About this SDK](https://github.com/meilisearch/meilisearch-go/) faceted_search_update_settings_1: |- - response, error := client.Settings("movies").UpdateAttributesForFaceting([]string{ + response, error := client.Index("movies").UpdateAttributesForFaceting([]string{ "director", "genres", }) faceted_search_facet_filters_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "thriller", FacetFilters: [][]string{ []string{"genres:Horror", "genres:Mystery"}, @@ -390,21 +390,21 @@ faceted_search_facet_filters_1: |- }, }) faceted_search_facets_distribution_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "Batman", FacetsDistribution: []string{ "genres", }, }) faceted_search_walkthrough_attributes_for_faceting_1: |- - response, error := client.Settings("movies").UpdateAttributesForFaceting([]string{ + response, error := client.Index("movies").UpdateAttributesForFaceting([]string{ "director", "producer", "genres", "production_companies", }) faceted_search_walkthrough_facet_filters_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "thriller", FacetFilters: [][]string{ []string{"genres:Horror", "genres:Mystery"}, @@ -412,13 +412,25 @@ faceted_search_walkthrough_facet_filters_1: |- }, }) faceted_search_walkthrough_facets_distribution_1: |- - results, error := client.Search("movies").Search(meilisearch.SearchRequest{ + results, error := client.Index("movies").Search(meilisearch.SearchRequest{ Query: "Batman", FacetsDistribution: []string{ "genres", }, }) post_dump_1: |- - results, error := client.Dumps().Create() + results, error := client.CreateDump() get_dump_status_1: |- - results, error := client.Dumps().GetStatus("dump-uid") + results, error := client.GetDumpStatus("dump-uid") +add_movies_json_1: |- +import ( + "encoding/json" + "io/ioutil" +) + + file, _ := ioutil.ReadFile("movies.json") + + var movies interface{} + json.Unmarshal([]byte(file), &movies) + + index.AddDocuments(&movies) diff --git a/README.md b/README.md index 577aaf5d..213f9379 100644 --- a/README.md +++ b/README.md @@ -67,43 +67,36 @@ NB: you can also download MeiliSearch from **Homebrew** or **APT**. package main import ( - "fmt" - "os" + "fmt" + "os" - "github.com/meilisearch/meilisearch-go" + "github.com/meilisearch/meilisearch-go" ) func main() { - var client = meilisearch.NewClient(meilisearch.Config{ - Host: "http://127.0.0.1:7700", - APIKey: "masterKey", - }) - - // Create an index if your index does not already exist - _, err := client.Indexes().Create(meilisearch.CreateIndexRequest{ - UID: "books", - }) - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - documents := []map[string]interface{}{ - {"book_id": 123, "title": "Pride and Prejudice"}, - {"book_id": 456, "title": "Le Petit Prince"}, - {"book_id": 1, "title": "Alice In Wonderland"}, - {"book_id": 1344, "title": "The Hobbit"}, - {"book_id": 4, "title": "Harry Potter and the Half-Blood Prince"}, - {"book_id": 42, "title": "The Hitchhiker's Guide to the Galaxy"}, - } - - updateRes, err := client.Documents("books").AddOrUpdate(documents) // => { "updateId": 0 } - if err != nil { - fmt.Println(err) - os.Exit(1) - } - - fmt.Println(updateRes.UpdateID) + client := meilisearch.NewClient(meilisearch.ClientConfig{ + Host: "http://127.0.0.1:7700", + MasterKey: "masterKey", + }) + // An index is where the documents are stored. + index := client.Index("indexUID") + + // If the index 'books' does not exist, MeiliSearch creates it when you first add the documents. + documents := []map[string]interface{}{ + {"book_id": 123, "title": "Pride and Prejudice"}, + {"book_id": 456, "title": "Le Petit Prince"}, + {"book_id": 1, "title": "Alice In Wonderland"}, + {"book_id": 1344, "title": "The Hobbit"}, + {"book_id": 4, "title": "Harry Potter and the Half-Blood Prince"}, + {"book_id": 42, "title": "The Hitchhiker's Guide to the Galaxy"}, + } + update, err := index.AddDocuments(documents) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + + fmt.Println(update.UpdateID) } ``` @@ -123,7 +116,7 @@ import ( func main() { // MeiliSearch is typo-tolerant: - searchRes, err := client.Search("books").Search(meilisearch.SearchRequest{ + searchRes, err := client.Index("books").Search(meilisearch.SearchRequest{ Query: "harry pottre", Limit: 10, }) @@ -156,7 +149,7 @@ All the supported options are described in the [search parameters](https://docs. ```go func main() { - resp, err := client.Search(indexUID).Search(meilisearch.SearchRequest{ + resp, err := client.Index("books").Search(meilisearch.SearchRequest{ Query: "prince", AttributesToHighlight: []string{"*"}, Filters: "book_id > 10" @@ -201,7 +194,7 @@ The following sections may interest you: - **Manipulate documents**: see the [API references](https://docs.meilisearch.com/reference/api/documents.html) or read more about [documents](https://docs.meilisearch.com/learn/core_concepts/documents.html). - **Search**: see the [API references](https://docs.meilisearch.com/reference/api/search.html) or follow our guide on [search parameters](https://docs.meilisearch.com/reference/features/search_parameters.html). - **Manage the indexes**: see the [API references](https://docs.meilisearch.com/reference/api/indexes.html) or read more about [indexes](https://docs.meilisearch.com/learn/core_concepts/indexes.html). -- **Configure the index settings**: see the [API references](https://docs.meilisearch.com/reference/api/settings.html) or follow our guide on [settings parameters](https://docs.meilisearch.com/reference/features/settings.html). +- **ClientConfigure the index settings**: see the [API references](https://docs.meilisearch.com/reference/api/settings.html) or follow our guide on [settings parameters](https://docs.meilisearch.com/reference/features/settings.html). ## ⚙️ Development Workflow and Contributing diff --git a/apis.go b/apis.go deleted file mode 100644 index d76ae587..00000000 --- a/apis.go +++ /dev/null @@ -1,206 +0,0 @@ -package meilisearch - -// APIWithIndexID is used to await an async update id response. -// Each apis that use an index internally implement this interface except APIUpdates. -type APIWithIndexID interface { - IndexID() string - Client() ClientInterface -} - -// APIIndexes index is an entity, like a table in SQL, with a specific schema definition. It gathers a collection of -// documents with the structure defined by the schema. -// An index is defined by an unique identifier uid that is generated by MeiliSearch (if none is given) on index -// creation. It also has a name to help you track your different indexes. -// -// Documentation: https://docs.meilisearch.com/reference/api/indexes.html -type APIIndexes interface { - - // Get the index relative information. - Get(uid string) (*Index, error) - - // List all indexes. - List() ([]Index, error) - - // Create an index. - // If no UID is specified in the request a randomly generated UID will be returned. - // It's associated to the new index. This UID will be essential to make all request over the created index. - // You can define your primary key during the index creation - Create(request CreateIndexRequest) (*CreateIndexResponse, error) - - // Update an index name. - UpdateName(uid string, name string) (*Index, error) - - // Update an index primary key. - UpdatePrimaryKey(uid string, primaryKey string) (*Index, error) - - // Delete an index. - Delete(uid string) (bool, error) -} - -// APIDocuments are objects composed of fields containing any data. -// -// Documentation: https://docs.meilisearch.com/reference/api/documents.html -type APIDocuments interface { - - // Get one document using its unique identifier. - // documentPtr should be a pointer. - Get(identifier string, documentPtr interface{}) error - - // Delete one document based on its unique identifier. - Delete(identifier string) (*AsyncUpdateID, error) - - // Delete a selection of documents based on array of identifiers. - Deletes(identifier []string) (*AsyncUpdateID, error) - - // List the documents in an unordered way. - List(request ListDocumentsRequest, documentsPtr interface{}) error - - // AddOrReplace a list of documents, replace them if they already exist based on their unique identifiers. - AddOrReplace(documentsPtr interface{}) (*AsyncUpdateID, error) - - // AddOrReplaceWithPrimaryKey do the same as AddOrReplace but will specify during the update to primaryKey to use for indexing - AddOrReplaceWithPrimaryKey(documentsPtr interface{}, primaryKey string) (resp *AsyncUpdateID, err error) - - // AddOrUpdate a list of documents, update them if they already exist based on their unique identifiers. - AddOrUpdate(documentsPtr interface{}) (*AsyncUpdateID, error) - - // AddOrUpdateWithPrimaryKey do the same as AddOrUpdate but will specify during the update to primaryKey to use for indexing - AddOrUpdateWithPrimaryKey(documentsPtr interface{}, primaryKey string) (resp *AsyncUpdateID, err error) - - // DeleteAllDocuments in the specified index. - DeleteAllDocuments() (*AsyncUpdateID, error) - - APIWithIndexID -} - -// APISearch search through documents list in an index. -// -// Documentation: https://docs.meilisearch.com/reference/api/search.html -type APISearch interface { - - // Search for documents matching a specific query in the given index. - Search(params SearchRequest) (*SearchResponse, error) - - APIWithIndexID -} - -// APIUpdates MeiliSearch is an asynchronous API. It means that the API does not behave as you would typically expect -// when handling the request's responses. -// -// Some actions are put in a queue and will be executed in turn (asynchronously). In this case, the server response -// contains the identifier to track the execution of the action. -// -// This API permit to get the state of an update id. -// -// Documentation: https://docs.meilisearch.com/reference/api/updates.html -type APIUpdates interface { - - // Get the status of an update in a given index. - Get(id int64) (*Update, error) - - // Get the status of all updates in a given index. - List() ([]Update, error) - - APIWithIndexID -} - -// APIKeys To communicate with MeiliSearch's RESTfull API most of the routes require an API key. -// -// Documentation: https://docs.meilisearch.com/reference/api/keys.html -type APIKeys interface { - - // Get all keys. - Get() (*Keys, error) -} - -// APISettings allow to configure the MeiliSearch indexing & search behaviour. -// -// Documentation: https://docs.meilisearch.com/reference/api/settings.html -type APISettings interface { - GetAll() (*Settings, error) - - UpdateAll(request Settings) (*AsyncUpdateID, error) - - ResetAll() (*AsyncUpdateID, error) - - GetRankingRules() (*[]string, error) - - UpdateRankingRules(arr []string) (*AsyncUpdateID, error) - - ResetRankingRules() (*AsyncUpdateID, error) - - GetDistinctAttribute() (*string, error) - - UpdateDistinctAttribute(string) (*AsyncUpdateID, error) - - ResetDistinctAttribute() (*AsyncUpdateID, error) - - GetSearchableAttributes() (*[]string, error) - - UpdateSearchableAttributes([]string) (*AsyncUpdateID, error) - - ResetSearchableAttributes() (*AsyncUpdateID, error) - - GetDisplayedAttributes() (*[]string, error) - - UpdateDisplayedAttributes([]string) (*AsyncUpdateID, error) - - ResetDisplayedAttributes() (*AsyncUpdateID, error) - - GetStopWords() (*[]string, error) - - UpdateStopWords([]string) (*AsyncUpdateID, error) - - ResetStopWords() (*AsyncUpdateID, error) - - GetSynonyms() (*map[string][]string, error) - - UpdateSynonyms(synonyms map[string][]string) (*AsyncUpdateID, error) - - ResetSynonyms() (*AsyncUpdateID, error) - - GetAttributesForFaceting() (*[]string, error) - - UpdateAttributesForFaceting([]string) (*AsyncUpdateID, error) - - ResetAttributesForFaceting() (*AsyncUpdateID, error) -} - -// APIStats retrieve statistic over all indexes or a specific index id. -// -// Documentation: https://docs.meilisearch.com/reference/api/stats.html -type APIStats interface { - - // Get stats of an index. - Get(indexUID string) (*StatsIndex, error) - - GetAll() (*Stats, error) -} - -// APIHealth handle health of a MeiliSearch server. -// -// Documentation: https://docs.meilisearch.com/reference/api/health.html -type APIHealth interface { - - // Get health of MeiliSearch server. - Get() error -} - -// APIDumps handle the creation of database dumps from MeiliSearch server. -// -// Documentation: https://docs.meilisearch.com/reference/api/dump.html -type APIDumps interface { - // Create a Dump. - Create() (*Dump, error) - // Get Dump status. - GetStatus(dumpUID string) (*Dump, error) -} - -// APIVersion retrieve the version of MeiliSearch. -// -// Documentation: https://docs.meilisearch.com/reference/api/version.html -type APIVersion interface { - - // Get version of MeiliSearch. - Get() (*Version, error) -} diff --git a/client.go b/client.go index 19e8ceee..840515cc 100644 --- a/client.go +++ b/client.go @@ -1,328 +1,166 @@ package meilisearch import ( - "context" - "github.com/pkg/errors" - "github.com/valyala/fasthttp" - "net/url" - "time" + "net/http" - "encoding/json" + "github.com/valyala/fasthttp" ) -// Config configure the Client -type Config struct { +// ClientConfig configure the Client +type ClientConfig struct { // Host is the host of your meilisearch database // Example: 'http://localhost:7700' Host string - // APIKey is optional - APIKey string + // MasterKey is optional + MasterKey string } // ClientInterface is interface for all Meilisearch client type ClientInterface interface { - WaitForPendingUpdate(ctx context.Context, interval time.Duration, indexID string, updateID *AsyncUpdateID) (UpdateStatus, error) - DefaultWaitForPendingUpdate(indexUID string, updateID *AsyncUpdateID) (UpdateStatus, error) - - Indexes() APIIndexes - Version() APIVersion - Documents(indexID string) APIDocuments - Search(indexID string) APISearch - Updates(indexID string) APIUpdates - Settings(indexID string) APISettings - Keys() APIKeys - Stats() APIStats - Health() APIHealth - Dumps() APIDumps -} - -// Client is a structure that give you the power for interacting with an high-level api with meilisearch. -type Client struct { - config Config - httpClient *fasthttp.Client - - // singleton clients which don't need index id - apiIndexes APIIndexes - apiKeys APIKeys - apiStats APIStats - apiHealth APIHealth - apiVersion APIVersion - apiDumps APIDumps -} - -// Indexes return an APIIndexes client. -func (c *Client) Indexes() APIIndexes { - return c.apiIndexes -} - -// Version return an APIVersion client. -func (c *Client) Version() APIVersion { - return c.apiVersion -} - -// Documents return an APIDocuments client. -func (c *Client) Documents(indexID string) APIDocuments { - return newClientDocuments(c, indexID) -} - -// Search return an APISearch client. -func (c *Client) Search(indexID string) APISearch { - return newClientSearch(c, indexID) -} - -// Updates return an APIUpdates client. -func (c *Client) Updates(indexID string) APIUpdates { - return newClientUpdates(c, indexID) -} - -// Settings return an APISettings client. -func (c *Client) Settings(indexID string) APISettings { - return newClientSettings(c, indexID) -} - -// Keys return an APIKeys client. -func (c *Client) Keys() APIKeys { - return c.apiKeys -} - -// Stats return an APIStats client. -func (c *Client) Stats() APIStats { - return c.apiStats -} - -// Health return an APIHealth client. -func (c *Client) Health() APIHealth { - return c.apiHealth -} - -// Dumps return an APIDumps client. -func (c *Client) Dumps() APIDumps { - return c.apiDumps -} + Index(uid string) *Index + GetIndex(indexID string) (resp *Index, err error) + GetAllIndexes() (resp []*Index, err error) + CreateIndex(config *IndexConfig) (resp *Index, err error) + GetOrCreateIndex(config *IndexConfig) (resp *Index, err error) + DeleteIndex(uid string) (bool, error) + GetKeys() (resp *Keys, err error) + GetAllStats() (resp *Stats, err error) + CreateDump() (resp *Dump, err error) + GetDumpStatus(dumpUID string) (resp *Dump, err error) + Version() (*Version, error) + GetVersion() (resp *Version, err error) + Health() (*Health, error) + IsHealthy() bool +} + +var _ ClientInterface = &Client{} // NewFastHTTPCustomClient creates Meilisearch with custom fasthttp.Client -func NewFastHTTPCustomClient(config Config, client *fasthttp.Client) ClientInterface { +func NewFastHTTPCustomClient(config ClientConfig, client *fasthttp.Client) *Client { c := &Client{ config: config, httpClient: client, } - - c.apiIndexes = newClientIndexes(c) - c.apiKeys = newClientKeys(c) - c.apiHealth = newClientHealth(c) - c.apiStats = newClientStats(c) - c.apiVersion = newClientVersion(c) - c.apiDumps = newClientDumps(c) - return c } // NewClient creates Meilisearch with default fasthttp.Client -func NewClient(config Config) ClientInterface { +func NewClient(config ClientConfig) *Client { client := &fasthttp.Client{ Name: "meilsearch-client", } - c := &Client{ config: config, httpClient: client, } - - c.apiIndexes = newClientIndexes(c) - c.apiKeys = newClientKeys(c) - c.apiHealth = newClientHealth(c) - c.apiStats = newClientStats(c) - c.apiVersion = newClientVersion(c) - c.apiDumps = newClientDumps(c) - return c } -type internalRequest struct { - endpoint string - method string - - withRequest interface{} - withResponse interface{} - withQueryParams map[string]string - - acceptedStatusCodes []int - - functionName string - apiName string -} - -func (c *Client) executeRequest(req internalRequest) error { - internalError := &Error{ - Endpoint: req.endpoint, - Method: req.method, - Function: req.functionName, - APIName: req.apiName, - RequestToString: "empty request", - ResponseToString: "empty response", - MeilisearchMessage: "empty meilisearch message", - StatusCodeExpected: req.acceptedStatusCodes, +func (c *Client) Version() (resp *Version, err error) { + resp = &Version{} + req := internalRequest{ + endpoint: "/version", + method: http.MethodGet, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "Version", } - - response := fasthttp.AcquireResponse() - defer fasthttp.ReleaseResponse(response) - err := c.sendRequest(&req, internalError, response) - if err != nil { - return err + if err := c.executeRequest(req); err != nil { + return nil, err } - internalError.StatusCode = response.StatusCode() - - err = c.handleStatusCode(&req, response, internalError) - if err != nil { - return err - } - - err = c.handleResponse(&req, response, internalError) - if err != nil { - return err - } - return nil + return resp, nil } -func (c *Client) sendRequest(req *internalRequest, internalError *Error, response *fasthttp.Response) error { - var ( - request *fasthttp.Request - - err error - ) +func (c *Client) GetVersion() (resp *Version, err error) { + return c.Version() +} - // Setup URL - requestURL, err := url.Parse(c.config.Host + req.endpoint) - if err != nil { - return errors.Wrap(err, "unable to parse url") +func (c *Client) GetAllStats() (resp *Stats, err error) { + resp = &Stats{} + req := internalRequest{ + endpoint: "/stats", + method: http.MethodGet, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetAllStats", } - - // Build query parameters - if req.withQueryParams != nil { - query := requestURL.Query() - for key, value := range req.withQueryParams { - query.Set(key, value) - } - - requestURL.RawQuery = query.Encode() + if err := c.executeRequest(req); err != nil { + return nil, err } - - request = fasthttp.AcquireRequest() - defer fasthttp.ReleaseRequest(request) - - request.SetRequestURI(requestURL.String()) - request.Header.SetMethod(req.method) - - if req.withRequest != nil { - - // A json request is mandatory, so the request interface{} need to be passed as a raw json body. - rawJSONRequest := req.withRequest - var data []byte - var err error - if raw, ok := rawJSONRequest.(json.Marshaler); ok { - data, err = raw.MarshalJSON() - } else { - data, err = json.Marshal(rawJSONRequest) - } - internalError.RequestToString = string(data) - if err != nil { - return internalError.WithErrCode(ErrCodeMarshalRequest, err) - } - request.SetBody(data) + return resp, nil +} + +func (c *Client) GetKeys() (resp *Keys, err error) { + resp = &Keys{} + req := internalRequest{ + endpoint: "/keys", + method: http.MethodGet, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetKeys", } - - // adding request headers - request.Header.Set("Content-Type", "application/json") - if c.config.APIKey != "" { - request.Header.Set("X-Meili-API-Key", c.config.APIKey) + if err := c.executeRequest(req); err != nil { + return nil, err } - - // request is sent - err = c.httpClient.Do(request, response) - - // request execution fail - if err != nil { - return internalError.WithErrCode(ErrCodeRequestExecution, err) + return resp, nil +} + +func (c *Client) Health() (resp *Health, err error) { + resp = &Health{} + req := internalRequest{ + endpoint: "/health", + method: http.MethodGet, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "Health", } - - return nil -} - -func (c *Client) handleStatusCode(req *internalRequest, response *fasthttp.Response, internalError *Error) error { - if req.acceptedStatusCodes != nil { - - // A successful status code is required so check if the response status code is in the - // expected status code list. - for _, acceptedCode := range req.acceptedStatusCodes { - if response.StatusCode() == acceptedCode { - return nil - } - } - // At this point the response status code is a failure. - rawBody := response.Body() - - internalError.ErrorBody(rawBody) - - return internalError.WithErrCode(ErrCodeResponseStatusCode) + if err := c.executeRequest(req); err != nil { + return nil, err } - - return nil + return resp, nil } -func (c *Client) handleResponse(req *internalRequest, response *fasthttp.Response, internalError *Error) (err error) { - if req.withResponse != nil { - - // A json response is mandatory, so the response interface{} need to be unmarshal from the response payload. - rawBody := response.Body() - internalError.ResponseToString = string(rawBody) - - var err error - if resp, ok := req.withResponse.(json.Unmarshaler); ok { - err = resp.UnmarshalJSON(rawBody) - req.withResponse = resp - } else { - err = json.Unmarshal(rawBody, req.withResponse) - } - if err != nil { - return internalError.WithErrCode(ErrCodeResponseUnmarshalBody, err) - } +func (c *Client) IsHealthy() bool { + if _, err := c.Health(); err != nil { + return false } - return nil -} - -// DefaultWaitForPendingUpdate checks each 50ms the status of a WaitForPendingUpdate. -// This is a default implementation of WaitForPendingUpdate. -func (c Client) DefaultWaitForPendingUpdate(indexUID string, updateID *AsyncUpdateID) (UpdateStatus, error) { - ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5) - defer cancelFunc() - - return c.WaitForPendingUpdate(ctx, time.Millisecond*50, indexUID, updateID) -} - -// WaitForPendingUpdate waits for the end of an update. -// The function will check by regular interval provided in parameter interval -// the UpdateStatus. If it is not UpdateStatusEnqueued or the ctx cancelled -// we return the UpdateStatus. -func (c Client) WaitForPendingUpdate( - ctx context.Context, - interval time.Duration, - indexID string, - updateID *AsyncUpdateID) (UpdateStatus, error) { - - apiUpdates := c.Updates(indexID) - for { - if err := ctx.Err(); err != nil { - return "", err - } - update, err := apiUpdates.Get(updateID.UpdateID) - if err != nil { - return UpdateStatusUnknown, nil - } - if update.Status != UpdateStatusEnqueued { - return update.Status, nil - } - time.Sleep(interval) + return true +} + +func (c *Client) CreateDump() (resp *Dump, err error) { + resp = &Dump{} + req := internalRequest{ + endpoint: "/dumps", + method: http.MethodPost, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusAccepted}, + functionName: "CreateDump", + } + if err := c.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (c *Client) GetDumpStatus(dumpUID string) (resp *Dump, err error) { + resp = &Dump{} + req := internalRequest{ + endpoint: "/dumps/" + dumpUID + "/status", + method: http.MethodGet, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetDumpStatus", + } + if err := c.executeRequest(req); err != nil { + return nil, err } + return resp, nil } diff --git a/client_documents.go b/client_documents.go deleted file mode 100644 index 1de6aca9..00000000 --- a/client_documents.go +++ /dev/null @@ -1,203 +0,0 @@ -package meilisearch - -import ( - "net/http" - "strconv" - "strings" -) - -type clientDocuments struct { - client *Client - indexUID string -} - -func newClientDocuments(client *Client, indexUID string) clientDocuments { - return clientDocuments{client: client, indexUID: indexUID} -} - -func (c clientDocuments) Get(identifier string, documentPtr interface{}) error { - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents/" + identifier, - method: http.MethodGet, - withRequest: nil, - withResponse: documentPtr, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "Get", - apiName: "Documents", - } - - if err := c.client.executeRequest(req); err != nil { - return err - } - return nil -} - -func (c clientDocuments) Delete(identifier string) (resp *AsyncUpdateID, err error) { - resp = &AsyncUpdateID{} - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents/" + identifier, - method: http.MethodDelete, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "Delete", - apiName: "Documents", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientDocuments) Deletes(identifier []string) (resp *AsyncUpdateID, err error) { - resp = &AsyncUpdateID{} - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents/delete-batch", - method: http.MethodPost, - withRequest: identifier, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "Deletes", - apiName: "Documents", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientDocuments) List(request ListDocumentsRequest, response interface{}) error { - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents", - method: http.MethodGet, - withRequest: request, - withResponse: response, - withQueryParams: map[string]string{}, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "List", - apiName: "Documents", - } - - if request.Limit != 0 { - req.withQueryParams["limit"] = strconv.FormatInt(request.Limit, 10) - } - if request.Offset != 0 { - req.withQueryParams["offset"] = strconv.FormatInt(request.Offset, 10) - } - if len(request.AttributesToRetrieve) != 0 { - req.withQueryParams["attributesToRetrieve"] = strings.Join(request.AttributesToRetrieve, ",") - } - - if err := c.client.executeRequest(req); err != nil { - return err - } - - return nil -} - -func (c clientDocuments) AddOrReplace(documentsPtr interface{}) (resp *AsyncUpdateID, err error) { - resp = &AsyncUpdateID{} - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents", - method: http.MethodPost, - withRequest: documentsPtr, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "AddOrReplace", - apiName: "Documents", - } - - if err = c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientDocuments) AddOrReplaceWithPrimaryKey(documentsPtr interface{}, primaryKey string) (resp *AsyncUpdateID, err error) { - resp = &AsyncUpdateID{} - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents?primaryKey=" + primaryKey, - method: http.MethodPost, - withRequest: documentsPtr, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "AddOrReplaceWithPrimaryKey", - apiName: "Documents", - } - - if err = c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientDocuments) AddOrUpdate(documentsPtr interface{}) (*AsyncUpdateID, error) { - var err error - resp := &AsyncUpdateID{} - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents", - method: http.MethodPut, - withRequest: documentsPtr, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "AddOrUpdate", - apiName: "Documents", - } - - if err = c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientDocuments) AddOrUpdateWithPrimaryKey(documentsPtr interface{}, primaryKey string) (resp *AsyncUpdateID, err error) { - resp = &AsyncUpdateID{} - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents?primaryKey=" + primaryKey, - method: http.MethodPut, - withRequest: documentsPtr, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "AddOrUpdateWithPrimaryKey", - apiName: "Documents", - } - - if err = c.client.executeRequest(req); err != nil { - return nil, err - } - return resp, nil -} - -func (c clientDocuments) DeleteAllDocuments() (resp *AsyncUpdateID, err error) { - resp = &AsyncUpdateID{} - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/documents", - method: http.MethodDelete, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "DeleteAllDocuments", - apiName: "Documents", - } - - if err = c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientDocuments) IndexID() string { - return c.indexUID -} - -func (c clientDocuments) Client() ClientInterface { - return c.client -} diff --git a/client_documents_test.go b/client_documents_test.go deleted file mode 100644 index b83eb37d..00000000 --- a/client_documents_test.go +++ /dev/null @@ -1,267 +0,0 @@ -package meilisearch - -import ( - "testing" -) - -func TestClientDocuments_Get(t *testing.T) { - var indexUID = "TestClientDocuments_Get" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client. - Documents(indexUID). - AddOrUpdate([]interface{}{ - docTest{ID: "123", Name: "nestle"}, - }) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - var doc docTest - if err = client. - Documents(indexUID). - Get("123", &doc); err != nil { - t.Fatal(err) - } - - expect := docTest{ID: "123", Name: "nestle"} - if doc != expect { - t.Errorf("%v != %v", doc, expect) - } -} - -func TestClientDocuments_Delete(t *testing.T) { - var indexUID = "TestClientDocuments_Delete" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client. - Documents(indexUID). - AddOrUpdate([]interface{}{ - docTest{ID: "123", Name: "nestle"}, - }) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - updateIDRes, err = client.Documents(indexUID).Delete("123") - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - var doc docTest - err = client.Documents(indexUID).Get("123", &doc) - - if err.(*Error).ErrCode != ErrCodeResponseStatusCode { - t.Fatal(err) - } -} - -func TestClientDocuments_Deletes(t *testing.T) { - var indexUID = "deletes" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client. - Documents(indexUID). - AddOrUpdate([]interface{}{ - docTest{ID: "123", Name: "nestle"}, - docTest{ID: "456", Name: "nestle"}, - }) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - updateIDRes, err = client.Documents(indexUID).Deletes([]string{"123", "456"}) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - var doc docTest - err = client.Documents(indexUID).Get("123", &doc) - - if err.(*Error).ErrCode != ErrCodeResponseStatusCode { - t.Fatal(err) - } -} - -func TestClientDocuments_List(t *testing.T) { - var indexUID = "TestClientDocuments_List" - - if _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }); err != nil { - t.Fatal(err) - } - - updateIDRes, err := client. - Documents(indexUID). - AddOrUpdate([]interface{}{ - docTest{ID: "123", Name: "nestle"}, - docTest{ID: "456", Name: "hershey"}, - }) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - var list []docTest - err = client.Documents(indexUID).List(ListDocumentsRequest{ - Offset: 1, - Limit: 1, - }, &list) - - if err != nil { - t.Fatal(err) - } - - if len(list) == 0 || list[0].ID != "456" { - t.Fatal("expected to return the document[1]") - } -} - -func TestClientDocuments_AddOrReplace(t *testing.T) { - var indexUID = "TestClientDocuments_AddOrReplace" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client. - Documents(indexUID). - AddOrReplace([]docTest{ - {ID: "123", Name: "nestle"}, - {ID: "456", Name: "nestle"}, - }) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - var list []docTest - err = client.Documents(indexUID).List(ListDocumentsRequest{ - Offset: 0, - Limit: 100, - }, &list) - - if err != nil { - t.Fatal(err) - } - - // tests are running in parallel so there can be more than 1 docs - if len(list) < 2 { - t.Fatal("number of doc should be at least 1") - } -} - -func TestClientDocuments_AddOrUpdate(t *testing.T) { - var indexUID = "TestClientDocuments_AddOrUpdate" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client. - Documents(indexUID). - AddOrUpdate([]docTest{ - {ID: "123", Name: "nestle"}, - {ID: "456", Name: "nestle"}, - }) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - var list []docTest - err = client.Documents(indexUID).List(ListDocumentsRequest{ - Offset: 0, - Limit: 100, - }, &list) - - if err != nil { - t.Fatal(err) - } - - // tests are running in parallel so there can be more than 1 docs - if len(list) < 2 { - t.Fatal("number of doc should be at least 1") - } -} - -func TestClientDocuments_DeleteAllDocuments(t *testing.T) { - var indexUID = "TestClientDocuments_DeleteAllDocuments" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client. - Documents(indexUID). - AddOrUpdate([]interface{}{ - docTest{ID: "123", Name: "nestle"}, - docTest{ID: "456", Name: "nestle"}, - }) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - _, err = client.Documents(indexUID).DeleteAllDocuments() - - if err != nil { - t.Fatal(err) - } -} diff --git a/client_dumps.go b/client_dumps.go deleted file mode 100644 index 47235bad..00000000 --- a/client_dumps.go +++ /dev/null @@ -1,47 +0,0 @@ -package meilisearch - -import ( - "net/http" -) - -type clientDumps struct { - client *Client -} - -func newClientDumps(client *Client) clientDumps { - return clientDumps{client: client} -} - -func (c clientDumps) Create() (resp *Dump, err error) { - resp = &Dump{} - req := internalRequest{ - endpoint: "/dumps", - method: http.MethodPost, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "Create", - apiName: "Dumps", - } - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - return resp, nil -} - -func (c clientDumps) GetStatus(dumpUID string) (resp *Dump, err error) { - resp = &Dump{} - req := internalRequest{ - endpoint: "/dumps/" + dumpUID + "/status", - method: http.MethodGet, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "GetStatus", - apiName: "Dumps", - } - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - return resp, nil -} diff --git a/client_dumps_test.go b/client_dumps_test.go deleted file mode 100644 index c81d768a..00000000 --- a/client_dumps_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package meilisearch - -import ( - "testing" -) - -func contains(a []string, x string) bool { - for _, n := range a { - if x == n { - return true - } - } - return false -} - -func TestClientDumps_CreateAndGetStatus(t *testing.T) { - resp, err := client.Dumps().Create() - - if err != nil { - t.Fatal(err) - } - - if resp.Status != "in_progress" { - t.Fatal("response create dump does not have the 'in_progress' status") - } - var dumpUID = resp.UID - resp, err = client.Dumps().GetStatus(dumpUID) - if err != nil { - t.Fatal(err) - } - if resp.UID != dumpUID { - t.Fatal("response get dump status does not have the same UID") - } - - var possibleStatuses = []string{"in_progress", "failed", "done"} - if !contains(possibleStatuses, resp.Status) { - t.Fatalf("response get dump status must be from %q", possibleStatuses) - } -} diff --git a/client_health.go b/client_health.go deleted file mode 100644 index 83bdf70e..00000000 --- a/client_health.go +++ /dev/null @@ -1,30 +0,0 @@ -package meilisearch - -import ( - "net/http" - - "github.com/valyala/fastjson" -) - -type clientHealth struct { - client *Client - arp *fastjson.ArenaPool -} - -func newClientHealth(client *Client) clientHealth { - return clientHealth{client: client} -} - -func (c clientHealth) Get() error { - req := internalRequest{ - endpoint: "/health", - method: http.MethodGet, - withRequest: nil, - withResponse: nil, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "Get", - apiName: "Health", - } - - return c.client.executeRequest(req) -} diff --git a/client_health_test.go b/client_health_test.go deleted file mode 100644 index ec5e9316..00000000 --- a/client_health_test.go +++ /dev/null @@ -1,9 +0,0 @@ -package meilisearch - -import "testing" - -func TestClientHealth_Get(t *testing.T) { - if err := client.Health().Get(); err != nil { - t.Fatal(err) - } -} diff --git a/client_index.go b/client_index.go new file mode 100644 index 00000000..11a4535d --- /dev/null +++ b/client_index.go @@ -0,0 +1,71 @@ +package meilisearch + +import "net/http" + +func (c *Client) Index(uid string) *Index { + return newIndex(c, uid) +} + +func (c *Client) GetIndex(uid string) (resp *Index, err error) { + return newIndex(c, uid).FetchInfo() +} + +func (c *Client) CreateIndex(config *IndexConfig) (resp *Index, err error) { + request := &CreateIndexRequest{ + UID: config.Uid, + PrimaryKey: config.PrimaryKey, + } + resp = newIndex(c, config.Uid) + req := internalRequest{ + endpoint: "/indexes", + method: http.MethodPost, + withRequest: request, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusCreated}, + functionName: "CreateIndex", + } + if err := c.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (c *Client) GetAllIndexes() (resp []*Index, err error) { + resp = []*Index{} + req := internalRequest{ + endpoint: "/indexes", + method: http.MethodGet, + withRequest: nil, + withResponse: &resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetAllIndexes", + } + if err := c.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (c *Client) GetOrCreateIndex(config *IndexConfig) (resp *Index, err error) { + resp, err = c.GetIndex(config.Uid) + if err == nil { + return resp, err + } + return c.CreateIndex(config) +} + +func (c *Client) DeleteIndex(uid string) (ok bool, err error) { + req := internalRequest{ + endpoint: "/indexes/" + uid, + method: http.MethodDelete, + withRequest: nil, + withResponse: nil, + acceptedStatusCodes: []int{http.StatusNoContent}, + functionName: "DeleteIndex", + } + // err is not nil if status code is not 204 StatusNoContent + if err := c.executeRequest(req); err != nil { + return false, err + } + return true, nil +} diff --git a/client_index_test.go b/client_index_test.go new file mode 100644 index 00000000..ef51d5c8 --- /dev/null +++ b/client_index_test.go @@ -0,0 +1,477 @@ +package meilisearch + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestClient_CreateIndex(t *testing.T) { + type args struct { + config IndexConfig + } + tests := []struct { + name string + client *Client + args args + wantResp *Index + }{ + { + name: "TestBasicCreateIndex", + client: defaultClient, + args: args{ + config: IndexConfig{ + Uid: "TestBasicCreateIndex", + }, + }, + wantResp: &Index{ + UID: "TestBasicCreateIndex", + }, + }, + { + name: "TestCreateIndexWithCustomClient", + client: customClient, + args: args{ + config: IndexConfig{ + Uid: "TestBasicCreateIndex", + }, + }, + wantResp: &Index{ + UID: "TestBasicCreateIndex", + }, + }, + { + name: "TestCreateIndexWithCustomClient", + client: customClient, + args: args{ + config: IndexConfig{ + Uid: "TestBasicCreateIndex", + }, + }, + wantResp: &Index{ + UID: "TestBasicCreateIndex", + }, + }, + { + name: "TestCreateIndexWithPrimaryKey", + client: defaultClient, + args: args{ + config: IndexConfig{ + Uid: "TestCreateIndexWithPrimaryKey", + PrimaryKey: "PrimaryKey", + }, + }, + wantResp: &Index{ + UID: "TestCreateIndexWithPrimaryKey", + PrimaryKey: "PrimaryKey", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.client + + gotResp, err := c.CreateIndex(&tt.args.config) + require.NoError(t, err) + if assert.NotNil(t, gotResp) { + require.Equal(t, tt.wantResp.UID, gotResp.UID) + require.Equal(t, tt.wantResp.PrimaryKey, gotResp.PrimaryKey) + } + + deleteAllIndexes(c) + }) + } +} + +func TestClient_DeleteIndex(t *testing.T) { + type args struct { + createUid []string + deleteUid []string + } + tests := []struct { + name string + client *Client + args args + wantOk bool + wantErr bool + }{ + { + name: "TestBasicDeleteIndex", + client: defaultClient, + args: args{ + createUid: []string{"1"}, + deleteUid: []string{"1"}, + }, + wantOk: true, + wantErr: false, + }, + { + name: "TestDeleteIndexWithCustomClient", + client: customClient, + args: args{ + createUid: []string{"1"}, + deleteUid: []string{"1"}, + }, + wantOk: true, + wantErr: false, + }, + { + name: "TestMultipleDeleteIndex", + client: defaultClient, + args: args{ + createUid: []string{"2", "3", "4", "5"}, + deleteUid: []string{"2", "3", "4", "5"}, + }, + wantOk: true, + wantErr: false, + }, + { + name: "TestNotExistingDeleteIndex", + client: defaultClient, + args: args{ + deleteUid: []string{"1"}, + }, + wantOk: false, + wantErr: true, + }, + { + name: "TestMultipleNotExistingDeleteIndex", + client: defaultClient, + args: args{ + deleteUid: []string{"2", "3", "4", "5"}, + }, + wantOk: false, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.client + + for _, uid := range tt.args.createUid { + _, err := c.CreateIndex(&IndexConfig{Uid: uid}) + require.NoError(t, err, "CreateIndex() in TestDeleteIndex error should be nil") + } + for _, uid := range tt.args.deleteUid { + gotOk, err := c.DeleteIndex(uid) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.wantOk, gotOk) + } + } + + deleteAllIndexes(c) + }) + } +} + +func TestClient_GetAllIndexes(t *testing.T) { + type args struct { + uid []string + } + tests := []struct { + name string + client *Client + args args + wantResp []Index + wantErr bool + }{ + { + name: "TestGelAllIndexesOnNoIndexes", + client: defaultClient, + args: args{ + uid: []string{}, + }, + wantResp: []Index{}, + wantErr: false, + }, + { + name: "TestBasicGelAllIndexes", + client: defaultClient, + args: args{ + uid: []string{"1"}, + }, + wantResp: []Index{ + { + UID: "1", + }, + }, + wantErr: false, + }, + { + name: "TestGelAllIndexesWithCustomClient", + client: customClient, + args: args{ + uid: []string{"1"}, + }, + wantResp: []Index{ + { + UID: "1", + }, + }, + wantErr: false, + }, + { + name: "TestGelAllIndexesOnMultipleIndex", + client: defaultClient, + args: args{ + uid: []string{"1", "2", "3"}, + }, + wantResp: []Index{ + { + UID: "1", + }, + { + UID: "2", + }, + { + UID: "3", + }, + }, + wantErr: false, + }, + { + name: "TestGelAllIndexesOnMultipleIndexWithPrimaryKey", + client: defaultClient, + args: args{ + uid: []string{"1", "2", "3"}, + }, + wantResp: []Index{ + { + UID: "1", + PrimaryKey: "PrimaryKey1", + }, + { + UID: "2", + PrimaryKey: "PrimaryKey2", + }, + { + UID: "3", + PrimaryKey: "PrimaryKey3", + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.client + + for _, uid := range tt.args.uid { + _, err := c.CreateIndex(&IndexConfig{Uid: uid}) + require.NoError(t, err, "CreateIndex() in TestGetAllIndexes error should be nil") + } + gotResp, err := c.GetAllIndexes() + require.NoError(t, err) + require.Equal(t, len(tt.wantResp), len(gotResp)) + + deleteAllIndexes(c) + }) + } +} + +func TestClient_GetIndex(t *testing.T) { + type args struct { + config IndexConfig + createdUid string + uid string + } + tests := []struct { + name string + client *Client + args args + wantResp *Index + wantErr bool + wantCmp bool + }{ + { + name: "TestBasicGetIndex", + client: defaultClient, + args: args{ + config: IndexConfig{ + Uid: "1", + }, + uid: "1", + }, + wantResp: &Index{ + UID: "1", + }, + wantErr: false, + wantCmp: false, + }, + { + name: "TestGetIndexWithCustomClient", + client: customClient, + args: args{ + config: IndexConfig{ + Uid: "1", + }, + uid: "1", + }, + wantResp: &Index{ + UID: "1", + }, + wantErr: false, + wantCmp: false, + }, + { + name: "TestGetIndexWithPrimaryKey", + client: defaultClient, + args: args{ + config: IndexConfig{ + Uid: "1", + PrimaryKey: "PrimaryKey", + }, + uid: "1", + }, + wantResp: &Index{ + UID: "1", + PrimaryKey: "PrimaryKey", + }, + wantErr: false, + wantCmp: false, + }, + { + name: "TestGetIndexOnNotExistingIndex", + client: defaultClient, + args: args{ + config: IndexConfig{}, + uid: "1", + }, + wantResp: nil, + wantErr: true, + wantCmp: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.client + + gotCreatedResp, err := c.CreateIndex(&tt.args.config) + gotResp, err := c.GetIndex(tt.args.uid) + if (err != nil) != tt.wantErr { + t.Errorf("GetIndex() error = %v, wantErr %v", err, tt.wantErr) + return + } + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.wantResp.UID, gotResp.UID) + require.Equal(t, gotCreatedResp.UID, gotResp.UID) + require.Equal(t, tt.wantResp.PrimaryKey, gotResp.PrimaryKey) + require.Equal(t, gotCreatedResp.PrimaryKey, gotResp.PrimaryKey) + } + + deleteAllIndexes(c) + }) + } +} + +func TestClient_GetOrCreateIndex(t *testing.T) { + type args struct { + config IndexConfig + } + tests := []struct { + name string + client *Client + args args + wantResp *Index + }{ + { + name: "TestBasicGetOrCreateIndex", + client: defaultClient, + args: args{ + config: IndexConfig{ + Uid: "TestBasicGetOrCreateIndex", + }, + }, + wantResp: &Index{ + UID: "TestBasicGetOrCreateIndex", + }, + }, + { + name: "TestGetOrCreateIndexWithCustomClient", + client: customClient, + args: args{ + config: IndexConfig{ + Uid: "TestBasicGetOrCreateIndex", + }, + }, + wantResp: &Index{ + UID: "TestBasicGetOrCreateIndex", + }, + }, + { + name: "TestGetOrCreateIndexWithPrimaryKey", + client: defaultClient, + args: args{ + config: IndexConfig{ + Uid: "TestGetOrCreateIndexWithPrimaryKey", + PrimaryKey: "PrimaryKey", + }, + }, + wantResp: &Index{ + UID: "TestGetOrCreateIndexWithPrimaryKey", + PrimaryKey: "PrimaryKey", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.client + + gotResp, err := c.GetOrCreateIndex(&tt.args.config) + require.NoError(t, err) + if assert.NotNil(t, gotResp) { + require.Equal(t, tt.wantResp.UID, gotResp.UID) + require.Equal(t, tt.wantResp.PrimaryKey, gotResp.PrimaryKey) + } + + deleteAllIndexes(c) + }) + } +} + +func TestClient_Index(t *testing.T) { + type args struct { + uid string + } + tests := []struct { + name string + client *Client + args args + want Index + }{ + { + name: "TestBasicIndex", + client: defaultClient, + args: args{ + uid: "1", + }, + want: Index{ + UID: "1", + }, + }, + { + name: "TestIndexWithCustomClient", + client: customClient, + args: args{ + uid: "1", + }, + want: Index{ + UID: "1", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.client.Index(tt.args.uid) + require.NotNil(t, got) + require.Equal(t, tt.want.UID, got.UID) + }) + } +} diff --git a/client_indexes.go b/client_indexes.go deleted file mode 100644 index de56bf0b..00000000 --- a/client_indexes.go +++ /dev/null @@ -1,125 +0,0 @@ -package meilisearch - -import ( - "net/http" -) - -type clientIndexes struct { - client *Client -} - -func newClientIndexes(client *Client) clientIndexes { - return clientIndexes{client: client} -} - -func (c clientIndexes) Get(uid string) (resp *Index, err error) { - resp = &Index{} - req := internalRequest{ - endpoint: "/indexes/" + uid, - method: http.MethodGet, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "Get", - apiName: "Indexes", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - return resp, nil -} - -func (c clientIndexes) List() (resp []Index, err error) { - resp = []Index{} - - req := internalRequest{ - endpoint: "/indexes", - method: http.MethodGet, - withRequest: nil, - withResponse: &resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "List", - apiName: "Indexes", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - return resp, nil -} - -func (c clientIndexes) Create(request CreateIndexRequest) (resp *CreateIndexResponse, err error) { - resp = &CreateIndexResponse{} - req := internalRequest{ - endpoint: "/indexes", - method: http.MethodPost, - withRequest: request, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusCreated}, - functionName: "Create", - apiName: "Indexes", - } - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientIndexes) UpdateName(uid string, name string) (resp *Index, err error) { - resp = &Index{} - req := internalRequest{ - endpoint: "/indexes/" + uid, - method: http.MethodPut, - withRequest: &Name{Name: name}, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "UpdateName", - apiName: "Indexes", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientIndexes) UpdatePrimaryKey(uid string, primaryKey string) (resp *Index, err error) { - resp = &Index{} - req := internalRequest{ - endpoint: "/indexes/" + uid, - method: http.MethodPut, - withRequest: &PrimaryKey{PrimaryKey: primaryKey}, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "UpdatePrimaryKey", - apiName: "Indexes", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientIndexes) Delete(uid string) (ok bool, err error) { - req := internalRequest{ - endpoint: "/indexes/" + uid, - method: http.MethodDelete, - withRequest: nil, - withResponse: nil, - acceptedStatusCodes: []int{http.StatusNoContent}, - functionName: "Delete", - apiName: "Indexes", - } - - // err is not nil if status code is not 204 StatusNoContent - if err := c.client.executeRequest(req); err != nil { - return false, err - } - - return true, nil -} diff --git a/client_indexes_test.go b/client_indexes_test.go deleted file mode 100644 index ef848f06..00000000 --- a/client_indexes_test.go +++ /dev/null @@ -1,125 +0,0 @@ -package meilisearch - -import ( - "testing" -) - -func TestClientIndexes_Create(t *testing.T) { - var indexUID = "TestClientIndexes_Create" - - resp, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - if resp.UID != "TestClientIndexes_Create" { - t.Fatal("response index does not have the same index") - } -} - -func TestClientIndexes_Get(t *testing.T) { - var indexUID = "TestClientIndexes_Get" - - resp, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - i, err := client.Indexes().Get(resp.UID) - if err != nil { - t.Fatal(err) - } - - if i.Name != resp.Name { - t.Fatal("index name not eq", i.Name, resp.Name) - } -} - -func TestClientIndexes_Delete(t *testing.T) { - var indexUID = "TestClientIndexes_Delete" - - resp, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - ok, err := client.Indexes().Delete(resp.UID) - if err != nil { - t.Fatal(err) - } - if !ok { - t.Fatal("delete fail") - } -} - -func TestClientIndexes_List(t *testing.T) { - var indexUID = "TestClientIndexes_List" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - list, err := client.Indexes().List() - if err != nil { - t.Fatal(err) - } - - if len(list) == 0 { - t.Fatal("len of indexes should be at list 1, found ", len(list)) - } -} - -func TestClientIndexes_UpdateName(t *testing.T) { - var indexUID = "TestClientIndexes_UpdateName" - - resp, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - update, err := client.Indexes().UpdateName(resp.UID, "TestClientIndexes_Update2") - if err != nil { - t.Fatal(err) - } - - if update.Name != "TestClientIndexes_Update2" { - t.Fatal("name of the index should be TestClientIndexes_Update2, found ", update.Name) - } -} - -func TestClientIndexes_UpdatePrimaryKey(t *testing.T) { - var indexUID = "TestClientIndexes_UpdatePrimaryKey" - - resp, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - update, err := client.Indexes().UpdatePrimaryKey(resp.UID, "identifier") - if err != nil { - t.Fatal(err) - } - - if update.PrimaryKey != "identifier" { - t.Fatal("name of the index should be TestClientIndexes_Update2, found ", update.Name) - } -} diff --git a/client_keys.go b/client_keys.go deleted file mode 100644 index cacfee38..00000000 --- a/client_keys.go +++ /dev/null @@ -1,29 +0,0 @@ -package meilisearch - -import "net/http" - -type clientKeys struct { - client *Client -} - -func newClientKeys(client *Client) clientKeys { - return clientKeys{client: client} -} - -func (c clientKeys) Get() (resp *Keys, err error) { - resp = &Keys{} - req := internalRequest{ - endpoint: "/keys", - method: http.MethodGet, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "Get", - apiName: "Keys", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - return resp, nil -} diff --git a/client_keys_test.go b/client_keys_test.go deleted file mode 100644 index 8cacf851..00000000 --- a/client_keys_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package meilisearch - -import ( - "testing" -) - -func TestClientKeys_Get(t *testing.T) { - if _, err := client.Keys().Get(); err != nil { - t.Fatal(err) - } -} diff --git a/client_request.go b/client_request.go new file mode 100644 index 00000000..657ac6d3 --- /dev/null +++ b/client_request.go @@ -0,0 +1,160 @@ +package meilisearch + +import ( + "net/url" + + "github.com/pkg/errors" + "github.com/valyala/fasthttp" + + "encoding/json" +) + +type internalRequest struct { + endpoint string + method string + + withRequest interface{} + withResponse interface{} + withQueryParams map[string]string + + acceptedStatusCodes []int + + functionName string +} + +func (c *Client) executeRequest(req internalRequest) error { + internalError := &Error{ + Endpoint: req.endpoint, + Method: req.method, + Function: req.functionName, + RequestToString: "empty request", + ResponseToString: "empty response", + MeilisearchMessage: "empty meilisearch message", + StatusCodeExpected: req.acceptedStatusCodes, + } + + response := fasthttp.AcquireResponse() + defer fasthttp.ReleaseResponse(response) + err := c.sendRequest(&req, internalError, response) + if err != nil { + return err + } + internalError.StatusCode = response.StatusCode() + + err = c.handleStatusCode(&req, response, internalError) + if err != nil { + return err + } + + err = c.handleResponse(&req, response, internalError) + if err != nil { + return err + } + return nil +} + +func (c *Client) sendRequest(req *internalRequest, internalError *Error, response *fasthttp.Response) error { + var ( + request *fasthttp.Request + + err error + ) + + // Setup URL + requestURL, err := url.Parse(c.config.Host + req.endpoint) + if err != nil { + return errors.Wrap(err, "unable to parse url") + } + + // Build query parameters + if req.withQueryParams != nil { + query := requestURL.Query() + for key, value := range req.withQueryParams { + query.Set(key, value) + } + + requestURL.RawQuery = query.Encode() + } + + request = fasthttp.AcquireRequest() + defer fasthttp.ReleaseRequest(request) + + request.SetRequestURI(requestURL.String()) + request.Header.SetMethod(req.method) + + if req.withRequest != nil { + + // A json request is mandatory, so the request interface{} need to be passed as a raw json body. + rawJSONRequest := req.withRequest + var data []byte + var err error + if raw, ok := rawJSONRequest.(json.Marshaler); ok { + data, err = raw.MarshalJSON() + } else { + data, err = json.Marshal(rawJSONRequest) + } + internalError.RequestToString = string(data) + if err != nil { + return internalError.WithErrCode(ErrCodeMarshalRequest, err) + } + request.SetBody(data) + } + + // adding request headers + request.Header.Set("Content-Type", "application/json") + if c.config.MasterKey != "" { + request.Header.Set("X-Meili-API-Key", c.config.MasterKey) + } + + // request is sent + err = c.httpClient.Do(request, response) + + // request execution fail + if err != nil { + return internalError.WithErrCode(ErrCodeRequestExecution, err) + } + + return nil +} + +func (c *Client) handleStatusCode(req *internalRequest, response *fasthttp.Response, internalError *Error) error { + if req.acceptedStatusCodes != nil { + + // A successful status code is required so check if the response status code is in the + // expected status code list. + for _, acceptedCode := range req.acceptedStatusCodes { + if response.StatusCode() == acceptedCode { + return nil + } + } + // At this point the response status code is a failure. + rawBody := response.Body() + + internalError.ErrorBody(rawBody) + + return internalError.WithErrCode(ErrCodeResponseStatusCode) + } + + return nil +} + +func (c *Client) handleResponse(req *internalRequest, response *fasthttp.Response, internalError *Error) (err error) { + if req.withResponse != nil { + + // A json response is mandatory, so the response interface{} need to be unmarshal from the response payload. + rawBody := response.Body() + internalError.ResponseToString = string(rawBody) + + var err error + if resp, ok := req.withResponse.(json.Unmarshaler); ok { + err = resp.UnmarshalJSON(rawBody) + req.withResponse = resp + } else { + err = json.Unmarshal(rawBody, req.withResponse) + } + if err != nil { + return internalError.WithErrCode(ErrCodeResponseUnmarshalBody, err) + } + } + return nil +} diff --git a/client_search_test.go b/client_search_test.go deleted file mode 100644 index 86620989..00000000 --- a/client_search_test.go +++ /dev/null @@ -1,329 +0,0 @@ -package meilisearch - -import ( - "fmt" - "testing" -) - -func TestClientSearch_Search(t *testing.T) { - var indexUID = "TestClientSearch_Search" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - booksTest := []docTestBooks{ - {BookID: 123, Title: "Pride and Prejudice", Tag: "Nice book"}, - {BookID: 456, Title: "Le Petit Prince", Tag: "Nice book"}, - {BookID: 1, Title: "Alice In Wonderland", Tag: "Nice book"}, - {BookID: 1344, Title: "The Hobbit", Tag: "Nice book"}, - {BookID: 4, Title: "Harry Potter and the Half-Blood Prince", Tag: "Interesting book"}, - {BookID: 42, Title: "The Hitchhiker's Guide to the Galaxy", Tag: "Interesting book"}, - {BookID: 24, Title: "You are a princess", Tag: "Interesting book"}, - } - - updateIDRes, err := client. - Documents(indexUID). - AddOrUpdate(booksTest) - - if err != nil { - t.Fatal(err) - } - - client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - // Test basic search - - resp, err := client.Search(indexUID).Search(SearchRequest{ - Query: "prince", - }) - - if err != nil { - t.Fatal(err) - } - - if len(resp.Hits) != 3 { - fmt.Println(resp) - t.Fatal("Basic search: number of hits should be equal to 3") - } - title := resp.Hits[0].(map[string]interface{})["title"] - if title != booksTest[1].Title { - fmt.Println(resp) - t.Fatalf("Basic search: should have found %s\n", booksTest[1].Title) - } - if resp.NbHits != 3 { - fmt.Println(resp) - t.Fatalf("Basic search: wrong number of hits, should have 3, got %d\n", resp.NbHits) - } - - // Test basic empty search - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "", - }) - - if err != nil { - t.Fatal(err) - } - - if len(resp.Hits) != len(booksTest) { - fmt.Println(resp) - t.Fatal("Basic placeholder search with an empty string: should return placeholder results") - } - - // Test basic placeholder search - - resp, err = client.Search(indexUID).Search(SearchRequest{ - PlaceholderSearch: true, - }) - - if err != nil { - t.Fatal(err) - } - - if len(resp.Hits) != len(booksTest) { - fmt.Println(resp) - t.Fatal("Basic placeholder search with no Query: should return placeholder results") - } - - // Test basic search with limit - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "prince", - Limit: 1, - }) - - if err != nil { - t.Fatal(err) - } - - if len(resp.Hits) != 1 { - fmt.Println(resp) - t.Fatal("Search offset: number of hits should be equal to 1") - } - title = resp.Hits[0].(map[string]interface{})["title"] - if title != booksTest[1].Title { - fmt.Println(resp) - t.Fatalf("Basic search: should have found %s\n", booksTest[1].Title) - } - - // Test basic placeholder search with limit - - resp, err = client.Search(indexUID).Search(SearchRequest{ - PlaceholderSearch: true, - Limit: 3, - }) - - if err != nil { - t.Fatal(err) - } - - if len(resp.Hits) != 3 { - fmt.Println(resp) - t.Fatal("Basic placeholder search with limit: should return 3 results") - } - - // Test basic search with offset - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "prince", - Offset: 1, - }) - - if err != nil { - t.Fatal(err) - } - - if len(resp.Hits) != 2 { - fmt.Println(resp) - t.Fatal("number of hits should be equal to 2") - } - retrievedTitles := []string{ - fmt.Sprint(resp.Hits[0].(map[string]interface{})["title"]), - fmt.Sprint(resp.Hits[1].(map[string]interface{})["title"]), - } - expectedTitles := []string{ - booksTest[4].Title, - booksTest[6].Title, - } - - for title := range expectedTitles { - found := false - for retrievedTitle := range retrievedTitles { - if title == retrievedTitle { - found = true - break - } - } - if !found { - fmt.Println(resp) - t.Fatal("Search offset: should have found 'Harry Potter and the Half-Blood Prince'") - } - } - - // Test basic search with attributesToRetrieve - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "prince", - AttributesToRetrieve: []string{"book_id", "title"}, - }) - - if err != nil { - t.Fatal(err) - } - - if resp.Hits[0].(map[string]interface{})["title"] == nil { - fmt.Println(resp) - t.Fatal("attributesToRetrieve: Couldn't retrieve field in response") - } - if resp.Hits[0].(map[string]interface{})["tag"] != nil { - fmt.Println(resp) - t.Fatal("attributesToRetrieve: Retrieve unrequested field in response") - } - - // Test basic search with attributesToCrop - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "to", - AttributesToCrop: []string{"title"}, - CropLength: 7, - }) - - if err != nil { - t.Fatal(err) - } - - if resp.Hits[0].(map[string]interface{})["title"] == nil { - fmt.Println(resp) - t.Fatal("attributesToCrop: Couldn't retrieve field in response") - } - formatted := resp.Hits[0].(map[string]interface{})["_formatted"] - if formatted.(map[string]interface{})["title"] != "Guide to the" { - fmt.Println(resp) - t.Fatal("attributesToCrop: CropLength didn't work as expected") - } - - // Test basic search with filters - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "and", - Filters: "tag = \"Nice book\"", - }) - - if err != nil { - t.Fatal(err) - } - - if len(resp.Hits) != 1 { - fmt.Println(resp) - t.Fatal("filters: Unable to filter properly") - } - if resp.Hits[0].(map[string]interface{})["title"] != "Pride and Prejudice" { - fmt.Println(resp) - t.Fatal("filters: Unable to filter properly") - } - - // Test basic search with matches - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "and", - Matches: true, - }) - - if err != nil { - t.Fatal(err) - } - - if resp.Hits[0].(map[string]interface{})["_matchesInfo"] == nil { - fmt.Println(resp) - t.Fatal("matches: Mathes info not found") - } - - // Test basic search with facetsDistribution - - r2, err := client.Settings(indexUID).UpdateAttributesForFaceting([]string{"tag"}) - - if err != nil { - t.Fatal(err) - } - - client.DefaultWaitForPendingUpdate(indexUID, r2) - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "prince", - FacetsDistribution: []string{"*"}, - }) - - if err != nil { - t.Fatal(err) - } - - tagCount := resp.FacetsDistribution.(map[string]interface{})["tag"] - - if len(tagCount.(map[string]interface{})) != 2 { - fmt.Println(tagCount.(map[string]interface{})) - t.Fatal("facetsDistribution: Wrong count of facet options") - } - - if tagCount.(map[string]interface{})["Interesting book"] != float64(2) { - fmt.Println(tagCount.(map[string]interface{})["Interesting book"]) - t.Fatal("facetsDistribution: Wrong count on facetDistribution") - } - - r2, _ = client.Settings(indexUID).ResetAttributesForFaceting() - client.DefaultWaitForPendingUpdate(indexUID, r2) - - // Test basic search with facetFilters - - r2, err = client.Settings(indexUID).UpdateAttributesForFaceting([]string{"tag", "title"}) - - if err != nil { - t.Fatal(err) - } - - client.DefaultWaitForPendingUpdate(indexUID, r2) - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "prince", - FacetFilters: []string{"tag:interesting book"}, - }) - if err != nil { - fmt.Println("Error:", err) - } - - if len(resp.Hits) != 2 { - fmt.Println(resp) - t.Fatal("facetsFilters: Error on single attribute facet search") - } - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "prince", - FacetFilters: []string{"tag:interesting book", "tag:nice book"}, - }) - if err != nil { - fmt.Println("Error:", err) - } - - if len(resp.Hits) != 0 { - fmt.Println(resp) - t.Fatal("facetsFilters: Error on 'AND' in attribute facet search") - } - - resp, err = client.Search(indexUID).Search(SearchRequest{ - Query: "prince", - FacetFilters: [][]string{{"tag:interesting book", "tag:nice book"}}, - }) - if err != nil { - fmt.Println("Error:", err) - } - - if len(resp.Hits) != 3 { - fmt.Println(resp) - t.Fatal("facetsFilters: Error on 'OR' in attribute facet search") - } - -} diff --git a/client_settings_test.go b/client_settings_test.go deleted file mode 100644 index a091d0de..00000000 --- a/client_settings_test.go +++ /dev/null @@ -1,631 +0,0 @@ -package meilisearch - -import ( - "fmt" - "github.com/stretchr/testify/assert" - "reflect" - "testing" -) - -func TestClientSettings_GetAll(t *testing.T) { - var indexUID = "TestClientSettings_GetAll" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - settingsRes, err := client.Settings(indexUID).GetAll() - - if err != nil { - t.Fatal(err) - } - - expected := Settings{ - RankingRules: []string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"}, - DistinctAttribute: nil, - SearchableAttributes: []string{"*"}, - DisplayedAttributes: []string{"*"}, - StopWords: []string{}, - Synonyms: map[string][]string(nil), - AttributesForFaceting: []string{}, - } - - assert.Equal(t, *settingsRes, expected) -} - -func TestClientSettings_UpdateAll(t *testing.T) { - var indexUID = "TestClientSettings_UpdateAll" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - settings := Settings{ - RankingRules: []string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"}, - SearchableAttributes: []string{"id", "title", "description"}, - DisplayedAttributes: []string{"id", "title", "description"}, - StopWords: []string{"a", "the"}, - Synonyms: map[string][]string{ - "car": {"automobile"}, - }, - AttributesForFaceting: []string{"title"}, - } - - updateIDRes, err := client.Settings(indexUID).UpdateAll(settings) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) -} - -func TestClientSettings_ResetAll(t *testing.T) { - var indexUID = "TestClientSettings_ResetAll" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).ResetAll() - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - -} - -func TestClientSettings_GetRankingRules(t *testing.T) { - var indexUID = "TestClientSettings_GetRankingRules" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - rankingRulesRes, err := client.Settings(indexUID).GetRankingRules() - - if err != nil { - t.Fatal(err) - } - - expected := []string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"} - - assert.Equal(t, expected, *rankingRulesRes) -} - -func TestClientSettings_UpdateRankingRules(t *testing.T) { - var indexUID = "TestClientSettings_UpdateRankingRules" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - rankingRules := []string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"} - - updateIDRes, err := client.Settings(indexUID).UpdateRankingRules(rankingRules) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) -} - -func TestClientSettings_ResetRankingRules(t *testing.T) { - var indexUID = "TestClientSettings_ResetRankingRules" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).ResetRankingRules() - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) -} - -func TestClientSettings_GetDistinctAttribute(t *testing.T) { - var indexUID = "TestClientSettings_GetDistinctAttribute" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - distinctAttributeRes, err := client.Settings(indexUID).GetDistinctAttribute() - - if err != nil { - t.Fatal(err) - } - - assert.Empty(t, *distinctAttributeRes) -} - -func TestClientSettings_UpdateDistinctAttribute(t *testing.T) { - var indexUID = "TestClientSettings_UpdateDistinctAttribute" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).UpdateDistinctAttribute("skuid") - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - -} - -func TestClientSettings_ResetDistinctAttribute(t *testing.T) { - var indexUID = "TestClientSettings_ResetDistinctAttribute" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).ResetDistinctAttribute() - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - -} - -func TestClientSettings_GetSearchableAttributes(t *testing.T) { - var indexUID = "TestClientSettings_GetSearchableAttributes" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - searchableAttributesRes, err := client.Settings(indexUID).GetSearchableAttributes() - - if err != nil { - t.Fatal(err) - } - - if len(*searchableAttributesRes) != 1 { - t.Fatal("Wrong response for searchableAttributes") - } - - searchableAttibutesString := *searchableAttributesRes - expectedSearchableAttributesString := "*" - - if searchableAttibutesString[0] != expectedSearchableAttributesString { - t.Fatalf( - "Wrong response for searchableAttributes, expected %s, got %s\n", - searchableAttibutesString, - expectedSearchableAttributesString, - ) - } -} - -func TestClientSettings_UpdateSearchableAttributes(t *testing.T) { - var indexUID = "TestClientSettings_UpdateSearchableAttributes" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - searchableAttributes := []string{"id", "title", "description"} - - updateIDRes, err := client.Settings(indexUID).UpdateSearchableAttributes(searchableAttributes) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) -} - -func TestClientSettings_ResetSearchableAttributes(t *testing.T) { - var indexUID = "TestClientSettings_ResetSearchableAttributes" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).ResetSearchableAttributes() - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - searchableAttributesRes, err := client.Settings(indexUID).GetSearchableAttributes() - - if err != nil { - t.Fatal(err) - } - - if len(*searchableAttributesRes) != 1 { - t.Fatal("Wrong response for searchableAttributes after reset") - } - - searchableAttibutesString := *searchableAttributesRes - expectedSearchableAttributesString := "*" - - if searchableAttibutesString[0] != expectedSearchableAttributesString { - t.Fatalf( - "Wrong response for searchableAttributes after reset, expected %s, got %s\n", - searchableAttibutesString, - expectedSearchableAttributesString, - ) - } -} - -func TestClientSettings_GetDisplayedAttributes(t *testing.T) { - var indexUID = "TestClientSettings_GetDisplayedAttributes" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - displayedAttributesRes, err := client.Settings(indexUID).GetDisplayedAttributes() - - if err != nil { - t.Fatal(err) - } - - if len(*displayedAttributesRes) != 1 { - t.Fatal("Wrong response for displayedAttributes") - } - - displayedAttributesString := *displayedAttributesRes - expecteddisplayedAttrributesString := "*" - - if displayedAttributesString[0] != expecteddisplayedAttrributesString { - t.Fatalf( - "Wrong response for displayedAttributes, expected %s, got %s\n", - displayedAttributesString, - expecteddisplayedAttrributesString, - ) - } -} - -func TestClientSettings_UpdateDisplayedAttributes(t *testing.T) { - var indexUID = "TestClientSettings_UpdateDisplayedAttributes" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - displayedAttributes := []string{"id", "title", "description"} - - updateIDRes, err := client.Settings(indexUID).UpdateDisplayedAttributes(displayedAttributes) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) -} - -func TestClientSettings_ResetDisplayedAttributes(t *testing.T) { - var indexUID = "TestClientSettings_ResetDisplayedAttributes" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).ResetDisplayedAttributes() - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - - displayedAttributesRes, err := client.Settings(indexUID).GetDisplayedAttributes() - - if err != nil { - t.Fatal(err) - } - - if len(*displayedAttributesRes) != 1 { - t.Fatal("Wrong response for displayedAttributes after reset") - } - - displayedAttributesString := *displayedAttributesRes - expecteddisplayedAttrributesString := "*" - - if displayedAttributesString[0] != expecteddisplayedAttrributesString { - t.Fatalf( - "Wrong response for displayedAttributes after reset, expected %s, got %s\n", - displayedAttributesString, - expecteddisplayedAttrributesString, - ) - } -} - -func TestClientSettings_GetStopWords(t *testing.T) { - var indexUID = "TestClientSettings_GetStopWords" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - stopWordsRes, err := client.Settings(indexUID).GetStopWords() - - if err != nil { - t.Fatal(err) - } - - if len(*stopWordsRes) > 0 { - t.Fatal("The response body is not good") - } - -} - -func TestClientSettings_UpdateStopWords(t *testing.T) { - var indexUID = "TestClientSettings_UpdateStopWords" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - stopWords := []string{"a", "the"} - - updateIDRes, err := client.Settings(indexUID).UpdateStopWords(stopWords) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - -} - -func TestClientSettings_ResetStopWords(t *testing.T) { - var indexUID = "TestClientSettings_ResetStopWords" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).ResetStopWords() - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - -} - -func TestClientSettings_GetSynonyms(t *testing.T) { - var indexUID = "TestClientSettings_GetSynonyms" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - synonymsRes, err := client.Settings(indexUID).GetSynonyms() - - if err != nil { - t.Fatal(err) - } - - if len(*synonymsRes) > 0 { - t.Fatal("The response body is not good") - } - -} - -func TestClientSettings_UpdateSynonyms(t *testing.T) { - var indexUID = "TestClientSettings_UpdateSynonyms" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - synonyms := map[string][]string{ - "car": {"automobile"}, - } - - updateIDRes, err := client.Settings(indexUID).UpdateSynonyms(synonyms) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) -} - -func TestClientSettings_ResetSynonyms(t *testing.T) { - var indexUID = "TestClientSettings_ResetSynonyms" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).ResetSynonyms() - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - -} - -func TestClientSettings_GetAttributesForFaceting(t *testing.T) { - var indexUID = "TestClientSettings_GetAttributesForFaceting" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - AttributesForFacetingRes, err := client.Settings(indexUID).GetAttributesForFaceting() - - if err != nil { - t.Fatal(err) - } - - if reflect.DeepEqual(*AttributesForFacetingRes, nil) { - t.Fatal("getAttributesForFaceting: Error getting attributesForFaceting on empty index") - } -} - -func TestClientSettings_UpdateAttributesForFaceting(t *testing.T) { - var indexUID = "TestClientSettings_UpdateAttributesForFaceting" - - attributesForFaceting := []string{"tag", "title"} - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).UpdateAttributesForFaceting(attributesForFaceting) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - r, _ := client.Settings(indexUID).GetAttributesForFaceting() - if !reflect.DeepEqual(*r, attributesForFaceting) { - fmt.Println(*r) - t.Fatal("updateAttributesForFaceting: Error getting attributesForFaceting after update") - } -} - -func TestClientSettings_ResetAttributesForFaceting(t *testing.T) { - var indexUID = "TestClientSettings_ResetAttributesForFaceting" - - attributesForFaceting := []string{"tag", "title"} - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - updateIDRes, err := client.Settings(indexUID).UpdateAttributesForFaceting(attributesForFaceting) - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - r, _ := client.Settings(indexUID).GetAttributesForFaceting() - if !reflect.DeepEqual(*r, attributesForFaceting) { - fmt.Println(*r) - t.Fatal("resetAttributesForFaceting: Error getting attributesForFaceting after update") - } - - updateIDRes, err = client.Settings(indexUID).ResetAttributesForFaceting() - - if err != nil { - t.Fatal(err) - } - - _, _ = client.DefaultWaitForPendingUpdate(indexUID, updateIDRes) - r, _ = client.Settings(indexUID).GetAttributesForFaceting() - if reflect.DeepEqual(*r, nil) { - t.Fatal("resetAttributesForFaceting: Error getting attributesForFaceting after reset") - } -} diff --git a/client_stats.go b/client_stats.go deleted file mode 100644 index c1135014..00000000 --- a/client_stats.go +++ /dev/null @@ -1,49 +0,0 @@ -package meilisearch - -import "net/http" - -type clientStats struct { - client *Client -} - -func newClientStats(client *Client) clientStats { - return clientStats{client: client} -} - -func (c clientStats) Get(indexUID string) (resp *StatsIndex, err error) { - resp = &StatsIndex{} - req := internalRequest{ - endpoint: "/indexes/" + indexUID + "/stats", - method: http.MethodGet, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "Get", - apiName: "Stats", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientStats) GetAll() (resp *Stats, err error) { - resp = &Stats{} - req := internalRequest{ - endpoint: "/stats", - method: http.MethodGet, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "Get", - apiName: "Stats", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} diff --git a/client_stats_test.go b/client_stats_test.go deleted file mode 100644 index 7a67ce85..00000000 --- a/client_stats_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package meilisearch - -import ( - "testing" -) - -func TestClientStats_Get(t *testing.T) { - if _, err := client.Stats().GetAll(); err != nil { - t.Fatal(err) - } - - var indexUID = "TestClientStats_Get" - - if _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }); err != nil { - t.Fatal(err) - } - - if _, err := client.Stats().Get(indexUID); err != nil { - t.Fatal(err) - } -} diff --git a/client_test.go b/client_test.go new file mode 100644 index 00000000..959464ac --- /dev/null +++ b/client_test.go @@ -0,0 +1,231 @@ +package meilisearch + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/valyala/fasthttp" +) + +func TestClient_Version(t *testing.T) { + tests := []struct { + name string + client *Client + }{ + { + name: "TestVersion", + client: defaultClient, + }, + { + name: "TestVersionWithCustomClient", + client: customClient, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotResp, err := tt.client.GetVersion() + require.NoError(t, err) + require.NotNil(t, gotResp, "Version() should not return nil value") + }) + } +} + +func TestClient_GetAllStats(t *testing.T) { + tests := []struct { + name string + client *Client + }{ + { + name: "TestGetAllStats", + client: defaultClient, + }, + { + name: "TestGetAllStatsWithCustomClient", + client: customClient, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotResp, err := tt.client.GetAllStats() + require.NoError(t, err) + require.NotNil(t, gotResp, "GetAllStats() should not return nil value") + }) + } +} + +func TestClient_GetKeys(t *testing.T) { + tests := []struct { + name string + client *Client + }{ + { + name: "TestGetKeys", + client: defaultClient, + }, + { + name: "TestGetKeysWithCustomClient", + client: defaultClient, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotResp, err := tt.client.GetKeys() + require.NoError(t, err) + require.NotNil(t, gotResp, "GetKeys() should not return nil value") + }) + } +} + +func TestClient_Health(t *testing.T) { + tests := []struct { + name string + client *Client + wantResp *Health + wantErr bool + }{ + { + name: "TestHealth", + client: defaultClient, + wantResp: &Health{ + Status: "available", + }, + wantErr: false, + }, + { + name: "TestHealthWithCustomClient", + client: customClient, + wantResp: &Health{ + Status: "available", + }, + wantErr: false, + }, + { + name: "TestHealthWIthBadUrl", + client: &Client{ + config: ClientConfig{ + Host: "http://wrongurl:1234", + MasterKey: masterKey, + }, + httpClient: &fasthttp.Client{ + Name: "meilsearch-client", + }, + }, + wantResp: nil, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotResp, err := tt.client.Health() + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp, "Health() got response %v, want %v", gotResp, tt.wantResp) + } + }) + } +} + +func TestClient_IsHealthy(t *testing.T) { + tests := []struct { + name string + client *Client + want bool + }{ + { + name: "TestIsHealthy", + client: defaultClient, + want: true, + }, + { + name: "TestIsHealthyWithCustomClient", + client: customClient, + want: true, + }, + { + name: "TestIsHealthyWIthBadUrl", + client: &Client{ + config: ClientConfig{ + Host: "http://wrongurl:1234", + MasterKey: masterKey, + }, + httpClient: &fasthttp.Client{ + Name: "meilsearch-client", + }, + }, + want: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.client.IsHealthy() + require.Equal(t, tt.want, got, "IsHealthy() got response %v, want %v", got, tt.want) + }) + } +} + +func TestClient_CreateDump(t *testing.T) { + tests := []struct { + name string + client *Client + wantResp *Dump + }{ + { + name: "TestCreateDump", + client: defaultClient, + wantResp: &Dump{ + Status: "in_progress", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.client + + gotResp, err := c.CreateDump() + require.NoError(t, err) + if assert.NotNil(t, gotResp, "CreateDump() should not return nil value") { + require.Equal(t, tt.wantResp.Status, gotResp.Status, "CreateDump() got response status %v, want: %v", gotResp.Status, tt.wantResp.Status) + } + + // Waiting for CreateDump() to finished + for { + gotResp, _ := c.GetDumpStatus(gotResp.UID) + if gotResp.Status == "done" { + break + } + } + }) + } +} + +func TestClient_GetDumpStatus(t *testing.T) { + tests := []struct { + name string + client *Client + wantResp []string + wantErr bool + }{ + { + name: "TestGetDumpStatus", + client: defaultClient, + wantResp: []string{"in_progress", "failed", "done"}, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.client + + dump, err := c.CreateDump() + require.NoError(t, err, "CreateDump() in TestGetDumpStatus error should be nil") + + gotResp, err := c.GetDumpStatus(dump.UID) + require.NoError(t, err) + require.Contains(t, tt.wantResp, gotResp.Status, "GetDumpStatus() got response status %v", gotResp.Status) + require.NotEqual(t, "failed", gotResp.Status, "GetDumpStatus() response status should not be failed") + }) + } +} diff --git a/client_updates.go b/client_updates.go deleted file mode 100644 index 82793d70..00000000 --- a/client_updates.go +++ /dev/null @@ -1,63 +0,0 @@ -package meilisearch - -import ( - "net/http" - "strconv" -) - -type clientUpdates struct { - client *Client - indexUID string -} - -func newClientUpdates(client *Client, indexUID string) clientUpdates { - return clientUpdates{client: client, indexUID: indexUID} -} - -func (c clientUpdates) Get(id int64) (resp *Update, err error) { - resp = &Update{} - - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/updates/" + strconv.FormatInt(id, 10), - method: http.MethodGet, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "Get", - apiName: "Updates", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientUpdates) List() (resp []Update, err error) { - resp = []Update{} - - req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/updates", - method: http.MethodGet, - withRequest: nil, - withResponse: &resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "List", - apiName: "Updates", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} - -func (c clientUpdates) IndexID() string { - return c.indexUID -} - -func (c clientUpdates) Client() ClientInterface { - return c.client -} diff --git a/client_updates_test.go b/client_updates_test.go deleted file mode 100644 index 1323e8a9..00000000 --- a/client_updates_test.go +++ /dev/null @@ -1,21 +0,0 @@ -package meilisearch - -import ( - "testing" -) - -func TestClientUpdates_List(t *testing.T) { - var indexUID = "TestClientUpdates_List" - - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: indexUID, - }) - - if err != nil { - t.Fatal(err) - } - - if _, err := client.Updates(indexUID).List(); err != nil { - t.Fatal(err) - } -} diff --git a/client_version.go b/client_version.go deleted file mode 100644 index 65c0dfbf..00000000 --- a/client_version.go +++ /dev/null @@ -1,31 +0,0 @@ -package meilisearch - -import "net/http" - -type clientVersion struct { - client *Client -} - -func newClientVersion(client *Client) clientVersion { - return clientVersion{client: client} -} - -func (c clientVersion) Get() (resp *Version, err error) { - resp = &Version{} - - req := internalRequest{ - endpoint: "/version", - method: http.MethodGet, - withRequest: nil, - withResponse: resp, - acceptedStatusCodes: []int{http.StatusOK}, - functionName: "Get", - apiName: "Version", - } - - if err := c.client.executeRequest(req); err != nil { - return nil, err - } - - return resp, nil -} diff --git a/client_version_test.go b/client_version_test.go deleted file mode 100644 index 0e9326d7..00000000 --- a/client_version_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package meilisearch - -import ( - "testing" -) - -func TestClientVersion_Get(t *testing.T) { - if _, err := client.Version().Get(); err != nil { - t.Fatal(err) - } -} diff --git a/index.go b/index.go new file mode 100644 index 00000000..68da8ef3 --- /dev/null +++ b/index.go @@ -0,0 +1,220 @@ +package meilisearch + +import ( + "context" + "net/http" + "strconv" + "time" +) + +// IndexConfig configure the Index +type IndexConfig struct { + + // Host is the host of your meilisearch database + // Example: 'http://localhost:7700' + Uid string + + // PrimaryKey is optional + PrimaryKey string + + client *Client +} + +type IndexInterface interface { + FetchInfo() (resp *Index, err error) + FetchPrimaryKey() (resp *string, err error) + UpdateIndex(primaryKey string) (resp *Index, err error) + Delete(uid string) (ok bool, err error) + GetStats() (resp *StatsIndex, err error) + + AddDocuments(documentsPtr interface{}) (resp *AsyncUpdateID, err error) + UpdateDocuments(documentsPtr interface{}) (resp *AsyncUpdateID, err error) + AddDocumentsWithPrimaryKey(documentsPtr interface{}, primaryKey string) (resp *AsyncUpdateID, err error) + UpdateDocumentsWithPrimaryKey(documentsPtr interface{}, primaryKey string) (resp *AsyncUpdateID, err error) + GetDocument(uid string, documentPtr interface{}) error + GetDocuments(request *DocumentsRequest, resp interface{}) error + DeleteDocument(uid string) (resp *AsyncUpdateID, err error) + DeleteDocuments(uid []string) (resp *AsyncUpdateID, err error) + DeleteAllDocuments() (resp *AsyncUpdateID, err error) + Search(query string, request *SearchRequest) (*SearchResponse, error) + + GetUpdateStatus(updateID int64) (resp *Update, err error) + GetAllUpdateStatus() (resp *[]Update, err error) + + GetSettings() (resp *Settings, err error) + UpdateSettings(request *Settings) (resp *AsyncUpdateID, err error) + ResetSettings() (resp *AsyncUpdateID, err error) + GetRankingRules() (resp *[]string, err error) + UpdateRankingRules(request *[]string) (resp *AsyncUpdateID, err error) + ResetRankingRules() (resp *AsyncUpdateID, err error) + GetDistinctAttribute() (resp *string, err error) + UpdateDistinctAttribute(request string) (resp *AsyncUpdateID, err error) + ResetDistinctAttribute() (resp *AsyncUpdateID, err error) + GetSearchableAttributes() (resp *[]string, err error) + UpdateSearchableAttributes(request *[]string) (resp *AsyncUpdateID, err error) + ResetSearchableAttributes() (resp *AsyncUpdateID, err error) + GetDisplayedAttributes() (resp *[]string, err error) + UpdateDisplayedAttributes(request *[]string) (resp *AsyncUpdateID, err error) + ResetDisplayedAttributes() (resp *AsyncUpdateID, err error) + GetStopWords() (resp *[]string, err error) + UpdateStopWords(request *[]string) (resp *AsyncUpdateID, err error) + ResetStopWords() (resp *AsyncUpdateID, err error) + GetSynonyms() (resp *map[string][]string, err error) + UpdateSynonyms(request *map[string][]string) (resp *AsyncUpdateID, err error) + ResetSynonyms() (resp *AsyncUpdateID, err error) + GetAttributesForFaceting() (resp *[]string, err error) + UpdateAttributesForFaceting(request *[]string) (resp *AsyncUpdateID, err error) + ResetAttributesForFaceting() (resp *AsyncUpdateID, err error) + + WaitForPendingUpdate(ctx context.Context, interval time.Duration, updateID *AsyncUpdateID) (UpdateStatus, error) + DefaultWaitForPendingUpdate(updateID *AsyncUpdateID) (UpdateStatus, error) +} + +var _ IndexInterface = &Index{} + +func newIndex(client *Client, uid string) *Index { + return &Index{ + UID: uid, + client: client, + } +} + +func (i Index) FetchInfo() (resp *Index, err error) { + resp = newIndex(i.client, i.UID) + req := internalRequest{ + endpoint: "/indexes/" + i.UID, + method: http.MethodGet, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "FetchInfo", + } + if err := i.client.executeRequest(req); err != nil { + return nil, err + } + i.PrimaryKey = resp.PrimaryKey + return resp, nil +} + +func (i Index) FetchPrimaryKey() (resp *string, err error) { + index, err := i.FetchInfo() + if err != nil { + return nil, err + } + return &index.PrimaryKey, nil +} + +func (i Index) UpdateIndex(primaryKey string) (resp *Index, err error) { + request := &UpdateIndexRequest{ + PrimaryKey: primaryKey, + } + i.PrimaryKey = primaryKey + + req := internalRequest{ + endpoint: "/indexes/" + i.UID, + method: http.MethodPut, + withRequest: request, + withResponse: &i, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "UpdateIndex", + } + if err := i.client.executeRequest(req); err != nil { + return nil, err + } + return &i, nil +} + +func (i Index) Delete(uid string) (ok bool, err error) { + req := internalRequest{ + endpoint: "/indexes/" + uid, + method: http.MethodDelete, + withRequest: nil, + withResponse: nil, + acceptedStatusCodes: []int{http.StatusNoContent}, + functionName: "Delete", + } + // err is not nil if status code is not 204 StatusNoContent + if err := i.client.executeRequest(req); err != nil { + return false, err + } + return true, nil +} + +func (i Index) GetStats() (resp *StatsIndex, err error) { + resp = &StatsIndex{} + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/stats", + method: http.MethodGet, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetStats", + } + if err := i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (i Index) GetUpdateStatus(updateID int64) (resp *Update, err error) { + resp = &Update{} + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/updates/" + strconv.FormatInt(updateID, 10), + method: http.MethodGet, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetUpdateStatus", + } + if err := i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (i Index) GetAllUpdateStatus() (resp *[]Update, err error) { + resp = &[]Update{} + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/updates", + method: http.MethodGet, + withRequest: nil, + withResponse: &resp, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetAllUpdateStatus", + } + if err := i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +// DefaultWaitForPendingUpdate checks each 50ms the status of a WaitForPendingUpdate. +// This is a default implementation of WaitForPendingUpdate. +func (i Index) DefaultWaitForPendingUpdate(updateID *AsyncUpdateID) (UpdateStatus, error) { + ctx, cancelFunc := context.WithTimeout(context.Background(), time.Second*5) + defer cancelFunc() + return i.WaitForPendingUpdate(ctx, time.Millisecond*50, updateID) +} + +// WaitForPendingUpdate waits for the end of an update. +// The function will check by regular interval provided in parameter interval +// the UpdateStatus. If it is not UpdateStatusEnqueued or the ctx cancelled +// we return the UpdateStatus. +func (i Index) WaitForPendingUpdate( + ctx context.Context, + interval time.Duration, + updateID *AsyncUpdateID) (UpdateStatus, error) { + for { + if err := ctx.Err(); err != nil { + return "", err + } + update, err := i.GetUpdateStatus(updateID.UpdateID) + if err != nil { + return UpdateStatusUnknown, nil + } + if update.Status != UpdateStatusEnqueued { + return update.Status, nil + } + time.Sleep(interval) + } +} diff --git a/index_documents.go b/index_documents.go new file mode 100644 index 00000000..c394c41e --- /dev/null +++ b/index_documents.go @@ -0,0 +1,162 @@ +package meilisearch + +import ( + "net/http" + "strconv" + "strings" +) + +func (i Index) GetDocument(identifier string, documentPtr interface{}) error { + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents/" + identifier, + method: http.MethodGet, + withRequest: nil, + withResponse: documentPtr, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetDocument", + } + if err := i.client.executeRequest(req); err != nil { + return err + } + return nil +} + +func (i Index) GetDocuments(request *DocumentsRequest, resp interface{}) error { + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents", + method: http.MethodGet, + withRequest: request, + withResponse: resp, + withQueryParams: map[string]string{}, + acceptedStatusCodes: []int{http.StatusOK}, + functionName: "GetDocuments", + } + if request.Limit != 0 { + req.withQueryParams["limit"] = strconv.FormatInt(request.Limit, 10) + } + if request.Offset != 0 { + req.withQueryParams["offset"] = strconv.FormatInt(request.Offset, 10) + } + if len(request.AttributesToRetrieve) != 0 { + req.withQueryParams["attributesToRetrieve"] = strings.Join(request.AttributesToRetrieve, ",") + } + if err := i.client.executeRequest(req); err != nil { + return err + } + return nil +} + +func (i Index) AddDocuments(documentsPtr interface{}) (resp *AsyncUpdateID, err error) { + resp = &AsyncUpdateID{} + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents", + method: http.MethodPost, + withRequest: documentsPtr, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusAccepted}, + functionName: "AddDocuments", + } + if err = i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (i Index) AddDocumentsWithPrimaryKey(documentsPtr interface{}, primaryKey string) (resp *AsyncUpdateID, err error) { + resp = &AsyncUpdateID{} + i.PrimaryKey = primaryKey + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents?primaryKey=" + primaryKey, + method: http.MethodPost, + withRequest: documentsPtr, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusAccepted}, + functionName: "AddDocumentsWithPrimaryKey", + } + if err = i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (i Index) UpdateDocuments(documentsPtr interface{}) (*AsyncUpdateID, error) { + var err error + resp := &AsyncUpdateID{} + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents", + method: http.MethodPut, + withRequest: documentsPtr, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusAccepted}, + functionName: "UpdateDocuments", + } + if err = i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (i Index) UpdateDocumentsWithPrimaryKey(documentsPtr interface{}, primaryKey string) (resp *AsyncUpdateID, err error) { + resp = &AsyncUpdateID{} + i.PrimaryKey = primaryKey + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents?primaryKey=" + primaryKey, + method: http.MethodPut, + withRequest: documentsPtr, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusAccepted}, + functionName: "UpdateDocumentsWithPrimaryKey", + } + if err = i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (i Index) DeleteDocument(identifier string) (resp *AsyncUpdateID, err error) { + resp = &AsyncUpdateID{} + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents/" + identifier, + method: http.MethodDelete, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusAccepted}, + functionName: "DeleteDocument", + } + if err := i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (i Index) DeleteDocuments(identifier []string) (resp *AsyncUpdateID, err error) { + resp = &AsyncUpdateID{} + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents/delete-batch", + method: http.MethodPost, + withRequest: identifier, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusAccepted}, + functionName: "DeleteDocuments", + } + if err := i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} + +func (i Index) DeleteAllDocuments() (resp *AsyncUpdateID, err error) { + resp = &AsyncUpdateID{} + req := internalRequest{ + endpoint: "/indexes/" + i.UID + "/documents", + method: http.MethodDelete, + withRequest: nil, + withResponse: resp, + acceptedStatusCodes: []int{http.StatusAccepted}, + functionName: "DeleteAllDocuments", + } + if err = i.client.executeRequest(req); err != nil { + return nil, err + } + return resp, nil +} diff --git a/index_documents_test.go b/index_documents_test.go new file mode 100644 index 00000000..297f3b61 --- /dev/null +++ b/index_documents_test.go @@ -0,0 +1,790 @@ +package meilisearch + +import ( + "strconv" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIndex_AddDocuments(t *testing.T) { + type args struct { + UID string + client *Client + documentsPtr interface{} + } + tests := []struct { + name string + args args + wantResp *AsyncUpdateID + }{ + { + name: "TestIndexBasicAddDocuments", + args: args{ + UID: "1", + client: defaultClient, + documentsPtr: []map[string]interface{}{ + {"ID": "123", "Name": "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexAddDocumentsWithCustomClient", + args: args{ + UID: "1", + client: customClient, + documentsPtr: []map[string]interface{}{ + {"ID": "123", "Name": "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexMultipleAddDocuments", + args: args{ + UID: "2", + client: defaultClient, + documentsPtr: []map[string]interface{}{ + {"ID": "123", "Name": "Pride and Prejudice"}, + {"ID": "456", "Name": "Le Petit Prince"}, + {"ID": "1", "Name": "Alice In Wonderland"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexBasicAddDocumentsWithIntID", + args: args{ + UID: "1", + client: defaultClient, + documentsPtr: []map[string]interface{}{ + {"BookID": float64(123), "Title": "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexAddDocumentsWithIntIDWithCustomClient", + args: args{ + UID: "1", + client: customClient, + documentsPtr: []map[string]interface{}{ + {"BookID": float64(123), "Title": "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexMultipleAddDocumentsWithIntID", + args: args{ + UID: "2", + client: defaultClient, + documentsPtr: []map[string]interface{}{ + {"BookID": float64(123), "Title": "Pride and Prejudice"}, + {"BookID": float64(456), "Title": "Le Petit Prince", "Tag": "Conte"}, + {"BookID": float64(1), "Title": "Alice In Wonderland"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.AddDocuments(tt.args.documentsPtr) + require.GreaterOrEqual(t, gotResp.UpdateID, tt.wantResp.UpdateID) + require.NoError(t, err) + i.DefaultWaitForPendingUpdate(gotResp) + + var documents []map[string]interface{} + i.GetDocuments(&DocumentsRequest{ + Limit: 3, + }, &documents) + require.Equal(t, tt.args.documentsPtr, documents) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_AddDocumentsWithPrimaryKey(t *testing.T) { + type args struct { + UID string + client *Client + documentsPtr interface{} + primaryKey string + } + tests := []struct { + name string + args args + wantResp *AsyncUpdateID + }{ + { + name: "TestIndexBasicAddDocumentsWithPrimaryKey", + args: args{ + UID: "1", + client: defaultClient, + documentsPtr: []map[string]interface{}{ + {"key": "123", "Name": "Pride and Prejudice"}, + }, + primaryKey: "key", + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexAddDocumentsWithPrimaryKeyWithCustomClient", + args: args{ + UID: "1", + client: customClient, + documentsPtr: []map[string]interface{}{ + {"key": "123", "Name": "Pride and Prejudice"}, + }, + primaryKey: "key", + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexMultipleAddDocumentsWithPrimaryKey", + args: args{ + UID: "2", + client: defaultClient, + documentsPtr: []map[string]interface{}{ + {"key": "123", "Name": "Pride and Prejudice"}, + {"key": "456", "Name": "Le Petit Prince"}, + {"key": "1", "Name": "Alice In Wonderland"}, + }, + primaryKey: "key", + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexAddDocumentsWithPrimaryKeyWithIntID", + args: args{ + UID: "1", + client: defaultClient, + documentsPtr: []map[string]interface{}{ + {"key": float64(123), "Name": "Pride and Prejudice"}, + }, + primaryKey: "key", + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexMultipleAddDocumentsWithPrimaryKeyWithIntID", + args: args{ + UID: "2", + client: defaultClient, + documentsPtr: []map[string]interface{}{ + {"key": float64(123), "Name": "Pride and Prejudice"}, + {"key": float64(456), "Name": "Le Petit Prince"}, + {"key": float64(1), "Name": "Alice In Wonderland"}, + }, + primaryKey: "key", + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.AddDocumentsWithPrimaryKey(tt.args.documentsPtr, tt.args.primaryKey) + require.GreaterOrEqual(t, gotResp.UpdateID, tt.wantResp.UpdateID) + require.NoError(t, err) + i.DefaultWaitForPendingUpdate(gotResp) + + var documents []map[string]interface{} + i.GetDocuments(&DocumentsRequest{ + Limit: 3, + }, &documents) + require.Equal(t, tt.args.documentsPtr, documents) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_DeleteAllDocuments(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantResp *AsyncUpdateID + }{ + { + name: "TestIndexBasicDeleteAllDocuments", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexDeleteAllDocumentsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + SetUpBasicIndex() + gotResp, err := i.DeleteAllDocuments() + require.NoError(t, err) + require.Equal(t, gotResp, tt.wantResp) + i.DefaultWaitForPendingUpdate(gotResp) + + var documents interface{} + i.GetDocuments(&DocumentsRequest{ + Limit: 5, + }, &documents) + require.Empty(t, documents) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_DeleteOneDocument(t *testing.T) { + type args struct { + UID string + PrimaryKey string + client *Client + identifier string + documentsPtr interface{} + } + tests := []struct { + name string + args args + wantResp *AsyncUpdateID + }{ + { + name: "TestIndexBasicDeleteOneDocument", + args: args{ + UID: "1", + client: defaultClient, + identifier: "123", + documentsPtr: []map[string]interface{}{ + {"ID": "123", "Name": "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexDeleteOneDocumentWithCustomClient", + args: args{ + UID: "1", + client: customClient, + identifier: "123", + documentsPtr: []map[string]interface{}{ + {"ID": "123", "Name": "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexDeleteOneDocumentinMultiple", + args: args{ + UID: "2", + client: defaultClient, + identifier: "456", + documentsPtr: []map[string]interface{}{ + {"ID": "123", "Name": "Pride and Prejudice"}, + {"ID": "456", "Name": "Le Petit Prince"}, + {"ID": "1", "Name": "Alice In Wonderland"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexBasicDeleteOneDocumentWithIntID", + args: args{ + UID: "1", + client: defaultClient, + identifier: "123", + documentsPtr: []map[string]interface{}{ + {"BookID": 123, "Title": "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexDeleteOneDocumentWithIntIDWithCustomClient", + args: args{ + UID: "1", + client: customClient, + identifier: "123", + documentsPtr: []map[string]interface{}{ + {"BookID": 123, "Title": "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + { + name: "TestIndexDeleteOneDocumentWithIntIDinMultiple", + args: args{ + UID: "2", + client: defaultClient, + identifier: "456", + documentsPtr: []map[string]interface{}{ + {"BookID": 123, "Title": "Pride and Prejudice"}, + {"BookID": 456, "Title": "Le Petit Prince"}, + {"BookID": 1, "Title": "Alice In Wonderland"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 0, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + gotAddResp, err := i.AddDocuments(tt.args.documentsPtr) + require.GreaterOrEqual(t, gotAddResp.UpdateID, tt.wantResp.UpdateID) + require.NoError(t, err) + i.DefaultWaitForPendingUpdate(gotAddResp) + + gotResp, err := i.DeleteDocument(tt.args.identifier) + require.NoError(t, err) + require.GreaterOrEqual(t, gotResp.UpdateID, tt.wantResp.UpdateID) + i.DefaultWaitForPendingUpdate(gotResp) + + var document []map[string]interface{} + err = i.GetDocument(tt.args.identifier, &document) + require.Empty(t, document) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_DeleteDocuments(t *testing.T) { + type args struct { + UID string + client *Client + identifier []string + documentsPtr []docTest + } + tests := []struct { + name string + args args + wantResp *AsyncUpdateID + }{ + { + name: "TestIndexBasicDeleteDocument", + args: args{ + UID: "1", + client: defaultClient, + identifier: []string{"123"}, + documentsPtr: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexDeleteDocumentWithCustomClient", + args: args{ + UID: "1", + client: customClient, + identifier: []string{"123"}, + documentsPtr: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexBasicDeleteDocument", + args: args{ + UID: "1", + client: defaultClient, + identifier: []string{"123"}, + documentsPtr: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + {ID: "456", Name: "Le Petit Prince"}, + {ID: "1", Name: "Alice In Wonderland"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexBasicDeleteDocument", + args: args{ + UID: "1", + client: defaultClient, + identifier: []string{"123", "456", "1"}, + documentsPtr: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + {ID: "456", Name: "Le Petit Prince"}, + {ID: "1", Name: "Alice In Wonderland"}, + }, + }, + wantResp: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + gotAddResp, err := i.AddDocuments(tt.args.documentsPtr) + require.NoError(t, err) + i.DefaultWaitForPendingUpdate(gotAddResp) + + gotResp, err := i.DeleteDocuments(tt.args.identifier) + require.NoError(t, err) + require.Equal(t, gotResp, tt.wantResp) + i.DefaultWaitForPendingUpdate(gotResp) + + var document docTest + for _, identifier := range tt.args.identifier { + err = i.GetDocument(identifier, &document) + require.Empty(t, document) + } + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_GetDocument(t *testing.T) { + type args struct { + UID string + client *Client + identifier string + documentPtr *docTestBooks + } + tests := []struct { + name string + args args + wantErr bool + }{ + { + name: "TestIndexBasicGetDocument", + args: args{ + UID: "indexUID", + client: defaultClient, + identifier: "123", + documentPtr: &docTestBooks{}, + }, + wantErr: false, + }, + { + name: "TestIndexGetDocumentWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + identifier: "123", + documentPtr: &docTestBooks{}, + }, + wantErr: false, + }, + { + name: "TestIndexGetDocumentWithNoExistingDocument", + args: args{ + UID: "indexUID", + client: defaultClient, + identifier: "125", + documentPtr: &docTestBooks{}, + }, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + SetUpBasicIndex() + + require.Empty(t, tt.args.documentPtr) + err := i.GetDocument(tt.args.identifier, tt.args.documentPtr) + if tt.wantErr { + require.Error(t, err) + require.Empty(t, tt.args.documentPtr) + } else { + require.NoError(t, err) + require.NotEmpty(t, tt.args.documentPtr) + require.Equal(t, strconv.Itoa(tt.args.documentPtr.BookID), tt.args.identifier) + } + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateDocuments(t *testing.T) { + type args struct { + UID string + client *Client + documentsPtr []docTestBooks + } + tests := []struct { + name string + args args + want *AsyncUpdateID + }{ + { + name: "TestIndexBasicUpdateDocument", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 123, Title: "One Hundred Years of Solitude"}, + }, + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDocumentWithCustomClient", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 123, Title: "One Hundred Years of Solitude"}, + }, + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDocumentOnMultipleDocuments", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 123, Title: "One Hundred Years of Solitude"}, + {BookID: 1344, Title: "Harry Potter and the Half-Blood Prince"}, + {BookID: 4, Title: "The Hobbit"}, + {BookID: 42, Title: "The Great Gatsby"}, + }, + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDocumentWithNoExistingDocument", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 237, Title: "One Hundred Years of Solitude"}, + }, + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDocumentWithNoExistingMultipleDocuments", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 246, Title: "One Hundred Years of Solitude"}, + {BookID: 834, Title: "To Kill a Mockingbird"}, + {BookID: 44, Title: "Don Quixote"}, + {BookID: 594, Title: "The Great Gatsby"}, + }, + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + SetUpBasicIndex() + + got, err := i.UpdateDocuments(tt.args.documentsPtr) + require.NoError(t, err) + require.Equal(t, got, tt.want) + i.DefaultWaitForPendingUpdate(got) + + var document docTestBooks + for _, identifier := range tt.args.documentsPtr { + err = i.GetDocument(strconv.Itoa(identifier.BookID), &document) + require.Equal(t, identifier.BookID, document.BookID) + require.Equal(t, identifier.Title, document.Title) + } + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateDocumentsWithPrimaryKey(t *testing.T) { + type args struct { + UID string + client *Client + documentsPtr []docTestBooks + primaryKey string + } + tests := []struct { + name string + args args + want *AsyncUpdateID + }{ + { + name: "TestIndexBasicUpdateDocumentsWithPrimaryKey", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 123, Title: "One Hundred Years of Solitude"}, + }, + primaryKey: "book_id", + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDocumentsWithPrimaryKeyWithCustomClient", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 123, Title: "One Hundred Years of Solitude"}, + }, + primaryKey: "book_id", + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDocumentsWithPrimaryKeyOnMultipleDocuments", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 123, Title: "One Hundred Years of Solitude"}, + {BookID: 1344, Title: "Harry Potter and the Half-Blood Prince"}, + {BookID: 4, Title: "The Hobbit"}, + {BookID: 42, Title: "The Great Gatsby"}, + }, + primaryKey: "book_id", + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDocumentsWithPrimaryKeyWithNoExistingDocument", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 237, Title: "One Hundred Years of Solitude"}, + }, + primaryKey: "book_id", + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDocumentsWithPrimaryKeyWithNoExistingMultipleDocuments", + args: args{ + UID: "indexUID", + client: defaultClient, + documentsPtr: []docTestBooks{ + {BookID: 246, Title: "One Hundred Years of Solitude"}, + {BookID: 834, Title: "To Kill a Mockingbird"}, + {BookID: 44, Title: "Don Quixote"}, + {BookID: 594, Title: "The Great Gatsby"}, + }, + primaryKey: "book_id", + }, + want: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + SetUpBasicIndex() + + got, err := i.UpdateDocumentsWithPrimaryKey(tt.args.documentsPtr, tt.args.primaryKey) + require.NoError(t, err) + require.Equal(t, got, tt.want) + i.DefaultWaitForPendingUpdate(got) + + var document docTestBooks + for _, identifier := range tt.args.documentsPtr { + err = i.GetDocument(strconv.Itoa(identifier.BookID), &document) + require.Equal(t, identifier.BookID, document.BookID) + require.Equal(t, identifier.Title, document.Title) + } + + deleteAllIndexes(c) + }) + } +} diff --git a/client_search.go b/index_search.go similarity index 69% rename from client_search.go rename to index_search.go index 7aa4e42f..04c3f5d9 100644 --- a/client_search.go +++ b/index_search.go @@ -4,27 +4,33 @@ import ( "net/http" ) -type clientSearch struct { - client *Client - indexUID string -} - -func newClientSearch(client *Client, indexUID string) clientSearch { - return clientSearch{client: client, indexUID: indexUID} -} - -func (c clientSearch) Search(request SearchRequest) (*SearchResponse, error) { +// This constant contains the default values assigned by meilisearch to the limit in search parameters +// +// Documentation: https://docs.meilisearch.com/reference/features/search_parameters.html +const ( + DefaultLimit int64 = 20 +) +func (i Index) Search(query string, request *SearchRequest) (*SearchResponse, error) { resp := &SearchResponse{} searchPostRequestParams := map[string]interface{}{} if request.Limit == 0 { - request.Limit = 20 + request.Limit = DefaultLimit } if !request.PlaceholderSearch { - searchPostRequestParams["q"] = request.Query + searchPostRequestParams["q"] = query + } + if request.Limit != DefaultLimit { + searchPostRequestParams["limit"] = request.Limit + } + if request.Matches { + searchPostRequestParams["matches"] = request.Matches + } + if request.FacetFilters != nil { + searchPostRequestParams["facetFilters"] = request.FacetFilters } if request.Filters != "" { searchPostRequestParams["filters"] = request.Filters @@ -32,9 +38,6 @@ func (c clientSearch) Search(request SearchRequest) (*SearchResponse, error) { if request.Offset != 0 { searchPostRequestParams["offset"] = request.Offset } - if request.Limit != 20 { - searchPostRequestParams["limit"] = request.Limit - } if request.CropLength != 0 { searchPostRequestParams["cropLength"] = request.CropLength } @@ -47,37 +50,22 @@ func (c clientSearch) Search(request SearchRequest) (*SearchResponse, error) { if len(request.AttributesToHighlight) != 0 { searchPostRequestParams["attributesToHighlight"] = request.AttributesToHighlight } - if request.Matches { - searchPostRequestParams["matches"] = request.Matches - } if len(request.FacetsDistribution) != 0 { searchPostRequestParams["facetsDistribution"] = request.FacetsDistribution } - if request.FacetFilters != nil { - searchPostRequestParams["facetFilters"] = request.FacetFilters - } req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/search", + endpoint: "/indexes/" + i.UID + "/search", method: http.MethodPost, withRequest: searchPostRequestParams, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, functionName: "Search", - apiName: "Search", } - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } - -func (c clientSearch) IndexID() string { - return c.indexUID -} - -func (c clientSearch) Client() ClientInterface { - return c.client -} diff --git a/index_search_test.go b/index_search_test.go new file mode 100644 index 00000000..7cdf1605 --- /dev/null +++ b/index_search_test.go @@ -0,0 +1,465 @@ +package meilisearch + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIndex_Search(t *testing.T) { + type args struct { + UID string + PrimaryKey string + client *Client + query string + request SearchRequest + } + tests := []struct { + name string + args args + want *SearchResponse + }{ + { + name: "TestIndexBasicSearch", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "prince", + request: SearchRequest{}, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(456), "title": "Le Petit Prince", + }, + map[string]interface{}{ + "Tag": "Epic fantasy", "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 2, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + query: "prince", + request: SearchRequest{}, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(456), "title": "Le Petit Prince", + }, + map[string]interface{}{ + "Tag": "Epic fantasy", "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 2, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithLimit", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "prince", + request: SearchRequest{ + Limit: 1, + }, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(456), "title": "Le Petit Prince", + }, + }, + NbHits: 2, + Offset: 0, + Limit: 1, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithPlaceholderSearch", + args: args{ + UID: "indexUID", + client: defaultClient, + request: SearchRequest{ + PlaceholderSearch: true, + Limit: 1, + }, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(123), "title": "Pride and Prejudice", + }, + }, + NbHits: 20, + Offset: 0, + Limit: 1, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithOffset", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "prince", + request: SearchRequest{ + Offset: 1, + }, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 2, + Offset: 1, + Limit: 20, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithAttributeToRetrieve", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "prince", + request: SearchRequest{ + AttributesToRetrieve: []string{"book_id", "title"}, + }, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(456), "title": "Le Petit Prince", + }, + map[string]interface{}{ + "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 2, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithAttributesToCrop", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "to", + request: SearchRequest{ + AttributesToCrop: []string{"title"}, + CropLength: 7, + }, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(42), "title": "The Hitchhiker's Guide to the Galaxy", + }, + }, + NbHits: 1, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithFilters", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "and", + request: SearchRequest{ + Filters: "tag = \"Romance\"", + }, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(123), "title": "Pride and Prejudice", + }, + }, + NbHits: 1, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithMatches", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "and", + request: SearchRequest{ + Matches: true, + }, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(123), "title": "Pride and Prejudice", + }, + map[string]interface{}{ + "book_id": float64(730), "title": "War and Peace", + }, + map[string]interface{}{ + "book_id": float64(1032), "title": "Crime and Punishment", + }, + map[string]interface{}{ + "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 4, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + }, + }, + { + name: "TestIndexSearchWithAttributeToHighlight", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "prince", + request: SearchRequest{ + AttributesToHighlight: []string{"*"}, + Filters: "book_id > 10", + }, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(456), "title": "Le Petit Prince", + }, + }, + NbHits: 1, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + got, err := i.Search(tt.args.query, &tt.args.request) + require.NoError(t, err) + require.Equal(t, len(tt.want.Hits), len(got.Hits)) + for len := range got.Hits { + require.Equal(t, tt.want.Hits[len].(map[string]interface{})["title"], got.Hits[len].(map[string]interface{})["title"]) + require.Equal(t, tt.want.Hits[len].(map[string]interface{})["book_id"], got.Hits[len].(map[string]interface{})["book_id"]) + } + require.Equal(t, tt.want.NbHits, got.NbHits) + require.Equal(t, tt.want.Offset, got.Offset) + require.Equal(t, tt.want.Limit, got.Limit) + require.Equal(t, tt.want.ExhaustiveNbHits, got.ExhaustiveNbHits) + require.Equal(t, tt.want.FacetsDistribution, got.FacetsDistribution) + require.Equal(t, tt.want.ExhaustiveFacetsCount, got.ExhaustiveFacetsCount) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_SearchFacets(t *testing.T) { + type args struct { + UID string + PrimaryKey string + client *Client + query string + request SearchRequest + facet []string + } + tests := []struct { + name string + args args + want *SearchResponse + }{ + { + name: "TestIndexSearchWithFacetsDistribution", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "prince", + request: SearchRequest{ + FacetsDistribution: []string{"*"}, + }, + facet: []string{"tag"}, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(456), "title": "Le Petit Prince", + }, + map[string]interface{}{ + "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 2, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + FacetsDistribution: map[string]interface{}( + map[string]interface{}{ + "tag": map[string]interface{}{ + "Crime fiction": float64(0), + "Epic": float64(0), + "Epic fantasy": float64(1), + "Historical fiction": float64(0), + "Modernist literature": float64(0), + "Novel": float64(0), + "Tale": float64(1), + "Romance": float64(0), + "Satiric": float64(0), + "Tragedy": float64(0), + }, + }), + ExhaustiveFacetsCount: interface{}(true), + }, + }, + { + name: "TestIndexSearchWithFacetsDistributionWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + query: "prince", + request: SearchRequest{ + FacetsDistribution: []string{"*"}, + }, + facet: []string{"tag"}, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(456), "title": "Le Petit Prince", + }, + map[string]interface{}{ + "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 2, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + FacetsDistribution: map[string]interface{}( + map[string]interface{}{ + "tag": map[string]interface{}{ + "Crime fiction": float64(0), + "Epic": float64(0), + "Epic fantasy": float64(1), + "Historical fiction": float64(0), + "Modernist literature": float64(0), + "Novel": float64(0), + "Tale": float64(1), + "Romance": float64(0), + "Satiric": float64(0), + "Tragedy": float64(0), + }, + }), + ExhaustiveFacetsCount: interface{}(true), + }, + }, + { + name: "TestIndexSearchWithFacetsDistributionWithTag", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "prince", + request: SearchRequest{ + FacetFilters: []string{"tag:Epic fantasy"}, + }, + facet: []string{"tag", "title"}, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 1, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + FacetsDistribution: nil, + ExhaustiveFacetsCount: interface{}(nil), + }, + }, + { + name: "TestIndexSearchWithFacetsDistributionWithTagAndOneFacet", + args: args{ + UID: "indexUID", + client: defaultClient, + query: "prince", + request: SearchRequest{ + FacetFilters: []string{"tag:Epic fantasy"}, + }, + facet: []string{"tag"}, + }, + want: &SearchResponse{ + Hits: []interface{}{ + map[string]interface{}{ + "book_id": float64(4), "title": "Harry Potter and the Half-Blood Prince", + }, + }, + NbHits: 1, + Offset: 0, + Limit: 20, + ExhaustiveNbHits: false, + FacetsDistribution: nil, + ExhaustiveFacetsCount: interface{}(nil), + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + update, _ := i.UpdateAttributesForFaceting(&tt.args.facet) + i.DefaultWaitForPendingUpdate(update) + + got, err := i.Search(tt.args.query, &tt.args.request) + require.NoError(t, err) + require.Equal(t, len(tt.want.Hits), len(got.Hits)) + for len := range got.Hits { + require.Equal(t, tt.want.Hits[len].(map[string]interface{})["title"], got.Hits[len].(map[string]interface{})["title"]) + require.Equal(t, tt.want.Hits[len].(map[string]interface{})["book_id"], got.Hits[len].(map[string]interface{})["book_id"]) + } + require.Equal(t, tt.want.NbHits, got.NbHits) + require.Equal(t, tt.want.Offset, got.Offset) + require.Equal(t, tt.want.Limit, got.Limit) + require.Equal(t, tt.want.ExhaustiveNbHits, got.ExhaustiveNbHits) + + require.Equal(t, tt.want.FacetsDistribution, got.FacetsDistribution) + if got.FacetsDistribution != nil { + require.Equal(t, tt.want.FacetsDistribution.(map[string]interface{})["tag"].(map[string]interface{})["Epic fantasy"], got.FacetsDistribution.(map[string]interface{})["tag"].(map[string]interface{})["Epic fantasy"]) + require.Equal(t, tt.want.FacetsDistribution.(map[string]interface{})["tag"].(map[string]interface{})["Tragedy"], got.FacetsDistribution.(map[string]interface{})["tag"].(map[string]interface{})["Tragedy"]) + require.Equal(t, tt.want.FacetsDistribution.(map[string]interface{})["tag"].(map[string]interface{})["Romance"], got.FacetsDistribution.(map[string]interface{})["tag"].(map[string]interface{})["Romance"]) + } + require.Equal(t, tt.want.ExhaustiveFacetsCount, got.ExhaustiveFacetsCount) + + deleteAllIndexes(c) + }) + } +} diff --git a/client_settings.go b/index_settings.go similarity index 51% rename from client_settings.go rename to index_settings.go index c68264dd..ef7a8e45 100644 --- a/client_settings.go +++ b/index_settings.go @@ -4,468 +4,387 @@ import ( "net/http" ) -type clientSettings struct { - client *Client - indexUID string -} - -func newClientSettings(client *Client, indexUID string) clientSettings { - return clientSettings{client: client, indexUID: indexUID} -} - -func (c clientSettings) IndexID() string { - return c.indexUID -} - -func (c clientSettings) Client() ClientInterface { - return c.client -} - -func (c clientSettings) GetAll() (resp *Settings, err error) { +func (i Index) GetSettings() (resp *Settings, err error) { resp = &Settings{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings", + endpoint: "/indexes/" + i.UID + "/settings", method: http.MethodGet, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, - functionName: "GetAll", - apiName: "Settings", + functionName: "GetSettings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } -func (c clientSettings) UpdateAll(request Settings) (resp *AsyncUpdateID, err error) { +func (i Index) UpdateSettings(request *Settings) (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings", + endpoint: "/indexes/" + i.UID + "/settings", method: http.MethodPost, withRequest: &request, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "UpdateAll", - apiName: "Documents", + functionName: "UpdateSettings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) ResetAll() (resp *AsyncUpdateID, err error) { +func (i Index) ResetSettings() (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings", + endpoint: "/indexes/" + i.UID + "/settings", method: http.MethodDelete, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, - functionName: "ResetAll", - apiName: "Documents", + functionName: "ResetSettings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) GetRankingRules() (resp *[]string, err error) { +func (i Index) GetRankingRules() (resp *[]string, err error) { resp = &[]string{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/ranking-rules", + endpoint: "/indexes/" + i.UID + "/settings/ranking-rules", method: http.MethodGet, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, functionName: "GetRankingRules", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } -func (c clientSettings) UpdateRankingRules(request []string) (resp *AsyncUpdateID, err error) { +func (i Index) UpdateRankingRules(request *[]string) (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/ranking-rules", + endpoint: "/indexes/" + i.UID + "/settings/ranking-rules", method: http.MethodPost, withRequest: &request, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "UpdateRankingRules", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) ResetRankingRules() (resp *AsyncUpdateID, err error) { +func (i Index) ResetRankingRules() (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/ranking-rules", + endpoint: "/indexes/" + i.UID + "/settings/ranking-rules", method: http.MethodDelete, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "ResetRankingRules", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) GetDistinctAttribute() (resp *string, err error) { +func (i Index) GetDistinctAttribute() (resp *string, err error) { empty := "" resp = &empty req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/distinct-attribute", + endpoint: "/indexes/" + i.UID + "/settings/distinct-attribute", method: http.MethodGet, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, functionName: "GetDistinctAttribute", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } -func (c clientSettings) UpdateDistinctAttribute(request string) (resp *AsyncUpdateID, err error) { +func (i Index) UpdateDistinctAttribute(request string) (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/distinct-attribute", + endpoint: "/indexes/" + i.UID + "/settings/distinct-attribute", method: http.MethodPost, withRequest: &request, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "UpdateDistinctAttribute", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) ResetDistinctAttribute() (resp *AsyncUpdateID, err error) { +func (i Index) ResetDistinctAttribute() (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/distinct-attribute", + endpoint: "/indexes/" + i.UID + "/settings/distinct-attribute", method: http.MethodDelete, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "ResetDistinctAttribute", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) GetSearchableAttributes() (resp *[]string, err error) { +func (i Index) GetSearchableAttributes() (resp *[]string, err error) { resp = &[]string{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/searchable-attributes", + endpoint: "/indexes/" + i.UID + "/settings/searchable-attributes", method: http.MethodGet, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, functionName: "GetSearchableAttributes", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } -func (c clientSettings) UpdateSearchableAttributes(request []string) (resp *AsyncUpdateID, err error) { +func (i Index) UpdateSearchableAttributes(request *[]string) (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/searchable-attributes", + endpoint: "/indexes/" + i.UID + "/settings/searchable-attributes", method: http.MethodPost, withRequest: &request, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "UpdateSearchableAttributes", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) ResetSearchableAttributes() (resp *AsyncUpdateID, err error) { +func (i Index) ResetSearchableAttributes() (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/searchable-attributes", + endpoint: "/indexes/" + i.UID + "/settings/searchable-attributes", method: http.MethodDelete, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "ResetSearchableAttributes", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) GetDisplayedAttributes() (resp *[]string, err error) { +func (i Index) GetDisplayedAttributes() (resp *[]string, err error) { resp = &[]string{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/displayed-attributes", + endpoint: "/indexes/" + i.UID + "/settings/displayed-attributes", method: http.MethodGet, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, functionName: "GetDisplayedAttributes", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } -func (c clientSettings) UpdateDisplayedAttributes(request []string) (resp *AsyncUpdateID, err error) { +func (i Index) UpdateDisplayedAttributes(request *[]string) (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/displayed-attributes", + endpoint: "/indexes/" + i.UID + "/settings/displayed-attributes", method: http.MethodPost, withRequest: &request, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "UpdateDisplayedAttributes", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) ResetDisplayedAttributes() (resp *AsyncUpdateID, err error) { +func (i Index) ResetDisplayedAttributes() (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/displayed-attributes", + endpoint: "/indexes/" + i.UID + "/settings/displayed-attributes", method: http.MethodDelete, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "ResetDisplayedAttributes", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) GetStopWords() (resp *[]string, err error) { +func (i Index) GetStopWords() (resp *[]string, err error) { resp = &[]string{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/stop-words", + endpoint: "/indexes/" + i.UID + "/settings/stop-words", method: http.MethodGet, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, functionName: "GetStopWords", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } -func (c clientSettings) UpdateStopWords(request []string) (resp *AsyncUpdateID, err error) { +func (i Index) UpdateStopWords(request *[]string) (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/stop-words", + endpoint: "/indexes/" + i.UID + "/settings/stop-words", method: http.MethodPost, withRequest: &request, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "UpdateStopWords", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) ResetStopWords() (resp *AsyncUpdateID, err error) { +func (i Index) ResetStopWords() (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/stop-words", + endpoint: "/indexes/" + i.UID + "/settings/stop-words", method: http.MethodDelete, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "ResetStopWords", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) GetSynonyms() (resp *map[string][]string, err error) { +func (i Index) GetSynonyms() (resp *map[string][]string, err error) { resp = &map[string][]string{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/synonyms", + endpoint: "/indexes/" + i.UID + "/settings/synonyms", method: http.MethodGet, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, functionName: "GetSynonyms", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } -func (c clientSettings) UpdateSynonyms(request map[string][]string) (resp *AsyncUpdateID, err error) { +func (i Index) UpdateSynonyms(request *map[string][]string) (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/synonyms", + endpoint: "/indexes/" + i.UID + "/settings/synonyms", method: http.MethodPost, withRequest: &request, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "UpdateSynonyms", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) ResetSynonyms() (resp *AsyncUpdateID, err error) { +func (i Index) ResetSynonyms() (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/synonyms", + endpoint: "/indexes/" + i.UID + "/settings/synonyms", method: http.MethodDelete, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "ResetSynonyms", - apiName: "Documents", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) GetAttributesForFaceting() (resp *[]string, err error) { +func (i Index) GetAttributesForFaceting() (resp *[]string, err error) { resp = &[]string{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/attributes-for-faceting", + endpoint: "/indexes/" + i.UID + "/settings/attributes-for-faceting", method: http.MethodGet, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusOK}, functionName: "GetAttributesForFaceting", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } return resp, nil } -func (c clientSettings) UpdateAttributesForFaceting(request []string) (resp *AsyncUpdateID, err error) { +func (i Index) UpdateAttributesForFaceting(request *[]string) (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/attributes-for-faceting", + endpoint: "/indexes/" + i.UID + "/settings/attributes-for-faceting", method: http.MethodPost, withRequest: &request, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "UpdateAttributesForFaceting", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } -func (c clientSettings) ResetAttributesForFaceting() (resp *AsyncUpdateID, err error) { +func (i Index) ResetAttributesForFaceting() (resp *AsyncUpdateID, err error) { resp = &AsyncUpdateID{} req := internalRequest{ - endpoint: "/indexes/" + c.indexUID + "/settings/attributes-for-faceting", + endpoint: "/indexes/" + i.UID + "/settings/attributes-for-faceting", method: http.MethodDelete, withRequest: nil, withResponse: resp, acceptedStatusCodes: []int{http.StatusAccepted}, functionName: "ResetAttributesForFaceting", - apiName: "Settings", } - - if err := c.client.executeRequest(req); err != nil { + if err := i.client.executeRequest(req); err != nil { return nil, err } - return resp, nil } diff --git a/index_settings_test.go b/index_settings_test.go new file mode 100644 index 00000000..c896add5 --- /dev/null +++ b/index_settings_test.go @@ -0,0 +1,1788 @@ +package meilisearch + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestIndex_GetAttributesForFaceting(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + }{ + { + name: "TestIndexBasicGetAttributesForFaceting", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + }, + { + name: "TestIndexGetAttributesForFacetingWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetAttributesForFaceting() + require.NoError(t, err) + require.Empty(t, gotResp) + }) + } +} + +func TestIndex_GetDisplayedAttributes(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantResp *[]string + }{ + { + name: "TestIndexBasicGetDisplayedAttributes", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &[]string{"*"}, + }, + { + name: "TestIndexGetDisplayedAttributesWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantResp: &[]string{"*"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetDisplayedAttributes() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_GetDistinctAttribute(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + }{ + { + name: "TestIndexBasicGetDistinctAttribute", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + }, + { + name: "TestIndexBasicGetDistinctAttribute", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetDistinctAttribute() + require.NoError(t, err) + require.Empty(t, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_GetRankingRules(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantResp *[]string + }{ + { + name: "TestIndexBasicGetRankingRules", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &[]string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"}, + }, + { + name: "TestIndexGetRankingRulesWithCustomClient", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &[]string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetRankingRules() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_GetSearchableAttributes(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantResp *[]string + }{ + { + name: "TestIndexBasicGetSearchableAttributes", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &[]string{"*"}, + }, + { + name: "TestIndexGetSearchableAttributesCustomClient", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &[]string{"*"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetSearchableAttributes() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_GetSettings(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantResp *Settings + }{ + { + name: "TestIndexBasicGetSettings", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexGetSettingsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetSettings() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_GetStopWords(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + }{ + { + name: "TestIndexBasicGetStopWords", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + }, + { + name: "TestIndexGetStopWordsCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetStopWords() + require.NoError(t, err) + require.Empty(t, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_GetSynonyms(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + }{ + { + name: "TestIndexBasicGetSynonyms", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + }, + { + name: "TestIndexGetSynonymsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetSynonyms() + require.NoError(t, err) + require.Empty(t, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_ResetAttributesForFaceting(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + }{ + { + name: "TestIndexBasicResetAttributesForFaceting", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexResetAttributesForFacetingCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotUpdate, err := i.ResetAttributesForFaceting() + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err := i.GetAttributesForFaceting() + require.NoError(t, err) + require.Empty(t, gotResp) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_ResetDisplayedAttributes(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *[]string + }{ + { + name: "TestIndexBasicResetDisplayedAttributes", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"*"}, + }, + { + name: "TestIndexResetDisplayedAttributesCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"*"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotUpdate, err := i.ResetDisplayedAttributes() + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err := i.GetDisplayedAttributes() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_ResetDistinctAttribute(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + }{ + { + name: "TestIndexBasicResetDistinctAttribute", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexResetDistinctAttributeWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotUpdate, err := i.ResetDistinctAttribute() + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err := i.GetDistinctAttribute() + require.NoError(t, err) + require.Empty(t, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_ResetRankingRules(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *[]string + }{ + { + name: "TestIndexBasicResetRankingRules", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"}, + }, + { + name: "TestIndexResetRankingRulesWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotUpdate, err := i.ResetRankingRules() + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err := i.GetRankingRules() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_ResetSearchableAttributes(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *[]string + }{ + { + name: "TestIndexBasicResetSearchableAttributes", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"*"}, + }, + { + name: "TestIndexResetSearchableAttributesWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"*"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotUpdate, err := i.ResetSearchableAttributes() + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err := i.GetSearchableAttributes() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_ResetSettings(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *Settings + }{ + { + name: "TestIndexBasicResetSettings", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexResetSettingsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotUpdate, err := i.ResetSettings() + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err := i.GetSettings() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_ResetStopWords(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + }{ + { + name: "TestIndexBasicResetStopWords", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexResetStopWordsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotUpdate, err := i.ResetStopWords() + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err := i.GetStopWords() + require.NoError(t, err) + require.Empty(t, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_ResetSynonyms(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + }{ + { + name: "TestIndexBasicResetSynonyms", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexResetSynonymsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotUpdate, err := i.ResetSynonyms() + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err := i.GetSynonyms() + require.NoError(t, err) + require.Empty(t, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateAttributesForFaceting(t *testing.T) { + type args struct { + UID string + client *Client + request []string + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + }{ + { + name: "TestIndexBasicUpdateAttributesForFaceting", + args: args{ + UID: "indexUID", + client: defaultClient, + request: []string{ + "title", "tag", + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateAttributesForFacetingWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + request: []string{ + "title", "tag", + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetAttributesForFaceting() + require.NoError(t, err) + require.Empty(t, gotResp) + + gotUpdate, err := i.UpdateAttributesForFaceting(&tt.args.request) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetAttributesForFaceting() + require.NoError(t, err) + require.Equal(t, &tt.args.request, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateDisplayedAttributes(t *testing.T) { + type args struct { + UID string + client *Client + request []string + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *[]string + }{ + { + name: "TestIndexBasicUpdateDisplayedAttributes", + args: args{ + UID: "indexUID", + client: defaultClient, + request: []string{ + "book_id", "tag", "title", + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"*"}, + }, + { + name: "TestIndexUpdateDisplayedAttributesWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + request: []string{ + "book_id", "tag", "title", + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"*"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetDisplayedAttributes() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + + gotUpdate, err := i.UpdateDisplayedAttributes(&tt.args.request) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetDisplayedAttributes() + require.NoError(t, err) + require.Equal(t, &tt.args.request, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateDistinctAttribute(t *testing.T) { + type args struct { + UID string + client *Client + request string + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + }{ + { + name: "TestIndexBasicUpdateDistinctAttribute", + args: args{ + UID: "indexUID", + client: defaultClient, + request: "", + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateDistinctAttributeWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + request: "", + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetDistinctAttribute() + require.NoError(t, err) + require.Empty(t, gotResp) + + gotUpdate, err := i.UpdateDistinctAttribute(tt.args.request) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetDistinctAttribute() + require.NoError(t, err) + require.Equal(t, &tt.args.request, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateRankingRules(t *testing.T) { + type args struct { + UID string + client *Client + request []string + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *[]string + }{ + { + name: "TestIndexBasicUpdateRankingRules", + args: args{ + UID: "indexUID", + client: defaultClient, + request: []string{ + "typo", "words", + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"}, + }, + { + name: "TestIndexUpdateRankingRulesWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + request: []string{ + "typo", "words", + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"typo", "words", "proximity", "attribute", "wordsPosition", "exactness"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetRankingRules() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + + gotUpdate, err := i.UpdateRankingRules(&tt.args.request) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetRankingRules() + require.NoError(t, err) + require.Equal(t, &tt.args.request, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateSearchableAttributes(t *testing.T) { + type args struct { + UID string + client *Client + request []string + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *[]string + }{ + { + name: "TestIndexBasicUpdateSearchableAttributes", + args: args{ + UID: "indexUID", + client: defaultClient, + request: []string{ + "title", "tag", + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"*"}, + }, + { + name: "TestIndexUpdateSearchableAttributesWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + request: []string{ + "title", "tag", + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &[]string{"*"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetSearchableAttributes() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + + gotUpdate, err := i.UpdateSearchableAttributes(&tt.args.request) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetSearchableAttributes() + require.NoError(t, err) + require.Equal(t, &tt.args.request, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateSettings(t *testing.T) { + type args struct { + UID string + client *Client + request Settings + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *Settings + }{ + { + name: "TestIndexBasicUpdateSettings", + args: args{ + UID: "indexUID", + client: defaultClient, + request: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{ + "title", "tag", + }, + DisplayedAttributes: []string{ + "book_id", "tag", "title", + }, + StopWords: []string{ + "of", "the", + }, + Synonyms: map[string][]string{ + "hp": {"harry potter"}, + }, + AttributesForFaceting: []string{ + "title", + }, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexUpdateSettingsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + request: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{ + "title", "tag", + }, + DisplayedAttributes: []string{ + "book_id", "tag", "title", + }, + StopWords: []string{ + "of", "the", + }, + Synonyms: map[string][]string{ + "hp": {"harry potter"}, + }, + AttributesForFaceting: []string{ + "title", + }, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetSettings() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + + gotUpdate, err := i.UpdateSettings(&tt.args.request) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetSettings() + require.NoError(t, err) + require.Equal(t, &tt.args.request, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateSettingsOneByOne(t *testing.T) { + type args struct { + UID string + client *Client + firstRequest Settings + firstResponse Settings + secondRequest Settings + secondResponse Settings + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + wantResp *Settings + }{ + { + name: "TestIndexUpdateSynonyms", + args: args{ + UID: "indexUID", + client: defaultClient, + firstRequest: Settings{ + RankingRules: []string{ + "typo", "words", + }, + Synonyms: map[string][]string{ + "hp": {"harry potter"}, + }, + }, + firstResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string{ + "hp": {"harry potter"}, + }, + AttributesForFaceting: []string{}, + }, + secondRequest: Settings{ + Synonyms: map[string][]string{ + "al": {"alice"}, + }, + }, + secondResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string{ + "al": {"alice"}, + }, + AttributesForFaceting: []string{}, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexUpdateSynonymsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + firstRequest: Settings{ + RankingRules: []string{ + "typo", "words", + }, + Synonyms: map[string][]string{ + "hp": {"harry potter"}, + }, + }, + firstResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string{ + "hp": {"harry potter"}, + }, + AttributesForFaceting: []string{}, + }, + secondRequest: Settings{ + Synonyms: map[string][]string{ + "al": {"alice"}, + }, + }, + secondResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string{ + "al": {"alice"}, + }, + AttributesForFaceting: []string{}, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexUpdateJustSearchableAttributes", + args: args{ + UID: "indexUID", + client: defaultClient, + firstRequest: Settings{ + RankingRules: []string{ + "typo", "words", + }, + SearchableAttributes: []string{ + "title", "tag", + }, + }, + firstResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{ + "title", "tag", + }, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + secondRequest: Settings{ + SearchableAttributes: []string{ + "title", + }, + }, + secondResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{ + "title", + }, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexUpdateJustDisplayedAttributes", + args: args{ + UID: "indexUID", + client: defaultClient, + firstRequest: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DisplayedAttributes: []string{ + "book_id", "tag", "title", + }, + }, + firstResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{ + "book_id", "tag", "title", + }, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + secondRequest: Settings{ + DisplayedAttributes: []string{ + "book_id", "tag", + }, + }, + secondResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{ + "book_id", "tag", + }, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexUpdateJustStopWords", + args: args{ + UID: "indexUID", + client: defaultClient, + firstRequest: Settings{ + RankingRules: []string{ + "typo", "words", + }, + StopWords: []string{ + "of", "the", + }, + }, + firstResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{ + "of", "the", + }, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + secondRequest: Settings{ + StopWords: []string{ + "of", "the", + }, + }, + secondResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{ + "of", "the", + }, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexUpdateJustAttributesForFaceting", + args: args{ + UID: "indexUID", + client: defaultClient, + firstRequest: Settings{ + RankingRules: []string{ + "typo", "words", + }, + AttributesForFaceting: []string{ + "title", + }, + }, + firstResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{ + "title", + }, + }, + secondRequest: Settings{ + AttributesForFaceting: []string{ + "title", "tag", + }, + }, + secondResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{ + "title", "tag", + }, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + { + name: "TestIndexUpdateJustAttributesForFaceting", + args: args{ + UID: "indexUID", + client: defaultClient, + firstRequest: Settings{ + RankingRules: []string{ + "typo", "words", + }, + AttributesForFaceting: []string{ + "title", + }, + }, + firstResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{ + "title", + }, + }, + secondRequest: Settings{ + AttributesForFaceting: []string{ + "title", "tag", + }, + }, + secondResponse: Settings{ + RankingRules: []string{ + "typo", "words", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{ + "title", "tag", + }, + }, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + wantResp: &Settings{ + RankingRules: []string{ + "typo", "words", "proximity", "attribute", "wordsPosition", "exactness", + }, + DistinctAttribute: (*string)(nil), + SearchableAttributes: []string{"*"}, + DisplayedAttributes: []string{"*"}, + StopWords: []string{}, + Synonyms: map[string][]string(nil), + AttributesForFaceting: []string{}, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetSettings() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + + gotUpdate, err := i.UpdateSettings(&tt.args.firstRequest) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetSettings() + require.NoError(t, err) + require.Equal(t, &tt.args.firstResponse, gotResp) + + gotUpdate, err = i.UpdateSettings(&tt.args.secondRequest) + require.NoError(t, err) + require.GreaterOrEqual(t, gotUpdate.UpdateID, tt.wantUpdate.UpdateID) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetSettings() + require.NoError(t, err) + require.Equal(t, &tt.args.secondResponse, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateStopWords(t *testing.T) { + type args struct { + UID string + client *Client + request []string + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + }{ + { + name: "TestIndexBasicUpdateStopWords", + args: args{ + UID: "indexUID", + client: defaultClient, + request: []string{}, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateStopWordsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + request: []string{}, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetStopWords() + require.NoError(t, err) + require.Empty(t, gotResp) + + gotUpdate, err := i.UpdateStopWords(&tt.args.request) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetStopWords() + require.NoError(t, err) + require.Equal(t, &tt.args.request, gotResp) + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateSynonyms(t *testing.T) { + type args struct { + UID string + client *Client + request map[string][]string + } + tests := []struct { + name string + args args + wantUpdate *AsyncUpdateID + }{ + { + name: "TestIndexBasicUpdateSynonyms", + args: args{ + UID: "indexUID", + client: defaultClient, + request: map[string][]string{}, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + { + name: "TestIndexUpdateSynonymsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + request: map[string][]string{}, + }, + wantUpdate: &AsyncUpdateID{ + UpdateID: 1, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpIndexForFaceting() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetSynonyms() + require.NoError(t, err) + require.Empty(t, gotResp) + + gotUpdate, err := i.UpdateSynonyms(&tt.args.request) + require.NoError(t, err) + require.Equal(t, tt.wantUpdate, gotUpdate) + i.DefaultWaitForPendingUpdate(gotUpdate) + + gotResp, err = i.GetSynonyms() + require.NoError(t, err) + require.Equal(t, &tt.args.request, gotResp) + deleteAllIndexes(c) + }) + } +} diff --git a/index_test.go b/index_test.go new file mode 100644 index 00000000..c14e70b5 --- /dev/null +++ b/index_test.go @@ -0,0 +1,626 @@ +package meilisearch + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" +) + +func TestIndex_Delete(t *testing.T) { + type args struct { + createUid []string + deleteUid []string + } + tests := []struct { + name string + client *Client + args args + wantOk bool + wantErr bool + }{ + { + name: "TestIndexDeleteOneIndex", + client: defaultClient, + args: args{ + createUid: []string{"1"}, + deleteUid: []string{"1"}, + }, + wantOk: true, + wantErr: false, + }, + { + name: "TestIndexDeleteOneIndexWithCustomClient", + client: customClient, + args: args{ + createUid: []string{"1"}, + deleteUid: []string{"1"}, + }, + wantOk: true, + wantErr: false, + }, + { + name: "TestIndexDeleteMultipleIndex", + client: defaultClient, + args: args{ + createUid: []string{"1", "2", "3", "4", "5"}, + deleteUid: []string{"1", "2", "3", "4", "5"}, + }, + wantOk: true, + wantErr: false, + }, + { + name: "TestIndexDeleteNotExistingIndex", + client: defaultClient, + args: args{ + createUid: []string{}, + deleteUid: []string{"1"}, + }, + wantOk: false, + wantErr: true, + }, + { + name: "TestIndexDeleteMultipleNotExistingIndex", + client: defaultClient, + args: args{ + createUid: []string{}, + deleteUid: []string{"1", "2", "3"}, + }, + wantOk: false, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.client + for _, uid := range tt.args.createUid { + _, err := c.CreateIndex(&IndexConfig{Uid: uid}) + require.NoError(t, err, "CreateIndex() in DeleteTest error should be nil") + } + for _, uid := range tt.args.deleteUid { + i := c.Index(uid) + gotOk, err := i.Delete(uid) + if tt.wantErr { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.wantOk, gotOk) + } + } + }) + } +} + +func TestIndex_GetStats(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantResp *StatsIndex + }{ + { + name: "TestIndexBasicGetStats", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &StatsIndex{ + NumberOfDocuments: 6, + IsIndexing: false, + }, + }, + { + name: "TestIndexGetStatsWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantResp: &StatsIndex{ + NumberOfDocuments: 6, + IsIndexing: false, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpBasicIndex() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.GetStats() + require.NoError(t, err) + require.Equal(t, tt.wantResp, gotResp) + + deleteAllIndexes(c) + }) + } +} + +func Test_newIndex(t *testing.T) { + type args struct { + client *Client + uid string + } + tests := []struct { + name string + args args + want *Index + }{ + { + name: "TestBasicNewIndex", + args: args{ + client: defaultClient, + uid: "TestBasicNewIndex", + }, + want: &Index{ + UID: "TestBasicNewIndex", + client: defaultClient, + }, + }, + { + name: "TestNewIndexCustomClient", + args: args{ + client: customClient, + uid: "TestBasicNewIndex", + }, + want: &Index{ + UID: "TestBasicNewIndex", + client: customClient, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + + got := newIndex(c, tt.args.uid) + require.Equal(t, tt.want.UID, got.UID) + require.Equal(t, tt.want.client, got.client) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_GetUpdateStatus(t *testing.T) { + type args struct { + UID string + client *Client + updateID int64 + document []docTest + } + tests := []struct { + name string + args args + }{ + { + name: "TestBasicGetUpdateStatus", + args: args{ + UID: "1", + client: defaultClient, + updateID: 0, + document: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + }, + }, + }, + { + name: "TestGetUpdateStatusWithCustomClient", + args: args{ + UID: "1", + client: customClient, + updateID: 0, + document: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + }, + }, + }, + { + name: "TestGetUpdateStatus", + args: args{ + UID: "1", + client: defaultClient, + updateID: 1, + document: []docTest{ + {ID: "456", Name: "Le Petit Prince"}, + {ID: "1", Name: "Alice In Wonderland"}, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + update, err := i.AddDocuments(tt.args.document) + require.NoError(t, err) + + gotResp, err := i.GetUpdateStatus(update.UpdateID) + require.NoError(t, err) + require.NotNil(t, gotResp) + require.GreaterOrEqual(t, gotResp.UpdateID, tt.args.updateID) + require.NotNil(t, gotResp.UpdateID) + }) + } + _, _ = deleteAllIndexes(defaultClient) +} + +func TestIndex_GetAllUpdateStatus(t *testing.T) { + type args struct { + UID string + client *Client + document []docTest + } + tests := []struct { + name string + args args + wantResp []Update + }{ + { + name: "TestIndexBasicGetAllUpdateStatus", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: []Update{ + { + Status: "processed", + UpdateID: 0, + Error: "", + }, + }, + }, + { + name: "TestIndexGetAllUpdateStatusWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantResp: []Update{ + { + Status: "processed", + UpdateID: 0, + Error: "", + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + SetUpBasicIndex() + + gotResp, err := i.GetAllUpdateStatus() + require.NoError(t, err) + require.Equal(t, tt.wantResp[0].Status, (*gotResp)[0].Status) + require.Equal(t, tt.wantResp[0].UpdateID, (*gotResp)[0].UpdateID) + require.Equal(t, tt.wantResp[0].Error, (*gotResp)[0].Error) + }) + } +} + +func TestIndex_DefaultWaitForPendingUpdate(t *testing.T) { + type args struct { + UID string + client *Client + updateID *AsyncUpdateID + document []docTest + } + tests := []struct { + name string + args args + want UpdateStatus + }{ + { + name: "TestDefaultWaitForPendingUpdate", + args: args{ + UID: "1", + client: defaultClient, + updateID: &AsyncUpdateID{ + UpdateID: 0, + }, + document: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + }, + }, + want: "processed", + }, + { + name: "TestDefaultWaitForPendingUpdateWithCustomClient", + args: args{ + UID: "1", + client: customClient, + updateID: &AsyncUpdateID{ + UpdateID: 0, + }, + document: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + }, + }, + want: "processed", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + update, err := i.AddDocuments(tt.args.document) + require.NoError(t, err) + + got, err := i.DefaultWaitForPendingUpdate(update) + require.NoError(t, err) + require.Equal(t, tt.want, got) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_WaitForPendingUpdate(t *testing.T) { + type args struct { + UID string + client *Client + interval time.Duration + timeout time.Duration + updateID *AsyncUpdateID + document []docTest + } + tests := []struct { + name string + args args + want UpdateStatus + }{ + { + name: "TestDefaultWaitForPendingUpdate50", + args: args{ + UID: "1", + client: defaultClient, + interval: time.Millisecond * 50, + timeout: time.Second * 5, + updateID: &AsyncUpdateID{ + UpdateID: 0, + }, + document: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + {ID: "456", Name: "Le Petit Prince"}, + {ID: "1", Name: "Alice In Wonderland"}, + }, + }, + want: "processed", + }, + { + name: "TestDefaultWaitForPendingUpdate50WithCustomClient", + args: args{ + UID: "1", + client: customClient, + interval: time.Millisecond * 50, + timeout: time.Second * 5, + updateID: &AsyncUpdateID{ + UpdateID: 0, + }, + document: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + {ID: "456", Name: "Le Petit Prince"}, + {ID: "1", Name: "Alice In Wonderland"}, + }, + }, + want: "processed", + }, + { + name: "TestDefaultWaitForPendingUpdate10", + args: args{ + UID: "1", + client: defaultClient, + interval: time.Millisecond * 10, + timeout: time.Second * 5, + updateID: &AsyncUpdateID{ + UpdateID: 1, + }, + document: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + {ID: "456", Name: "Le Petit Prince"}, + {ID: "1", Name: "Alice In Wonderland"}, + }, + }, + want: "processed", + }, + { + name: "TestDefaultWaitForPendingUpdateWithTimeout", + args: args{ + UID: "1", + client: defaultClient, + interval: time.Millisecond * 50, + timeout: time.Millisecond * 10, + updateID: &AsyncUpdateID{ + UpdateID: 1, + }, + document: []docTest{ + {ID: "123", Name: "Pride and Prejudice"}, + {ID: "456", Name: "Le Petit Prince"}, + {ID: "1", Name: "Alice In Wonderland"}, + }, + }, + want: "processed", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i := c.Index(tt.args.UID) + + update, err := i.AddDocuments(tt.args.document) + require.NoError(t, err) + + ctx, cancelFunc := context.WithTimeout(context.Background(), tt.args.timeout) + defer cancelFunc() + + got, err := i.WaitForPendingUpdate(ctx, tt.args.interval, update) + if tt.args.timeout < tt.args.interval { + require.Error(t, err) + } else { + require.NoError(t, err) + require.Equal(t, tt.want, got) + } + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_FetchInfo(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantResp *Index + }{ + { + name: "TestIndexBasicFetchInfo", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantResp: &Index{ + UID: "indexUID", + PrimaryKey: "book_id", + }, + }, + { + name: "TestIndexFetchInfoWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantResp: &Index{ + UID: "indexUID", + PrimaryKey: "book_id", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpBasicIndex() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotResp, err := i.FetchInfo() + require.NoError(t, err) + require.Equal(t, tt.wantResp.UID, gotResp.UID) + require.Equal(t, tt.wantResp.PrimaryKey, gotResp.PrimaryKey) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_FetchPrimaryKey(t *testing.T) { + type args struct { + UID string + client *Client + } + tests := []struct { + name string + args args + wantPrimaryKey string + }{ + { + name: "TestIndexBasicFetchPrimaryKey", + args: args{ + UID: "indexUID", + client: defaultClient, + }, + wantPrimaryKey: "book_id", + }, + { + name: "TestIndexFetchPrimaryKeyWithCustomClient", + args: args{ + UID: "indexUID", + client: customClient, + }, + wantPrimaryKey: "book_id", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + SetUpBasicIndex() + c := tt.args.client + i := c.Index(tt.args.UID) + + gotPrimaryKey, err := i.FetchPrimaryKey() + require.NoError(t, err) + require.Equal(t, &tt.wantPrimaryKey, gotPrimaryKey) + + deleteAllIndexes(c) + }) + } +} + +func TestIndex_UpdateIndex(t *testing.T) { + type args struct { + primaryKey string + config IndexConfig + client *Client + } + tests := []struct { + name string + args args + wantResp *Index + }{ + { + name: "TestIndexBasicUpdateIndex", + args: args{ + client: defaultClient, + config: IndexConfig{ + Uid: "indexUID", + }, + primaryKey: "book_id", + }, + wantResp: &Index{ + UID: "indexUID", + PrimaryKey: "book_id", + }, + }, + { + name: "TestIndexUpdateIndexWithCustomClient", + args: args{ + client: customClient, + config: IndexConfig{ + Uid: "indexUID", + }, + primaryKey: "book_id", + }, + wantResp: &Index{ + UID: "indexUID", + PrimaryKey: "book_id", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + c := tt.args.client + i, err := c.CreateIndex(&tt.args.config) + require.NoError(t, err) + require.Equal(t, tt.args.config.Uid, i.UID) + require.Equal(t, tt.args.config.PrimaryKey, i.PrimaryKey) + + gotResp, err := i.UpdateIndex(tt.args.primaryKey) + + require.NoError(t, err) + require.Equal(t, tt.wantResp.UID, gotResp.UID) + require.Equal(t, tt.wantResp.PrimaryKey, gotResp.PrimaryKey) + + deleteAllIndexes(c) + }) + } +} diff --git a/main_test.go b/main_test.go index a8568ee8..d6d230d5 100644 --- a/main_test.go +++ b/main_test.go @@ -1,8 +1,12 @@ package meilisearch import ( + "crypto/tls" + "fmt" "os" "testing" + + "github.com/valyala/fasthttp" ) type docTest struct { @@ -17,27 +21,104 @@ type docTestBooks struct { } func deleteAllIndexes(client ClientInterface) (ok bool, err error) { - list, err := client.Indexes().List() + list, err := client.GetAllIndexes() if err != nil { return false, err } for _, index := range list { - _, _ = client.Indexes().Delete(index.UID) + _, _ = client.DeleteIndex(index.UID) } return true, nil } -var client = NewClient(Config{ - Host: "http://localhost:7700", - APIKey: "masterKey", +func SetUpBasicIndex() { + client := NewClient(ClientConfig{ + Host: "http://localhost:7700", + MasterKey: masterKey, + }) + index := client.Index("indexUID") + + documents := []map[string]interface{}{ + {"book_id": 123, "title": "Pride and Prejudice"}, + {"book_id": 456, "title": "Le Petit Prince"}, + {"book_id": 1, "title": "Alice In Wonderland"}, + {"book_id": 1344, "title": "The Hobbit"}, + {"book_id": 4, "title": "Harry Potter and the Half-Blood Prince"}, + {"book_id": 42, "title": "The Hitchhiker's Guide to the Galaxy"}, + } + update, err := index.AddDocuments(documents) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + finalUpdateStatus, _ := index.DefaultWaitForPendingUpdate(update) + if finalUpdateStatus != "processed" { + os.Exit(1) + } +} + +func SetUpIndexForFaceting() { + client := NewClient(ClientConfig{ + Host: "http://localhost:7700", + MasterKey: masterKey, + }) + index := client.Index("indexUID") + + booksTest := []docTestBooks{ + {BookID: 123, Title: "Pride and Prejudice", Tag: "Romance"}, + {BookID: 456, Title: "Le Petit Prince", Tag: "Tale"}, + {BookID: 1, Title: "Alice In Wonderland", Tag: "Tale"}, + {BookID: 1344, Title: "The Hobbit", Tag: "Epic fantasy"}, + {BookID: 4, Title: "Harry Potter and the Half-Blood Prince", Tag: "Epic fantasy"}, + {BookID: 42, Title: "The Hitchhiker's Guide to the Galaxy", Tag: "Epic fantasy"}, + {BookID: 742, Title: "The Great Gatsby", Tag: "Tragedy"}, + {BookID: 834, Title: "One Hundred Years of Solitude", Tag: "Tragedy"}, + {BookID: 17, Title: "In Search of Lost Time", Tag: "Modernist literature"}, + {BookID: 204, Title: "Ulysses", Tag: "Novel"}, + {BookID: 7, Title: "Don Quixote", Tag: "Satiric"}, + {BookID: 10, Title: "Moby Dick", Tag: "Novel"}, + {BookID: 730, Title: "War and Peace", Tag: "Historical fiction"}, + {BookID: 69, Title: "Hamlet", Tag: "Tragedy"}, + {BookID: 32, Title: "The Odyssey", Tag: "Epic"}, + {BookID: 71, Title: "Madame Bovary", Tag: "Novel"}, + {BookID: 56, Title: "The Divine Comedy", Tag: "Epic"}, + {BookID: 254, Title: "Lolita", Tag: "Novel"}, + {BookID: 921, Title: "The Brothers Karamazov", Tag: "Novel"}, + {BookID: 1032, Title: "Crime and Punishment", Tag: "Crime fiction"}, + } + update, err := index.AddDocuments(booksTest) + if err != nil { + fmt.Println(err) + os.Exit(1) + } + finalUpdateStatus, _ := index.DefaultWaitForPendingUpdate(update) + if finalUpdateStatus != "processed" { + os.Exit(1) + } +} + +var masterKey = "masterKey" +var primaryKey = "primaryKey" +var defaultClient = NewClient(ClientConfig{ + Host: "http://localhost:7700", + MasterKey: masterKey, }) +var customClient = NewFastHTTPCustomClient(ClientConfig{ + Host: "http://localhost:7700", + MasterKey: masterKey, +}, + &fasthttp.Client{ + TLSConfig: &tls.Config{InsecureSkipVerify: true}, + Name: "custom-client", + }) + func TestMain(m *testing.M) { - _, _ = deleteAllIndexes(client) + _, _ = deleteAllIndexes(defaultClient) code := m.Run() - _, _ = deleteAllIndexes(client) + _, _ = deleteAllIndexes(defaultClient) os.Exit(code) } @@ -47,11 +128,11 @@ func Test_deleteAllIndexes(t *testing.T) { "Test_deleteAllIndexes2", "Test_deleteAllIndexes3", } - _, _ = deleteAllIndexes(client) + _, _ = deleteAllIndexes(defaultClient) for _, uid := range indexUIDs { - _, err := client.Indexes().Create(CreateIndexRequest{ - UID: uid, + _, err := defaultClient.CreateIndex(&IndexConfig{ + Uid: uid, }) if err != nil { @@ -59,10 +140,10 @@ func Test_deleteAllIndexes(t *testing.T) { } } - _, _ = deleteAllIndexes(client) + _, _ = deleteAllIndexes(defaultClient) for _, uid := range indexUIDs { - resp, err := client.Indexes().Get(uid) + resp, err := defaultClient.GetIndex(uid) if err == nil { t.Fatal(err) } diff --git a/types.go b/types.go index 924f9e31..d6797ad8 100644 --- a/types.go +++ b/types.go @@ -5,6 +5,7 @@ import ( "sync" "time" + "github.com/valyala/fasthttp" "github.com/valyala/fastjson" ) @@ -19,13 +20,19 @@ var ( // Internal types to Meilisearch // +// Client is a structure that give you the power for interacting with an high-level api with meilisearch. +type Client struct { + config ClientConfig + httpClient *fasthttp.Client +} + // Index is the type that represent an index in MeiliSearch type Index struct { - Name string `json:"name"` UID string `json:"uid"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` PrimaryKey string `json:"primaryKey,omitempty"` + client *Client } // Settings is the type that represents the settings in MeiliSearch @@ -113,27 +120,15 @@ type Dump struct { // CreateIndexRequest is the request body for create index method type CreateIndexRequest struct { - Name string `json:"name,omitempty"` UID string `json:"uid,omitempty"` PrimaryKey string `json:"primaryKey,omitempty"` } -// CreateIndexResponse is the response body for create index method -type CreateIndexResponse struct { - Name string `json:"name"` - UID string `json:"uid"` - UpdateID int64 `json:"updateID,omitempty"` - CreatedAt time.Time `json:"createdAt"` - UpdatedAt time.Time `json:"updatedAt"` - PrimaryKey string `json:"primaryKey,omitempty"` -} - // SearchRequest is the request url param needed for a search query. // This struct will be converted to url param before sent. // // Documentation: https://docs.meilisearch.com/reference/features/search_parameters.html type SearchRequest struct { - Query string Offset int64 Limit int64 AttributesToRetrieve []string @@ -153,14 +148,15 @@ type SearchResponse struct { NbHits int64 `json:"nbHits"` Offset int64 `json:"offset"` Limit int64 `json:"limit"` + ExhaustiveNbHits bool `json:"exhaustiveNbHits"` ProcessingTimeMs int64 `json:"processingTimeMs"` Query string `json:"query"` FacetsDistribution interface{} `json:"facetsDistribution,omitempty"` ExhaustiveFacetsCount interface{} `json:"exhaustiveFacetsCount,omitempty"` } -// ListDocumentsRequest is the request body for list documents method -type ListDocumentsRequest struct { +// DocumentsRequest is the request body for list documents method +type DocumentsRequest struct { Offset int64 `json:"offset,omitempty"` Limit int64 `json:"limit,omitempty"` AttributesToRetrieve []string `json:"attributesToRetrieve,omitempty"` @@ -171,16 +167,11 @@ type RawType []byte // Health is the request body for set Meilisearch health type Health struct { - Health bool `json:"health"` -} - -// Name is the request body for set Index name -type Name struct { - Name string `json:"name"` + Status string `json:"status"` } -// PrimaryKey is the request body for set Index primary key -type PrimaryKey struct { +// UpdateIndexRequest is the request body for update Index primary key +type UpdateIndexRequest struct { PrimaryKey string `json:"primaryKey"` } diff --git a/types_easyjson.go b/types_easyjson.go index 36f2dfc5..37a9e44b 100644 --- a/types_easyjson.go +++ b/types_easyjson.go @@ -99,7 +99,73 @@ func (v *Version) UnmarshalJSON(data []byte) error { func (v *Version) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo1(in *jlexer.Lexer, out *Update) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo1(in *jlexer.Lexer, out *UpdateIndexRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "primaryKey": + out.PrimaryKey = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo1(out *jwriter.Writer, in UpdateIndexRequest) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"primaryKey\":" + out.RawString(prefix[1:]) + out.String(string(in.PrimaryKey)) + } + out.RawByte('}') +} + +// MarshalJSON supports json.Marshaler interface +func (v UpdateIndexRequest) MarshalJSON() ([]byte, error) { + w := jwriter.Writer{} + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo1(&w, v) + return w.Buffer.BuildBytes(), w.Error +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v UpdateIndexRequest) MarshalEasyJSON(w *jwriter.Writer) { + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo1(w, v) +} + +// UnmarshalJSON supports json.Unmarshaler interface +func (v *UpdateIndexRequest) UnmarshalJSON(data []byte) error { + r := jlexer.Lexer{Data: data} + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo1(&r, v) + return r.Error() +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *UpdateIndexRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo1(l, v) +} +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo2(in *jlexer.Lexer, out *Update) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -164,7 +230,7 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo1(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo1(out *jwriter.Writer, in Update) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo2(out *jwriter.Writer, in Update) { out.RawByte('{') first := true _ = first @@ -226,27 +292,27 @@ func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo1(out *jwriter.Write // MarshalJSON supports json.Marshaler interface func (v Update) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo1(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo2(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface func (v Update) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo1(w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo2(w, v) } // UnmarshalJSON supports json.Unmarshaler interface func (v *Update) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo1(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo2(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface func (v *Update) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo1(l, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo2(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo2(in *jlexer.Lexer, out *StatsIndex) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo3(in *jlexer.Lexer, out *StatsIndex) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -295,7 +361,7 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo2(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo2(out *jwriter.Writer, in StatsIndex) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo3(out *jwriter.Writer, in StatsIndex) { out.RawByte('{') first := true _ = first @@ -336,27 +402,27 @@ func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo2(out *jwriter.Write // MarshalJSON supports json.Marshaler interface func (v StatsIndex) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo2(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo3(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface func (v StatsIndex) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo2(w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo3(w, v) } // UnmarshalJSON supports json.Unmarshaler interface func (v *StatsIndex) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo2(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo3(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface func (v *StatsIndex) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo2(l, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo3(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo3(in *jlexer.Lexer, out *Stats) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo4(in *jlexer.Lexer, out *Stats) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -407,7 +473,7 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo3(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo3(out *jwriter.Writer, in Stats) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo4(out *jwriter.Writer, in Stats) { out.RawByte('{') first := true _ = first @@ -448,27 +514,27 @@ func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo3(out *jwriter.Write // MarshalJSON supports json.Marshaler interface func (v Stats) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo3(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo4(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface func (v Stats) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo3(w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo4(w, v) } // UnmarshalJSON supports json.Unmarshaler interface func (v *Stats) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo3(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo4(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface func (v *Stats) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo3(l, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo4(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo4(in *jlexer.Lexer, out *Settings) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo5(in *jlexer.Lexer, out *Settings) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -663,7 +729,7 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo4(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo4(out *jwriter.Writer, in Settings) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo5(out *jwriter.Writer, in Settings) { out.RawByte('{') first := true _ = first @@ -809,27 +875,27 @@ func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo4(out *jwriter.Write // MarshalJSON supports json.Marshaler interface func (v Settings) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo4(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo5(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface func (v Settings) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo4(w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo5(w, v) } // UnmarshalJSON supports json.Unmarshaler interface func (v *Settings) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo4(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo5(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface func (v *Settings) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo4(l, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo5(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo5(in *jlexer.Lexer, out *SearchResponse) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo6(in *jlexer.Lexer, out *SearchResponse) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -883,6 +949,8 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo5(in *jlexer.Lexer, out.Offset = int64(in.Int64()) case "limit": out.Limit = int64(in.Int64()) + case "exhaustiveNbHits": + out.ExhaustiveNbHits = bool(in.Bool()) case "processingTimeMs": out.ProcessingTimeMs = int64(in.Int64()) case "query": @@ -913,7 +981,7 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo5(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo5(out *jwriter.Writer, in SearchResponse) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo6(out *jwriter.Writer, in SearchResponse) { out.RawByte('{') first := true _ = first @@ -954,6 +1022,11 @@ func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo5(out *jwriter.Write out.RawString(prefix) out.Int64(int64(in.Limit)) } + { + const prefix string = ",\"exhaustiveNbHits\":" + out.RawString(prefix) + out.Bool(bool(in.ExhaustiveNbHits)) + } { const prefix string = ",\"processingTimeMs\":" out.RawString(prefix) @@ -992,27 +1065,27 @@ func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo5(out *jwriter.Write // MarshalJSON supports json.Marshaler interface func (v SearchResponse) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo5(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo6(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface func (v SearchResponse) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo5(w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo6(w, v) } // UnmarshalJSON supports json.Unmarshaler interface func (v *SearchResponse) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo5(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo6(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface func (v *SearchResponse) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo5(l, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo6(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo6(in *jlexer.Lexer, out *SearchRequest) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo7(in *jlexer.Lexer, out *SearchRequest) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -1031,8 +1104,6 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo6(in *jlexer.Lexer, continue } switch key { - case "Query": - out.Query = string(in.String()) case "Offset": out.Offset = int64(in.Int64()) case "Limit": @@ -1155,18 +1226,13 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo6(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo6(out *jwriter.Writer, in SearchRequest) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo7(out *jwriter.Writer, in SearchRequest) { out.RawByte('{') first := true _ = first - { - const prefix string = ",\"Query\":" - out.RawString(prefix[1:]) - out.String(string(in.Query)) - } { const prefix string = ",\"Offset\":" - out.RawString(prefix) + out.RawString(prefix[1:]) out.Int64(int64(in.Offset)) } { @@ -1275,27 +1341,27 @@ func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo6(out *jwriter.Write // MarshalJSON supports json.Marshaler interface func (v SearchRequest) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo6(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo7(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface func (v SearchRequest) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo6(w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo7(w, v) } // UnmarshalJSON supports json.Unmarshaler interface func (v *SearchRequest) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo6(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo7(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface func (v *SearchRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo6(l, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo7(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo7(in *jlexer.Lexer, out *PrimaryKey) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo8(in *jlexer.Lexer, out *Keys) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -1314,8 +1380,10 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo7(in *jlexer.Lexer, continue } switch key { - case "primaryKey": - out.PrimaryKey = string(in.String()) + case "public": + out.Public = string(in.String()) + case "private": + out.Private = string(in.String()) default: in.SkipRecursive() } @@ -1326,42 +1394,53 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo7(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo7(out *jwriter.Writer, in PrimaryKey) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo8(out *jwriter.Writer, in Keys) { out.RawByte('{') first := true _ = first - { - const prefix string = ",\"primaryKey\":" + if in.Public != "" { + const prefix string = ",\"public\":" + first = false out.RawString(prefix[1:]) - out.String(string(in.PrimaryKey)) + out.String(string(in.Public)) + } + if in.Private != "" { + const prefix string = ",\"private\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Private)) } out.RawByte('}') } // MarshalJSON supports json.Marshaler interface -func (v PrimaryKey) MarshalJSON() ([]byte, error) { +func (v Keys) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo7(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo8(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface -func (v PrimaryKey) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo7(w, v) +func (v Keys) MarshalEasyJSON(w *jwriter.Writer) { + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo8(w, v) } // UnmarshalJSON supports json.Unmarshaler interface -func (v *PrimaryKey) UnmarshalJSON(data []byte) error { +func (v *Keys) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo7(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo8(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *PrimaryKey) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo7(l, v) +func (v *Keys) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo8(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo8(in *jlexer.Lexer, out *Name) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo9(in *jlexer.Lexer, out *Index) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -1380,8 +1459,18 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo8(in *jlexer.Lexer, continue } switch key { - case "name": - out.Name = string(in.String()) + case "uid": + out.UID = string(in.String()) + case "createdAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.CreatedAt).UnmarshalJSON(data)) + } + case "updatedAt": + if data := in.Raw(); in.Ok() { + in.AddError((out.UpdatedAt).UnmarshalJSON(data)) + } + case "primaryKey": + out.PrimaryKey = string(in.String()) default: in.SkipRecursive() } @@ -1392,42 +1481,57 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo8(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo8(out *jwriter.Writer, in Name) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo9(out *jwriter.Writer, in Index) { out.RawByte('{') first := true _ = first { - const prefix string = ",\"name\":" + const prefix string = ",\"uid\":" out.RawString(prefix[1:]) - out.String(string(in.Name)) + out.String(string(in.UID)) + } + { + const prefix string = ",\"createdAt\":" + out.RawString(prefix) + out.Raw((in.CreatedAt).MarshalJSON()) + } + { + const prefix string = ",\"updatedAt\":" + out.RawString(prefix) + out.Raw((in.UpdatedAt).MarshalJSON()) + } + if in.PrimaryKey != "" { + const prefix string = ",\"primaryKey\":" + out.RawString(prefix) + out.String(string(in.PrimaryKey)) } out.RawByte('}') } // MarshalJSON supports json.Marshaler interface -func (v Name) MarshalJSON() ([]byte, error) { +func (v Index) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo8(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo9(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface -func (v Name) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo8(w, v) +func (v Index) MarshalEasyJSON(w *jwriter.Writer) { + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo9(w, v) } // UnmarshalJSON supports json.Unmarshaler interface -func (v *Name) UnmarshalJSON(data []byte) error { +func (v *Index) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo8(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo9(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Name) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo8(l, v) +func (v *Index) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo9(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo9(in *jlexer.Lexer, out *ListDocumentsRequest) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo10(in *jlexer.Lexer, out *Health) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -1446,33 +1550,8 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo9(in *jlexer.Lexer, continue } switch key { - case "offset": - out.Offset = int64(in.Int64()) - case "limit": - out.Limit = int64(in.Int64()) - case "attributesToRetrieve": - if in.IsNull() { - in.Skip() - out.AttributesToRetrieve = nil - } else { - in.Delim('[') - if out.AttributesToRetrieve == nil { - if !in.IsDelim(']') { - out.AttributesToRetrieve = make([]string, 0, 4) - } else { - out.AttributesToRetrieve = []string{} - } - } else { - out.AttributesToRetrieve = (out.AttributesToRetrieve)[:0] - } - for !in.IsDelim(']') { - var v42 string - v42 = string(in.String()) - out.AttributesToRetrieve = append(out.AttributesToRetrieve, v42) - in.WantComma() - } - in.Delim(']') - } + case "status": + out.Status = string(in.String()) default: in.SkipRecursive() } @@ -1483,151 +1562,42 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo9(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo9(out *jwriter.Writer, in ListDocumentsRequest) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo10(out *jwriter.Writer, in Health) { out.RawByte('{') first := true _ = first - if in.Offset != 0 { - const prefix string = ",\"offset\":" - first = false + { + const prefix string = ",\"status\":" out.RawString(prefix[1:]) - out.Int64(int64(in.Offset)) - } - if in.Limit != 0 { - const prefix string = ",\"limit\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.Int64(int64(in.Limit)) - } - if len(in.AttributesToRetrieve) != 0 { - const prefix string = ",\"attributesToRetrieve\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - { - out.RawByte('[') - for v43, v44 := range in.AttributesToRetrieve { - if v43 > 0 { - out.RawByte(',') - } - out.String(string(v44)) - } - out.RawByte(']') - } - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v ListDocumentsRequest) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo9(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v ListDocumentsRequest) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo9(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *ListDocumentsRequest) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo9(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *ListDocumentsRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo9(l, v) -} -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo10(in *jlexer.Lexer, out *Keys) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "public": - out.Public = string(in.String()) - case "private": - out.Private = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo10(out *jwriter.Writer, in Keys) { - out.RawByte('{') - first := true - _ = first - if in.Public != "" { - const prefix string = ",\"public\":" - first = false - out.RawString(prefix[1:]) - out.String(string(in.Public)) - } - if in.Private != "" { - const prefix string = ",\"private\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.Private)) + out.String(string(in.Status)) } out.RawByte('}') } // MarshalJSON supports json.Marshaler interface -func (v Keys) MarshalJSON() ([]byte, error) { +func (v Health) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo10(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface -func (v Keys) MarshalEasyJSON(w *jwriter.Writer) { +func (v Health) MarshalEasyJSON(w *jwriter.Writer) { easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo10(w, v) } // UnmarshalJSON supports json.Unmarshaler interface -func (v *Keys) UnmarshalJSON(data []byte) error { +func (v *Health) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo10(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Keys) UnmarshalEasyJSON(l *jlexer.Lexer) { +func (v *Health) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo10(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo11(in *jlexer.Lexer, out *Index) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo11(in *jlexer.Lexer, out *Dump) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -1646,20 +1616,10 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo11(in *jlexer.Lexer, continue } switch key { - case "name": - out.Name = string(in.String()) case "uid": out.UID = string(in.String()) - case "createdAt": - if data := in.Raw(); in.Ok() { - in.AddError((out.CreatedAt).UnmarshalJSON(data)) - } - case "updatedAt": - if data := in.Raw(); in.Ok() { - in.AddError((out.UpdatedAt).UnmarshalJSON(data)) - } - case "primaryKey": - out.PrimaryKey = string(in.String()) + case "status": + out.Status = string(in.String()) default: in.SkipRecursive() } @@ -1670,62 +1630,47 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo11(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo11(out *jwriter.Writer, in Index) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo11(out *jwriter.Writer, in Dump) { out.RawByte('{') first := true _ = first - { - const prefix string = ",\"name\":" - out.RawString(prefix[1:]) - out.String(string(in.Name)) - } { const prefix string = ",\"uid\":" - out.RawString(prefix) + out.RawString(prefix[1:]) out.String(string(in.UID)) } { - const prefix string = ",\"createdAt\":" - out.RawString(prefix) - out.Raw((in.CreatedAt).MarshalJSON()) - } - { - const prefix string = ",\"updatedAt\":" - out.RawString(prefix) - out.Raw((in.UpdatedAt).MarshalJSON()) - } - if in.PrimaryKey != "" { - const prefix string = ",\"primaryKey\":" + const prefix string = ",\"status\":" out.RawString(prefix) - out.String(string(in.PrimaryKey)) + out.String(string(in.Status)) } out.RawByte('}') } // MarshalJSON supports json.Marshaler interface -func (v Index) MarshalJSON() ([]byte, error) { +func (v Dump) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo11(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface -func (v Index) MarshalEasyJSON(w *jwriter.Writer) { +func (v Dump) MarshalEasyJSON(w *jwriter.Writer) { easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo11(w, v) } // UnmarshalJSON supports json.Unmarshaler interface -func (v *Index) UnmarshalJSON(data []byte) error { +func (v *Dump) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo11(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Index) UnmarshalEasyJSON(l *jlexer.Lexer) { +func (v *Dump) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo11(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo12(in *jlexer.Lexer, out *Health) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo12(in *jlexer.Lexer, out *DocumentsRequest) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -1744,8 +1689,33 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo12(in *jlexer.Lexer, continue } switch key { - case "health": - out.Health = bool(in.Bool()) + case "offset": + out.Offset = int64(in.Int64()) + case "limit": + out.Limit = int64(in.Int64()) + case "attributesToRetrieve": + if in.IsNull() { + in.Skip() + out.AttributesToRetrieve = nil + } else { + in.Delim('[') + if out.AttributesToRetrieve == nil { + if !in.IsDelim(']') { + out.AttributesToRetrieve = make([]string, 0, 4) + } else { + out.AttributesToRetrieve = []string{} + } + } else { + out.AttributesToRetrieve = (out.AttributesToRetrieve)[:0] + } + for !in.IsDelim(']') { + var v42 string + v42 = string(in.String()) + out.AttributesToRetrieve = append(out.AttributesToRetrieve, v42) + in.WantComma() + } + in.Delim(']') + } default: in.SkipRecursive() } @@ -1756,42 +1726,72 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo12(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo12(out *jwriter.Writer, in Health) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo12(out *jwriter.Writer, in DocumentsRequest) { out.RawByte('{') first := true _ = first - { - const prefix string = ",\"health\":" + if in.Offset != 0 { + const prefix string = ",\"offset\":" + first = false out.RawString(prefix[1:]) - out.Bool(bool(in.Health)) + out.Int64(int64(in.Offset)) + } + if in.Limit != 0 { + const prefix string = ",\"limit\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int64(int64(in.Limit)) + } + if len(in.AttributesToRetrieve) != 0 { + const prefix string = ",\"attributesToRetrieve\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + { + out.RawByte('[') + for v43, v44 := range in.AttributesToRetrieve { + if v43 > 0 { + out.RawByte(',') + } + out.String(string(v44)) + } + out.RawByte(']') + } } out.RawByte('}') } // MarshalJSON supports json.Marshaler interface -func (v Health) MarshalJSON() ([]byte, error) { +func (v DocumentsRequest) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo12(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface -func (v Health) MarshalEasyJSON(w *jwriter.Writer) { +func (v DocumentsRequest) MarshalEasyJSON(w *jwriter.Writer) { easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo12(w, v) } // UnmarshalJSON supports json.Unmarshaler interface -func (v *Health) UnmarshalJSON(data []byte) error { +func (v *DocumentsRequest) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo12(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Health) UnmarshalEasyJSON(l *jlexer.Lexer) { +func (v *DocumentsRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo12(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo13(in *jlexer.Lexer, out *Dump) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo13(in *jlexer.Lexer, out *CreateIndexRequest) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -1812,8 +1812,8 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo13(in *jlexer.Lexer, switch key { case "uid": out.UID = string(in.String()) - case "status": - out.Status = string(in.String()) + case "primaryKey": + out.PrimaryKey = string(in.String()) default: in.SkipRecursive() } @@ -1824,47 +1824,53 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo13(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo13(out *jwriter.Writer, in Dump) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo13(out *jwriter.Writer, in CreateIndexRequest) { out.RawByte('{') first := true _ = first - { + if in.UID != "" { const prefix string = ",\"uid\":" + first = false out.RawString(prefix[1:]) out.String(string(in.UID)) } - { - const prefix string = ",\"status\":" - out.RawString(prefix) - out.String(string(in.Status)) + if in.PrimaryKey != "" { + const prefix string = ",\"primaryKey\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.PrimaryKey)) } out.RawByte('}') } // MarshalJSON supports json.Marshaler interface -func (v Dump) MarshalJSON() ([]byte, error) { +func (v CreateIndexRequest) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo13(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface -func (v Dump) MarshalEasyJSON(w *jwriter.Writer) { +func (v CreateIndexRequest) MarshalEasyJSON(w *jwriter.Writer) { easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo13(w, v) } // UnmarshalJSON supports json.Unmarshaler interface -func (v *Dump) UnmarshalJSON(data []byte) error { +func (v *CreateIndexRequest) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo13(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *Dump) UnmarshalEasyJSON(l *jlexer.Lexer) { +func (v *CreateIndexRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo13(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo14(in *jlexer.Lexer, out *CreateIndexResponse) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo14(in *jlexer.Lexer, out *Client) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -1883,22 +1889,6 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo14(in *jlexer.Lexer, continue } switch key { - case "name": - out.Name = string(in.String()) - case "uid": - out.UID = string(in.String()) - case "updateID": - out.UpdateID = int64(in.Int64()) - case "createdAt": - if data := in.Raw(); in.Ok() { - in.AddError((out.CreatedAt).UnmarshalJSON(data)) - } - case "updatedAt": - if data := in.Raw(); in.Ok() { - in.AddError((out.UpdatedAt).UnmarshalJSON(data)) - } - case "primaryKey": - out.PrimaryKey = string(in.String()) default: in.SkipRecursive() } @@ -1909,158 +1899,37 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo14(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo14(out *jwriter.Writer, in CreateIndexResponse) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo14(out *jwriter.Writer, in Client) { out.RawByte('{') first := true _ = first - { - const prefix string = ",\"name\":" - out.RawString(prefix[1:]) - out.String(string(in.Name)) - } - { - const prefix string = ",\"uid\":" - out.RawString(prefix) - out.String(string(in.UID)) - } - if in.UpdateID != 0 { - const prefix string = ",\"updateID\":" - out.RawString(prefix) - out.Int64(int64(in.UpdateID)) - } - { - const prefix string = ",\"createdAt\":" - out.RawString(prefix) - out.Raw((in.CreatedAt).MarshalJSON()) - } - { - const prefix string = ",\"updatedAt\":" - out.RawString(prefix) - out.Raw((in.UpdatedAt).MarshalJSON()) - } - if in.PrimaryKey != "" { - const prefix string = ",\"primaryKey\":" - out.RawString(prefix) - out.String(string(in.PrimaryKey)) - } out.RawByte('}') } // MarshalJSON supports json.Marshaler interface -func (v CreateIndexResponse) MarshalJSON() ([]byte, error) { +func (v Client) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo14(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface -func (v CreateIndexResponse) MarshalEasyJSON(w *jwriter.Writer) { +func (v Client) MarshalEasyJSON(w *jwriter.Writer) { easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo14(w, v) } // UnmarshalJSON supports json.Unmarshaler interface -func (v *CreateIndexResponse) UnmarshalJSON(data []byte) error { +func (v *Client) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo14(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *CreateIndexResponse) UnmarshalEasyJSON(l *jlexer.Lexer) { +func (v *Client) UnmarshalEasyJSON(l *jlexer.Lexer) { easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo14(l, v) } -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo15(in *jlexer.Lexer, out *CreateIndexRequest) { - isTopLevel := in.IsStart() - if in.IsNull() { - if isTopLevel { - in.Consumed() - } - in.Skip() - return - } - in.Delim('{') - for !in.IsDelim('}') { - key := in.UnsafeFieldName(false) - in.WantColon() - if in.IsNull() { - in.Skip() - in.WantComma() - continue - } - switch key { - case "name": - out.Name = string(in.String()) - case "uid": - out.UID = string(in.String()) - case "primaryKey": - out.PrimaryKey = string(in.String()) - default: - in.SkipRecursive() - } - in.WantComma() - } - in.Delim('}') - if isTopLevel { - in.Consumed() - } -} -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo15(out *jwriter.Writer, in CreateIndexRequest) { - out.RawByte('{') - first := true - _ = first - if in.Name != "" { - const prefix string = ",\"name\":" - first = false - out.RawString(prefix[1:]) - out.String(string(in.Name)) - } - if in.UID != "" { - const prefix string = ",\"uid\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.UID)) - } - if in.PrimaryKey != "" { - const prefix string = ",\"primaryKey\":" - if first { - first = false - out.RawString(prefix[1:]) - } else { - out.RawString(prefix) - } - out.String(string(in.PrimaryKey)) - } - out.RawByte('}') -} - -// MarshalJSON supports json.Marshaler interface -func (v CreateIndexRequest) MarshalJSON() ([]byte, error) { - w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo15(&w, v) - return w.Buffer.BuildBytes(), w.Error -} - -// MarshalEasyJSON supports easyjson.Marshaler interface -func (v CreateIndexRequest) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo15(w, v) -} - -// UnmarshalJSON supports json.Unmarshaler interface -func (v *CreateIndexRequest) UnmarshalJSON(data []byte) error { - r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo15(&r, v) - return r.Error() -} - -// UnmarshalEasyJSON supports easyjson.Unmarshaler interface -func (v *CreateIndexRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo15(l, v) -} -func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo16(in *jlexer.Lexer, out *AsyncUpdateID) { +func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo15(in *jlexer.Lexer, out *AsyncUpdateID) { isTopLevel := in.IsStart() if in.IsNull() { if isTopLevel { @@ -2091,7 +1960,7 @@ func easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo16(in *jlexer.Lexer, in.Consumed() } } -func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo16(out *jwriter.Writer, in AsyncUpdateID) { +func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo15(out *jwriter.Writer, in AsyncUpdateID) { out.RawByte('{') first := true _ = first @@ -2106,23 +1975,23 @@ func easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo16(out *jwriter.Writ // MarshalJSON supports json.Marshaler interface func (v AsyncUpdateID) MarshalJSON() ([]byte, error) { w := jwriter.Writer{} - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo16(&w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo15(&w, v) return w.Buffer.BuildBytes(), w.Error } // MarshalEasyJSON supports easyjson.Marshaler interface func (v AsyncUpdateID) MarshalEasyJSON(w *jwriter.Writer) { - easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo16(w, v) + easyjson6601e8cdEncodeGithubComMeilisearchMeilisearchGo15(w, v) } // UnmarshalJSON supports json.Unmarshaler interface func (v *AsyncUpdateID) UnmarshalJSON(data []byte) error { r := jlexer.Lexer{Data: data} - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo16(&r, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo15(&r, v) return r.Error() } // UnmarshalEasyJSON supports easyjson.Unmarshaler interface func (v *AsyncUpdateID) UnmarshalEasyJSON(l *jlexer.Lexer) { - easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo16(l, v) + easyjson6601e8cdDecodeGithubComMeilisearchMeilisearchGo15(l, v) }