Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
45.28% covered (danger)
45.28%
24 / 53
27.27% covered (danger)
27.27%
3 / 11
CRAP
0.00% covered (danger)
0.00%
0 / 1
Index
45.28% covered (danger)
45.28%
24 / 53
27.27% covered (danger)
27.27%
3 / 11
109.66
0.00% covered (danger)
0.00%
0 / 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
50.00% covered (danger)
50.00%
2 / 4
0.00% covered (danger)
0.00%
0 / 1
2.50
 listImports
50.00% covered (danger)
50.00%
2 / 4
0.00% covered (danger)
0.00%
0 / 1
2.50
 describeImport
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
2.06
 cancelImport
33.33% covered (danger)
33.33%
1 / 3
0.00% covered (danger)
0.00%
0 / 1
3.19
 listNamespaces
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 describeNamespace
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
 deleteNamespace
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 namespace
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 handleResponse
58.33% covered (warning)
58.33%
7 / 12
0.00% covered (danger)
0.00%
0 / 1
5.16
1<?php
2
3declare(strict_types=1);
4
5namespace Mbvb1223\Pinecone\Data;
6
7use GuzzleHttp\Client;
8use GuzzleHttp\Exception\GuzzleException;
9use Mbvb1223\Pinecone\Errors\PineconeApiException;
10use Mbvb1223\Pinecone\Errors\PineconeException;
11use Psr\Http\Message\ResponseInterface;
12
13class Index
14{
15    private DataPlane $dataPlane;
16
17    public function __construct(private readonly Client $httpClient)
18    {
19        $this->dataPlane = new DataPlane($httpClient);
20    }
21
22    public function describeIndexStats(?array $filter = null): array
23    {
24        try {
25            $payload = [];
26            if ($filter) {
27                $payload['filter'] = $filter;
28            }
29
30            $response = $this->httpClient->post('/describe_index_stats', ['json' => (object) $payload]);
31
32            return $this->handleResponse($response);
33        } catch (GuzzleException $e) {
34            throw new PineconeException('Failed to describe index stats: ' . $e->getMessage(), 0, $e);
35        }
36    }
37
38    // Import operations
39    public function startImport(array $requestData): array
40    {
41        try {
42            $response = $this->httpClient->post('/bulk/imports', ['json' => $requestData]);
43
44            return $this->handleResponse($response);
45        } catch (GuzzleException $e) {
46            throw new PineconeException('Failed to start import: ' . $e->getMessage(), 0, $e);
47        }
48    }
49
50    public function listImports(): array
51    {
52        try {
53            $response = $this->httpClient->get('/bulk/imports');
54
55            return $this->handleResponse($response);
56        } catch (GuzzleException $e) {
57            throw new PineconeException('Failed to list imports: ' . $e->getMessage(), 0, $e);
58        }
59    }
60
61    public function describeImport(string $importId): array
62    {
63        try {
64            $response = $this->httpClient->get("/bulk/imports/{$importId}");
65
66            return $this->handleResponse($response);
67        } catch (GuzzleException $e) {
68            throw new PineconeException('Failed to describe import: ' . $e->getMessage(), 0, $e);
69        }
70    }
71
72    public function cancelImport(string $importId): void
73    {
74        try {
75            $this->httpClient->delete("/bulk/imports/{$importId}");
76        } catch (GuzzleException $e) {
77            throw new PineconeException('Failed to cancel import: ' . $e->getMessage(), 0, $e);
78        }
79    }
80
81    // Namespace operations
82    public function listNamespaces(): array
83    {
84        try {
85            $response = $this->httpClient->get('/describe_index_stats');
86            $data = $this->handleResponse($response);
87
88            return array_keys($data['namespaces'] ?? []);
89        } catch (GuzzleException $e) {
90            throw new PineconeException('Failed to list namespaces: ' . $e->getMessage(), 0, $e);
91        }
92    }
93
94    public function describeNamespace(string $namespace): array
95    {
96        try {
97            $response = $this->httpClient->post('/describe_index_stats', [
98                'json' => (object) ['filter' => ['namespace' => $namespace]]
99            ]);
100            $data = $this->handleResponse($response);
101
102            return $data['namespaces'][$namespace] ?? [];
103        } catch (GuzzleException $e) {
104            throw new PineconeException('Failed to describe namespace: ' . $e->getMessage(), 0, $e);
105        }
106    }
107
108    public function deleteNamespace(string $namespace): void
109    {
110        try {
111            $this->httpClient->post('/vectors/delete', [
112                'json' => ['deleteAll' => true, 'namespace' => $namespace]
113            ]);
114        } catch (GuzzleException $e) {
115            throw new PineconeException('Failed to delete namespace: ' . $e->getMessage(), 0, $e);
116        }
117    }
118
119    public function namespace(string $namespace): IndexNamespace
120    {
121        return new IndexNamespace($this->dataPlane, $namespace);
122    }
123
124    private function handleResponse(ResponseInterface $response): array
125    {
126        $statusCode = $response->getStatusCode();
127        $body = $response->getBody()->getContents();
128
129        if ($statusCode >= 400) {
130            $data = json_decode($body, true) ?? [];
131            $message = $data['message'] ?? 'API request failed';
132            throw new PineconeApiException($message, $statusCode, $data);
133        }
134
135        if (empty($body)) {
136            return [];
137        }
138
139        $decoded = json_decode($body, true);
140        if (json_last_error() !== JSON_ERROR_NONE) {
141            throw new PineconeException('Failed to decode JSON response: ' . json_last_error_msg());
142        }
143
144        return $decoded;
145    }
146}