Repository: meilisearch/meilisearch-go

Issue:
[v1.23] Add support for compacting database indexes
## Description

Meilisearch v1.23 introduced a new [Compact database](https://www.meilisearch.com/docs/reference/api/compact#compact-database) API endpoint.

We want to add support for this compacting database indexes in this SDK.

## Tasks

- [ ] Add the method to interact with the endpoint
- [ ] Add a test case
- [ ] Add an example in [.code-samples.meilisearch.yaml](../blob/main/.code-samples.meilisearch.yaml) under the `compact_index_1` key; it should be the equivalent of this [CURL-based example](https://github.com/meilisearch/documentation/blob/4ca3dab738851508e86e79f45a131c5dd8641668/.code-samples.meilisearch.yaml#L1521-L1523)

Hints from issue comments:

Solution patch:
diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml
index 9f9ed83..e397c13 100644
--- a/.code-samples.meilisearch.yaml
+++ b/.code-samples.meilisearch.yaml
@@ -1066,3 +1066,5 @@ network_patch_2: |-
     Self: meilisearch.String("TEST"),
     Remotes: meilisearch.Null[map[string]meilisearch.Opt[meilisearch.Remote]](),
   });
+index_compact_1: |-
+  client.Index("INDEX_UID").Compact();
diff --git a/index.go b/index.go
index 5a1d193..03d1e29 100644
--- a/index.go
+++ b/index.go
@@ -157,3 +157,24 @@ func (i *index) GetStatsWithContext(ctx context.Context) (*StatsIndex, error) {
 	}
 	return resp, nil
 }
+
+func (i *index) Compact() (*TaskInfo, error) {
+	return i.CompactWithContext(context.Background())
+}
+
+func (i *index) CompactWithContext(ctx context.Context) (*TaskInfo, error) {
+	resp := new(TaskInfo)
+	req := &internalRequest{
+		endpoint:            "/indexes/" + i.uid + "/compact",
+		method:              http.MethodPost,
+		contentType:         contentTypeJSON,
+		withRequest:         nil,
+		withResponse:        resp,
+		acceptedStatusCodes: []int{http.StatusAccepted},
+		functionName:        "Compact",
+	}
+	if err := i.client.executeRequest(ctx, req); err != nil {
+		return nil, err
+	}
+	return resp, nil
+}
diff --git a/index_interface.go b/index_interface.go
index e3bc8a8..5866cd3 100644
--- a/index_interface.go
+++ b/index_interface.go
@@ -32,6 +32,12 @@ type IndexManager interface {
 
 	// DeleteWithContext removes the index identified by the given UID using the provided context for cancellation.
 	DeleteWithContext(ctx context.Context, uid string) (bool, error)
+
+	// Compact compacts the index.
+	Compact() (*TaskInfo, error)
+
+	// CompactWithContext compacts the index using the provided context for cancellation.
+	CompactWithContext(ctx context.Context) (*TaskInfo, error)
 }
 
 type IndexReader interface {



Test patch:
diff --git a/integration/index_test.go b/integration/index_test.go
index e27b5ca..6ac8317 100644
--- a/integration/index_test.go
+++ b/integration/index_test.go
@@ -422,9 +422,9 @@ func TestIndex_UpdateIndex(t *testing.T) {
 
 			var indexUID string
 			indexRenamed := tt.args.params.UID != ""
-			if indexRenamed { 
+			if indexRenamed {
 				indexUID = tt.args.params.UID
-			} else {	
+			} else {
 				indexUID = tt.args.config.Uid
 			}
 			gotIndex, err := c.GetIndex(indexUID)
@@ -449,3 +449,42 @@ func TestIndexManagerAndReaders(t *testing.T) {
 	require.NotNil(t, idx.GetDocumentManager())
 	require.NotNil(t, idx.GetDocumentReader())
 }
+
+func TestIndex_Compact(t *testing.T) {
+	sv := setup(t, "")
+	customSv := setup(t, "", meilisearch.WithCustomClientWithTLS(&tls.Config{
+		InsecureSkipVerify: true,
+	}))
+
+	tests := []struct {
+		name     string
+		client   meilisearch.ServiceManager
+		wantTask *meilisearch.TaskInfo
+	}{
+		{
+			name:   "TestIndexCompact",
+			client: sv,
+			wantTask: &meilisearch.TaskInfo{
+				TaskUID: 1,
+			},
+		},
+		{
+			name:   "TestIndexCompactWithCustomClient",
+			client: customSv,
+			wantTask: &meilisearch.TaskInfo{
+				TaskUID: 1,
+			},
+		},
+	}
+
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			t.Cleanup(cleanup(tt.client))
+			idx := setupMovieIndex(t, tt.client, "movies")
+			gotTask, err := idx.Compact()
+			require.NoError(t, err)
+			require.GreaterOrEqual(t, gotTask.TaskUID, tt.wantTask.TaskUID)
+			testWaitForTask(t, idx, gotTask)
+		})
+	}
+}