Skip to content

Commit 16921c6

Browse files
committed
Revert "fix: convert sqlx macros to runtime queries for offline mode"
This reverts commit 91b6b29.
1 parent 91b6b29 commit 16921c6

1 file changed

Lines changed: 91 additions & 88 deletions

File tree

toki-api/src/domain/search/repository/postgres.rs

Lines changed: 91 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ impl SearchRepository for PgSearchRepository {
3434
) -> Result<Vec<SearchResult>> {
3535
// Build the hybrid search query with RRF
3636
// RRF formula: score = sum(1 / (k + rank)) where k=60 is standard
37-
let results = sqlx::query_as::<_, SearchResultRow>(
37+
let results = sqlx::query_as!(
38+
SearchResultRow,
3839
r#"
3940
WITH bm25_results AS (
40-
SELECT
41+
SELECT
4142
id,
4243
ts_rank_cd(search_vector, websearch_to_tsquery('english', $1)) as score,
4344
ROW_NUMBER() OVER (
@@ -56,7 +57,7 @@ impl SearchRepository for PgSearchRepository {
5657
LIMIT 100
5758
),
5859
vector_results AS (
59-
SELECT
60+
SELECT
6061
id,
6162
1 - (embedding <=> $10::vector) as score,
6263
ROW_NUMBER() OVER (
@@ -75,15 +76,15 @@ impl SearchRepository for PgSearchRepository {
7576
LIMIT 100
7677
),
7778
rrf_combined AS (
78-
SELECT
79+
SELECT
7980
COALESCE(b.id, v.id) as id,
8081
COALESCE(1.0 / (60 + b.rank), 0) + COALESCE(1.0 / (60 + v.rank), 0) as rrf_score
8182
FROM bm25_results b
8283
FULL OUTER JOIN vector_results v ON b.id = v.id
8384
)
84-
SELECT
85+
SELECT
8586
d.id,
86-
d.source_type,
87+
d.source_type as "source_type: SearchSource",
8788
d.source_id,
8889
d.external_id,
8990
d.title,
@@ -101,18 +102,18 @@ impl SearchRepository for PgSearchRepository {
101102
ORDER BY r.rrf_score DESC
102103
LIMIT $11
103104
"#,
105+
query.search_text,
106+
query.filters.source_type as Option<SearchSource>,
107+
query.filters.organization.as_deref(),
108+
query.filters.project.as_deref(),
109+
query.filters.status.as_deref(),
110+
query.filters.priority.as_deref(),
111+
query.filters.item_type.as_deref(),
112+
query.filters.is_draft,
113+
query.filters.updated_after,
114+
embedding as &[f32],
115+
limit
104116
)
105-
.bind(&query.search_text)
106-
.bind(query.filters.source_type)
107-
.bind(query.filters.organization.as_deref())
108-
.bind(query.filters.project.as_deref())
109-
.bind(query.filters.status.as_deref())
110-
.bind(query.filters.priority.as_deref())
111-
.bind(query.filters.item_type.as_deref())
112-
.bind(query.filters.is_draft)
113-
.bind(query.filters.updated_after)
114-
.bind(embedding)
115-
.bind(limit)
116117
.fetch_all(&self.pool)
117118
.await?;
118119

@@ -138,11 +139,11 @@ impl SearchRepository for PgSearchRepository {
138139
}
139140

140141
async fn upsert_document(&self, doc: &SearchDocument) -> Result<()> {
141-
sqlx::query(
142+
sqlx::query!(
142143
r#"
143144
INSERT INTO search_documents (
144145
source_type, source_id, external_id, title, description, content,
145-
organization, project, repo_name, status,
146+
organization, project, repo_name, status,
146147
author_id, author_name, assigned_to_id, assigned_to_name,
147148
priority, item_type, is_draft,
148149
created_at, updated_at, closed_at,
@@ -170,31 +171,31 @@ impl SearchRepository for PgSearchRepository {
170171
embedding = EXCLUDED.embedding,
171172
indexed_at = NOW()
172173
"#,
174+
doc.source_type as SearchSource,
175+
doc.source_id,
176+
doc.external_id,
177+
doc.title,
178+
doc.description.as_deref(),
179+
doc.content.as_deref(),
180+
doc.organization,
181+
doc.project,
182+
doc.repo_name.as_deref(),
183+
doc.status,
184+
doc.author_id.as_deref(),
185+
doc.author_name.as_deref(),
186+
doc.assigned_to_id.as_deref(),
187+
doc.assigned_to_name.as_deref(),
188+
doc.priority,
189+
doc.item_type.as_deref(),
190+
doc.is_draft,
191+
doc.created_at,
192+
doc.updated_at,
193+
doc.closed_at,
194+
doc.url,
195+
doc.parent_id,
196+
&doc.linked_work_items,
197+
doc.embedding.as_deref(),
173198
)
174-
.bind(doc.source_type)
175-
.bind(&doc.source_id)
176-
.bind(doc.external_id)
177-
.bind(&doc.title)
178-
.bind(doc.description.as_deref())
179-
.bind(doc.content.as_deref())
180-
.bind(&doc.organization)
181-
.bind(&doc.project)
182-
.bind(doc.repo_name.as_deref())
183-
.bind(&doc.status)
184-
.bind(doc.author_id.as_deref())
185-
.bind(doc.author_name.as_deref())
186-
.bind(doc.assigned_to_id.as_deref())
187-
.bind(doc.assigned_to_name.as_deref())
188-
.bind(doc.priority)
189-
.bind(doc.item_type.as_deref())
190-
.bind(doc.is_draft)
191-
.bind(doc.created_at)
192-
.bind(doc.updated_at)
193-
.bind(doc.closed_at)
194-
.bind(&doc.url)
195-
.bind(doc.parent_id)
196-
.bind(&doc.linked_work_items)
197-
.bind(doc.embedding.as_deref())
198199
.execute(&self.pool)
199200
.await?;
200201

@@ -206,7 +207,7 @@ impl SearchRepository for PgSearchRepository {
206207
let mut count = 0;
207208

208209
for doc in docs {
209-
sqlx::query(
210+
sqlx::query!(
210211
r#"
211212
INSERT INTO search_documents (
212213
source_type, source_id, external_id, title, description, content,
@@ -238,31 +239,31 @@ impl SearchRepository for PgSearchRepository {
238239
embedding = EXCLUDED.embedding,
239240
indexed_at = NOW()
240241
"#,
242+
doc.source_type as SearchSource,
243+
doc.source_id,
244+
doc.external_id,
245+
doc.title,
246+
doc.description.as_deref(),
247+
doc.content.as_deref(),
248+
doc.organization,
249+
doc.project,
250+
doc.repo_name.as_deref(),
251+
doc.status,
252+
doc.author_id.as_deref(),
253+
doc.author_name.as_deref(),
254+
doc.assigned_to_id.as_deref(),
255+
doc.assigned_to_name.as_deref(),
256+
doc.priority,
257+
doc.item_type.as_deref(),
258+
doc.is_draft,
259+
doc.created_at,
260+
doc.updated_at,
261+
doc.closed_at,
262+
doc.url,
263+
doc.parent_id,
264+
&doc.linked_work_items,
265+
doc.embedding.as_deref(),
241266
)
242-
.bind(doc.source_type)
243-
.bind(&doc.source_id)
244-
.bind(doc.external_id)
245-
.bind(&doc.title)
246-
.bind(doc.description.as_deref())
247-
.bind(doc.content.as_deref())
248-
.bind(&doc.organization)
249-
.bind(&doc.project)
250-
.bind(doc.repo_name.as_deref())
251-
.bind(&doc.status)
252-
.bind(doc.author_id.as_deref())
253-
.bind(doc.author_name.as_deref())
254-
.bind(doc.assigned_to_id.as_deref())
255-
.bind(doc.assigned_to_name.as_deref())
256-
.bind(doc.priority)
257-
.bind(doc.item_type.as_deref())
258-
.bind(doc.is_draft)
259-
.bind(doc.created_at)
260-
.bind(doc.updated_at)
261-
.bind(doc.closed_at)
262-
.bind(&doc.url)
263-
.bind(doc.parent_id)
264-
.bind(&doc.linked_work_items)
265-
.bind(doc.embedding.as_deref())
266267
.execute(&mut *tx)
267268
.await?;
268269
count += 1;
@@ -273,14 +274,14 @@ impl SearchRepository for PgSearchRepository {
273274
}
274275

275276
async fn delete_document(&self, source_type: SearchSource, source_id: &str) -> Result<bool> {
276-
let result = sqlx::query(
277+
let result = sqlx::query!(
277278
r#"
278279
DELETE FROM search_documents
279280
WHERE source_type = $1 AND source_id = $2
280281
"#,
282+
source_type as SearchSource,
283+
source_id
281284
)
282-
.bind(source_type)
283-
.bind(source_id)
284285
.execute(&self.pool)
285286
.await?;
286287

@@ -292,10 +293,11 @@ impl SearchRepository for PgSearchRepository {
292293
source_type: SearchSource,
293294
source_id: &str,
294295
) -> Result<Option<SearchDocument>> {
295-
let row = sqlx::query_as::<_, SearchDocumentRow>(
296+
let row = sqlx::query_as!(
297+
SearchDocumentRow,
296298
r#"
297-
SELECT
298-
source_type,
299+
SELECT
300+
source_type as "source_type: SearchSource",
299301
source_id,
300302
external_id,
301303
title,
@@ -321,9 +323,9 @@ impl SearchRepository for PgSearchRepository {
321323
FROM search_documents
322324
WHERE source_type = $1 AND source_id = $2
323325
"#,
326+
source_type as SearchSource,
327+
source_id
324328
)
325-
.bind(source_type)
326-
.bind(source_id)
327329
.fetch_optional(&self.pool)
328330
.await?;
329331

@@ -356,10 +358,11 @@ impl SearchRepository for PgSearchRepository {
356358
}
357359

358360
async fn get_stale_documents(&self, older_than: OffsetDateTime) -> Result<Vec<SearchDocument>> {
359-
let rows = sqlx::query_as::<_, SearchDocumentRow>(
361+
let rows = sqlx::query_as!(
362+
SearchDocumentRow,
360363
r#"
361-
SELECT
362-
source_type,
364+
SELECT
365+
source_type as "source_type: SearchSource",
363366
source_id,
364367
external_id,
365368
title,
@@ -385,8 +388,8 @@ impl SearchRepository for PgSearchRepository {
385388
FROM search_documents
386389
WHERE indexed_at < $1
387390
"#,
391+
older_than
388392
)
389-
.bind(older_than)
390393
.fetch_all(&self.pool)
391394
.await?;
392395

@@ -422,15 +425,17 @@ impl SearchRepository for PgSearchRepository {
422425
}
423426

424427
async fn count(&self, source_type: Option<SearchSource>) -> Result<i64> {
425-
let count: i64 = match source_type {
428+
let count = match source_type {
426429
Some(st) => {
427-
sqlx::query_scalar(r#"SELECT COUNT(*) FROM search_documents WHERE source_type = $1"#)
428-
.bind(st)
429-
.fetch_one(&self.pool)
430-
.await?
430+
sqlx::query_scalar!(
431+
r#"SELECT COUNT(*) as "count!" FROM search_documents WHERE source_type = $1"#,
432+
st as SearchSource
433+
)
434+
.fetch_one(&self.pool)
435+
.await?
431436
}
432437
None => {
433-
sqlx::query_scalar(r#"SELECT COUNT(*) FROM search_documents"#)
438+
sqlx::query_scalar!(r#"SELECT COUNT(*) as "count!" FROM search_documents"#)
434439
.fetch_one(&self.pool)
435440
.await?
436441
}
@@ -442,7 +447,6 @@ impl SearchRepository for PgSearchRepository {
442447

443448
// Row types for sqlx queries
444449

445-
#[derive(sqlx::FromRow)]
446450
#[allow(dead_code)]
447451
struct SearchResultRow {
448452
id: i32,
@@ -461,7 +465,6 @@ struct SearchResultRow {
461465
score: Option<f64>,
462466
}
463467

464-
#[derive(sqlx::FromRow)]
465468
#[allow(dead_code)]
466469
struct SearchDocumentRow {
467470
source_type: SearchSource,

0 commit comments

Comments
 (0)