| 13 |
13 |
|
SearchRepository, SearchResultItem, SearchResultType, UserId,
|
| 14 |
14 |
|
};
|
| 15 |
15 |
|
|
| 16 |
|
- |
use crate::utils::{escape_like, parse_uuid};
|
|
16 |
+ |
use crate::utils::{escape_like, format_datetime, parse_uuid};
|
| 17 |
17 |
|
|
| 18 |
18 |
|
/// SQLite-backed implementation of [`SearchRepository`].
|
| 19 |
19 |
|
///
|
| 468 |
468 |
|
param_idx += 1;
|
| 469 |
469 |
|
}
|
| 470 |
470 |
|
|
| 471 |
|
- |
// Date filters
|
|
471 |
+ |
// Date filters. Compare the stored `received_at` text directly (it is written
|
|
472 |
+ |
// in the sortable "%Y-%m-%d %H:%M:%S" format, so lexicographic order is
|
|
473 |
+ |
// chronological) rather than wrapping it in datetime(): the old code queried a
|
|
474 |
+ |
// nonexistent `e.date` column (a runtime error on any dated search) and the
|
|
475 |
+ |
// datetime() wrap was also non-sargable. Bind the bound in the same format so
|
|
476 |
+ |
// the string comparison is correct and can use idx_emails_received_at.
|
| 472 |
477 |
|
if let Some(df) = &query.date_from {
|
| 473 |
|
- |
sql.push_str(&format!(
|
| 474 |
|
- |
" AND datetime(e.date) >= datetime(${})",
|
| 475 |
|
- |
param_idx
|
| 476 |
|
- |
));
|
| 477 |
|
- |
params.push(df.to_rfc3339());
|
|
478 |
+ |
sql.push_str(&format!(" AND e.received_at >= ${}", param_idx));
|
|
479 |
+ |
params.push(format_datetime(df));
|
| 478 |
480 |
|
param_idx += 1;
|
| 479 |
481 |
|
}
|
| 480 |
482 |
|
if let Some(dt) = &query.date_to {
|
| 481 |
|
- |
sql.push_str(&format!(
|
| 482 |
|
- |
" AND datetime(e.date) <= datetime(${})",
|
| 483 |
|
- |
param_idx
|
| 484 |
|
- |
));
|
| 485 |
|
- |
params.push(dt.to_rfc3339());
|
|
483 |
+ |
sql.push_str(&format!(" AND e.received_at <= ${}", param_idx));
|
|
484 |
+ |
params.push(format_datetime(dt));
|
| 486 |
485 |
|
}
|
| 487 |
486 |
|
|
| 488 |
487 |
|
sql.push_str(&format!(" ORDER BY rank LIMIT {}", per_type_limit));
|