Skip to main content

relay_knowledge/storage/sqlite/
code.rs

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}