Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
16 / 16
CRAP
100.00% covered (success)
100.00%
1 / 1
Index
100.00% covered (success)
100.00%
51 / 51
100.00% covered (success)
100.00%
16 / 16
28
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 describeIndexStats
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 startImport
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 listImports
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
5
 describeImport
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 cancelImport
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 listNamespaces
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 describeNamespace
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 deleteNamespace
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 namespace
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 upsert
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 query
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 fetch
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 delete
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 update
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 listVectorIds
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare(strict_types=1);
4
5namespace Mbvb1223\Pinecone\Data;
6
7use GuzzleHttp\Client;
8use GuzzleHttp\Exception\GuzzleException;
9use Mbvb1223\Pinecone\Errors\PineconeException;
10use Mbvb1223\Pinecone\Utils\HandlesApiResponse;
11
12class Index
13{
14    use HandlesApiResponse;
15
16    private DataPlane $dataPlane;
17
18    public function __construct(private readonly Client $httpClient)
19    {
20        $this->dataPlane = new DataPlane($httpClient);
21    }
22
23    /**
24     * @param array<string, mixed>|null $filter Metadata filter expression
25     * @return array<string, mixed>
26     */
27    public function describeIndexStats(?array $filter = null): array
28    {
29        try {
30            $payload = [];
31            if ($filter !== null) {
32                $payload['filter'] = $filter;
33            }
34
35            $response = $this->httpClient->post('/describe_index_stats', ['json' => (object) $payload]);
36
37            return $this->handleResponse($response);
38        } catch (GuzzleException $e) {
39            throw new PineconeException('Failed to describe index stats: ' . $e->getMessage(), 0, $e);
40        }
41    }
42
43    // Import operations
44
45    /**
46     * @param array{uri: string, errorMode?: array{onError?: string}, ...} $requestData
47     * @return array<string, mixed>
48     */
49    public function startImport(array $requestData): array
50    {
51        try {
52            $response = $this->httpClient->post('/bulk/imports', ['json' => $requestData]);
53
54            return $this->handleResponse($response);
55        } catch (GuzzleException $e) {
56            throw new PineconeException('Failed to start import: ' . $e->getMessage(), 0, $e);
57        }
58    }
59
60    /** @return array<string, mixed> */
61    public function listImports(?int $limit = null, ?string $paginationToken = null): array
62    {
63        try {
64            $params = [];
65            if ($limit !== null) {
66                $params['limit'] = $limit;
67            }
68            if ($paginationToken !== null) {
69                $params['paginationToken'] = $paginationToken;
70            }
71
72            $options = !empty($params) ? ['query' => $params] : [];
73            $response = $this->httpClient->get('/bulk/imports', $options);
74
75            return $this->handleResponse($response);
76        } catch (GuzzleException $e) {
77            throw new PineconeException('Failed to list imports: ' . $e->getMessage(), 0, $e);
78        }
79    }
80
81    /** @return array<string, mixed> */
82    public function describeImport(string $importId): array
83    {
84        try {
85            $response = $this->httpClient->get('/bulk/imports/' . urlencode($importId));
86
87            return $this->handleResponse($response);
88        } catch (GuzzleException $e) {
89            throw new PineconeException('Failed to describe import: ' . $e->getMessage(), 0, $e);
90        }
91    }
92
93    public function cancelImport(string $importId): void
94    {
95        try {
96            $this->httpClient->delete('/bulk/imports/' . urlencode($importId));
97        } catch (GuzzleException $e) {
98            throw new PineconeException('Failed to cancel import: ' . $e->getMessage(), 0, $e);
99        }
100    }
101
102    // Namespace operations
103
104    /** @return array<int, string> */
105    public function listNamespaces(): array
106    {
107        try {
108            $response = $this->httpClient->post('/describe_index_stats', ['json' => (object) []]);
109            $data = $this->handleResponse($response);
110
111            return array_keys($data['namespaces'] ?? []);
112        } catch (GuzzleException $e) {
113            throw new PineconeException('Failed to list namespaces: ' . $e->getMessage(), 0, $e);
114        }
115    }
116
117    /** @return array<string, mixed> */
118    public function describeNamespace(string $namespace): array
119    {
120        try {
121            $response = $this->httpClient->post('/describe_index_stats', ['json' => (object) []]);
122            $data = $this->handleResponse($response);
123
124            return $data['namespaces'][$namespace] ?? [];
125        } catch (GuzzleException $e) {
126            throw new PineconeException('Failed to describe namespace: ' . $e->getMessage(), 0, $e);
127        }
128    }
129
130    public function deleteNamespace(string $namespace): void
131    {
132        try {
133            $this->httpClient->post('/vectors/delete', [
134                'json' => ['deleteAll' => true, 'namespace' => $namespace],
135            ]);
136        } catch (GuzzleException $e) {
137            throw new PineconeException('Failed to delete namespace: ' . $e->getMessage(), 0, $e);
138        }
139    }
140
141    public function namespace(string $namespace): IndexNamespace
142    {
143        return new IndexNamespace($this->dataPlane, $namespace);
144    }
145
146    // Data plane proxy methods
147
148    /**
149     * @param array<int, array{id: string, values: array<float>, sparseValues?: array{indices: array<int>, values: array<float>}, metadata?: array<string, mixed>}> $vectors
150     * @return array<string, mixed>
151     */
152    public function upsert(array $vectors, ?string $namespace = null): array
153    {
154        return $this->dataPlane->upsert($vectors, $namespace);
155    }
156
157    /**
158     * @param array<float> $vector
159     * @param array<string, mixed>|null $filter Metadata filter expression
160     * @param array{indices: array<int>, values: array<float>}|null $sparseVector
161     * @return array<string, mixed>
162     */
163    public function query(
164        array $vector = [],
165        ?string $id = null,
166        int $topK = 10,
167        ?array $filter = null,
168        ?string $namespace = null,
169        bool $includeValues = false,
170        bool $includeMetadata = true,
171        ?array $sparseVector = null,
172    ): array {
173        return $this->dataPlane->query($vector, $id, $topK, $filter, $namespace, $includeValues, $includeMetadata, $sparseVector);
174    }
175
176    /**
177     * @param array<int, string> $ids
178     * @return array<string, array<string, mixed>>
179     */
180    public function fetch(array $ids, ?string $namespace = null): array
181    {
182        return $this->dataPlane->fetch($ids, $namespace);
183    }
184
185    /**
186     * @param array<int, string> $ids
187     * @param array<string, mixed>|null $filter Metadata filter expression
188     * @return array<string, mixed>
189     */
190    public function delete(array $ids = [], ?array $filter = null, ?string $namespace = null, bool $deleteAll = false): array
191    {
192        return $this->dataPlane->delete($ids, $filter, $namespace, $deleteAll);
193    }
194
195    /**
196     * @param array<float> $values
197     * @param array<string, mixed>|null $setMetadata
198     * @param array{indices: array<int>, values: array<float>}|null $sparseValues
199     * @return array<string, mixed>
200     */
201    public function update(string $id, array $values = [], ?array $setMetadata = null, ?string $namespace = null, ?array $sparseValues = null): array
202    {
203        return $this->dataPlane->update($id, $values, $setMetadata, $namespace, $sparseValues);
204    }
205
206    /** @return array<string, mixed> */
207    public function listVectorIds(?string $prefix = null, ?int $limit = null, ?string $paginationToken = null, ?string $namespace = null): array
208    {
209        return $this->dataPlane->listVectorIds($prefix, $limit, $paginationToken, $namespace);
210    }
211}