1use rusqlite::Connection;
2
3#[path = "code_query.rs"]
4mod code_query;
5
6#[path = "code_query_hits.rs"]
7mod code_query_hits;
8
9#[path = "code_query_scope.rs"]
10mod code_query_scope;
11
12#[path = "code_impact.rs"]
13mod code_impact;
14
15#[path = "code_report.rs"]
16mod code_report;
17
18#[path = "code_schema.rs"]
19mod code_schema;
20
21#[path = "code_status.rs"]
22mod code_status;
23
24#[path = "code_batch.rs"]
25mod code_batch;
26
27#[path = "code_cleanup.rs"]
28mod code_cleanup;
29
30#[path = "code_tasks.rs"]
31mod code_tasks;
32
33#[path = "code_search.rs"]
34mod code_search;
35
36#[path = "code_snapshot.rs"]
37mod code_snapshot;
38
39#[path = "code_set.rs"]
40mod code_set;
41
42#[path = "code_set_tasks.rs"]
43mod code_set_tasks;
44
45#[cfg(test)]
46#[path = "code_tests.rs"]
47mod code_tests;
48
49#[cfg(test)]
50#[path = "code_incremental_search_tests.rs"]
51mod code_incremental_search_tests;
52
53#[cfg(test)]
54#[path = "code_batch_finalize_tests.rs"]
55mod code_batch_finalize_tests;
56
57#[cfg(test)]
58#[path = "code_batch_finalize_typescript_tests.rs"]
59mod code_batch_finalize_typescript_tests;
60
61#[cfg(test)]
62#[path = "code_batch_search_tests.rs"]
63mod code_batch_search_tests;
64
65#[cfg(test)]
66#[path = "code_query_accuracy_tests.rs"]
67mod code_query_accuracy_tests;
68
69#[cfg(test)]
70#[path = "code_query_import_target_tests.rs"]
71mod code_query_import_target_tests;
72
73#[cfg(test)]
74#[path = "code_query_import_ranking_tests.rs"]
75mod code_query_import_ranking_tests;
76
77#[cfg(test)]
78#[path = "code_query_line_context_tests.rs"]
79mod code_query_line_context_tests;
80
81#[cfg(test)]
82#[path = "code_metadata_tests.rs"]
83mod code_metadata_tests;
84
85#[cfg(test)]
86#[path = "code_tasks_tests.rs"]
87mod code_tasks_tests;
88
89#[cfg(test)]
90#[path = "code_set_tasks_tests.rs"]
91mod code_set_tasks_tests;
92
93#[cfg(test)]
94#[path = "code_set_tests.rs"]
95mod code_set_tests;
96
97use crate::{
98 domain::{
99 CodeFileFingerprint, CodeImpactRequest, CodeIndexBatch, CodeIndexCheckpoint,
100 CodeIndexSession, CodeIndexSnapshot, CodeIndexSummary, CodeRepositoryRegistration,
101 CodeRepositoryReport, CodeRepositoryStatus, CodeRepositoryTotals, CodeRetrievalHit,
102 CodeRetrievalRequest,
103 },
104 storage::{CodeImpactChanges, CodeRepositoryStore, StorageError, StorageFuture},
105};
106
107use super::SqliteGraphStore;
108pub(super) use code_search::SearchDocumentInserter;
109
110const MAX_SYMBOL_SIGNATURE_LOOKUP_IDS_PER_STATEMENT: usize = 500;
111
112pub(super) fn initialize_code_schema(connection: &Connection) -> Result<(), StorageError> {
113 code_schema::initialize_code_schema(connection)
114}
115
116impl CodeRepositoryStore for SqliteGraphStore {
117 fn upsert_code_repository(
118 &self,
119 registration: CodeRepositoryRegistration,
120 ) -> StorageFuture<'_, CodeRepositoryStatus> {
121 self.run(move |connection| code_status::upsert_repository(connection, registration))
122 }
123
124 fn code_repository_status(
125 &self,
126 repository: String,
127 ) -> StorageFuture<'_, Option<CodeRepositoryStatus>> {
128 self.run(move |connection| code_status::repository_status(connection, &repository))
129 }
130
131 fn code_repository_scope_status(
132 &self,
133 repository: String,
134 resolved_commit_sha: String,
135 path_filters: Vec<String>,
136 language_filters: Vec<String>,
137 ) -> StorageFuture<'_, Option<CodeRepositoryStatus>> {
138 self.run(move |connection| {
139 code_status::repository_scope_status(
140 connection,
141 &repository,
142 &resolved_commit_sha,
143 &path_filters,
144 &language_filters,
145 )
146 })
147 }
148
149 fn queue_code_index_task(
150 &self,
151 task: crate::storage::CodeIndexTaskSeed,
152 ) -> StorageFuture<'_, crate::domain::CodeIndexTaskRecord> {
153 self.run(move |connection| code_tasks::queue_task(connection, task))
154 }
155
156 fn claim_code_index_task(
157 &self,
158 request: crate::storage::CodeIndexTaskClaimRequest,
159 ) -> StorageFuture<'_, Option<crate::domain::CodeIndexTaskRecord>> {
160 self.run(move |connection| code_tasks::claim_task(connection, request))
161 }
162
163 fn complete_code_index_task(
164 &self,
165 request: crate::storage::CodeIndexTaskCompletion,
166 ) -> StorageFuture<'_, crate::domain::CodeIndexTaskRecord> {
167 self.run(move |connection| code_tasks::complete_task(connection, request))
168 }
169
170 fn fail_code_index_task(
171 &self,
172 request: crate::storage::CodeIndexTaskFailure,
173 ) -> StorageFuture<'_, crate::domain::CodeIndexTaskRecord> {
174 self.run(move |connection| code_tasks::fail_task(connection, request))
175 }
176
177 fn code_index_task(
178 &self,
179 task_id: String,
180 ) -> StorageFuture<'_, Option<crate::domain::CodeIndexTaskRecord>> {
181 self.run(move |connection| code_tasks::task_by_id(connection, &task_id))
182 }
183
184 fn active_code_index_task(
185 &self,
186 repository_id: String,
187 ) -> StorageFuture<'_, Option<crate::domain::CodeIndexTaskRecord>> {
188 self.run(move |connection| code_tasks::active_task(connection, &repository_id))
189 }
190
191 fn code_index_checkpoint(
192 &self,
193 source_scope: String,
194 ) -> StorageFuture<'_, Option<crate::domain::CodeIndexCheckpoint>> {
195 self.run(move |connection| code_tasks::checkpoint(connection, &source_scope))
196 }
197
198 fn code_scope_retention(
199 &self,
200 repository_id: String,
201 ) -> StorageFuture<'_, crate::domain::CodeScopeRetentionSummary> {
202 self.run(move |connection| code_tasks::retention_status(connection, &repository_id))
203 }
204
205 fn prune_code_repository_scopes(
206 &self,
207 request: crate::storage::CodeScopeRetentionRequest,
208 ) -> StorageFuture<'_, crate::domain::CodeScopeRetentionSummary> {
209 self.run(move |connection| code_tasks::prune_scopes(connection, request))
210 }
211
212 fn code_file_fingerprints(
213 &self,
214 repository_id: String,
215 ) -> StorageFuture<'_, Vec<CodeFileFingerprint>> {
216 self.run(move |connection| code_snapshot::file_fingerprints(connection, &repository_id))
217 }
218
219 fn code_file_fingerprints_for_scope(
220 &self,
221 source_scope: String,
222 ) -> StorageFuture<'_, Vec<CodeFileFingerprint>> {
223 self.run(move |connection| {
224 code_snapshot::file_fingerprints_for_scope(connection, &source_scope)
225 })
226 }
227
228 fn code_file_candidate_paths_for_scope(
229 &self,
230 source_scope: String,
231 path_filters: Vec<String>,
232 language_filters: Vec<String>,
233 limit: usize,
234 ) -> StorageFuture<'_, Vec<String>> {
235 self.run(move |connection| {
236 code_snapshot::file_candidate_paths_for_scope(
237 connection,
238 &source_scope,
239 &path_filters,
240 &language_filters,
241 limit,
242 )
243 })
244 }
245
246 fn apply_code_index_snapshot(
247 &self,
248 snapshot: CodeIndexSnapshot,
249 ) -> StorageFuture<'_, CodeIndexSummary> {
250 self.run(move |connection| code_snapshot::apply_snapshot(connection, snapshot))
251 }
252
253 fn begin_code_index_session(
254 &self,
255 session: CodeIndexSession,
256 ) -> StorageFuture<'_, CodeIndexCheckpoint> {
257 self.run(move |connection| code_batch::begin_session(connection, session))
258 }
259
260 fn apply_code_index_batch(
261 &self,
262 batch: CodeIndexBatch,
263 ) -> StorageFuture<'_, CodeIndexCheckpoint> {
264 self.run(move |connection| code_batch::apply_batch(connection, batch))
265 }
266
267 fn finalize_code_index_session(
268 &self,
269 session: CodeIndexSession,
270 ) -> StorageFuture<'_, CodeIndexSummary> {
271 self.run(move |connection| code_batch::finalize_session(connection, session))
272 }
273
274 fn search_code(
275 &self,
276 request: CodeRetrievalRequest,
277 ) -> StorageFuture<'_, Vec<CodeRetrievalHit>> {
278 self.run(move |connection| code_query::search_code(connection, request))
279 }
280
281 fn search_code_scope(
282 &self,
283 source_scope: String,
284 request: CodeRetrievalRequest,
285 ) -> StorageFuture<'_, Vec<CodeRetrievalHit>> {
286 self.run(move |connection| {
287 code_query::search_code_scope(connection, &source_scope, request)
288 })
289 }
290
291 fn analyze_code_impact(
292 &self,
293 request: CodeImpactRequest,
294 changes: CodeImpactChanges,
295 ) -> StorageFuture<'_, Vec<CodeRetrievalHit>> {
296 self.run(move |connection| code_impact::analyze_impact(connection, request, changes))
297 }
298
299 fn code_repository_totals(&self) -> StorageFuture<'_, CodeRepositoryTotals> {
300 self.run(code_report::repository_totals)
301 }
302
303 fn code_repository_report(
304 &self,
305 repository: String,
306 ) -> StorageFuture<'_, CodeRepositoryReport> {
307 self.run(move |connection| code_report::repository_report(connection, &repository))
308 }
309
310 fn create_code_repository_set(
311 &self,
312 seed: crate::storage::CodeRepositorySetSeed,
313 ) -> StorageFuture<'_, crate::domain::CodeRepositorySet> {
314 self.run(move |connection| code_set::create_set(connection, seed))
315 }
316
317 fn add_code_repository_set_member(
318 &self,
319 seed: crate::storage::CodeRepositorySetMemberSeed,
320 ) -> StorageFuture<'_, crate::domain::CodeRepositorySetMember> {
321 self.run(move |connection| code_set::add_member(connection, seed))
322 }
323
324 fn remove_code_repository_set_member(
325 &self,
326 set_alias: String,
327 repository_alias: String,
328 ) -> StorageFuture<'_, crate::domain::CodeRepositorySetMember> {
329 self.run(move |connection| {
330 code_set::remove_member(connection, &set_alias, &repository_alias)
331 })
332 }
333
334 fn code_repository_set(
335 &self,
336 set_alias: String,
337 ) -> StorageFuture<'_, Option<crate::domain::CodeRepositorySet>> {
338 self.run(move |connection| code_set::set_by_alias(connection, &set_alias))
339 }
340
341 fn code_repository_set_status(
342 &self,
343 set_alias: String,
344 ) -> StorageFuture<'_, Option<crate::domain::CodeRepositorySetStatus>> {
345 self.run(move |connection| code_set::set_status(connection, &set_alias))
346 }
347
348 fn refresh_code_repository_set_overlay(
349 &self,
350 set_alias: String,
351 now_ms: u64,
352 ) -> StorageFuture<'_, crate::domain::CodeRepositorySetRefreshSummary> {
353 self.run(move |connection| code_set::refresh_overlay(connection, &set_alias, now_ms))
354 }
355
356 fn code_repository_set_cross_edges(
357 &self,
358 set_id: String,
359 ) -> StorageFuture<'_, Vec<crate::domain::CodeRepositoryCrossEdge>> {
360 self.run(move |connection| code_set::cross_edges_for_set(connection, &set_id))
361 }
362
363 fn queue_code_repository_set_refresh_task(
364 &self,
365 task: crate::storage::CodeRepositorySetRefreshTaskSeed,
366 ) -> StorageFuture<'_, crate::domain::CodeRepositorySetRefreshTaskRecord> {
367 self.run(move |connection| code_set_tasks::queue_refresh_task(connection, task))
368 }
369
370 fn claim_code_repository_set_refresh_task(
371 &self,
372 request: crate::storage::CodeRepositorySetRefreshTaskClaimRequest,
373 ) -> StorageFuture<'_, Option<crate::domain::CodeRepositorySetRefreshTaskRecord>> {
374 self.run(move |connection| code_set_tasks::claim_refresh_task(connection, request))
375 }
376
377 fn complete_code_repository_set_refresh_task(
378 &self,
379 request: crate::storage::CodeRepositorySetRefreshTaskCompletion,
380 ) -> StorageFuture<'_, crate::domain::CodeRepositorySetRefreshTaskRecord> {
381 self.run(move |connection| code_set_tasks::complete_refresh_task(connection, request))
382 }
383
384 fn fail_code_repository_set_refresh_task(
385 &self,
386 request: crate::storage::CodeRepositorySetRefreshTaskFailure,
387 ) -> StorageFuture<'_, crate::domain::CodeRepositorySetRefreshTaskRecord> {
388 self.run(move |connection| code_set_tasks::fail_refresh_task(connection, request))
389 }
390}