server: add not_modified check when no 'to' param

This commit is contained in:
nym21
2025-03-31 17:19:33 +02:00
parent cc5091e28c
commit 655b99cac8
9 changed files with 103 additions and 45 deletions

View File

@@ -22,7 +22,7 @@ pub fn query(params: QueryParams) -> color_eyre::Result<()> {
let ids = params.values.iter().map(|s| s.as_str()).collect::<Vec<_>>();
let res = query.search(index, &ids, params.from, params.to, params.format)?;
let res = query.search_and_format(index, &ids, params.from, params.to, params.format)?;
if params.format.is_some() {
println!("{}", res);

View File

@@ -193,6 +193,7 @@ where
Ok(())
}
#[allow(clippy::wrong_self_convention)]
pub fn from_aligned<I2>(
&mut self,
max_from: I,

View File

@@ -1,10 +1,7 @@
use std::ops::{Add, Div};
use derive_deref::Deref;
use jiff::{
civil::{Time, date},
tz::TimeZone,
};
use jiff::{civil::date, tz::TimeZone};
use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};

View File

@@ -20,8 +20,8 @@ impl StoreMeta {
pub fn checked_open(path: &Path, version: Version) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
let is_same_version =
Version::try_from(Self::path_version_(path).as_path()).is_ok_and(|prev_version| version == prev_version);
let is_same_version = Version::try_from(Self::path_version_(path).as_path())
.is_ok_and(|prev_version| version == prev_version);
if !is_same_version {
Self::reset_(path)?;
@@ -92,7 +92,7 @@ impl StoreMeta {
fn write_length(&self) -> io::Result<()> {
Self::write_length_(&self.pathbuf, self.len)
}
fn write_length_(path: &Path, len: usize) -> Result<(), io::Error> {
fn write_length_(path: &Path, len: usize) -> io::Result<()> {
fs::write(Self::path_length(path), len.as_bytes())
}
fn path_length(path: &Path) -> PathBuf {

View File

@@ -19,9 +19,9 @@ pub fn main() -> color_eyre::Result<()> {
let query = Query::build(&indexer, &computer);
dbg!(query.search(Index::Height, &["date"], Some(-1), None, None)?);
dbg!(query.search(Index::Height, &["date"], Some(-10), None, None)?);
dbg!(query.search(Index::Height, &["date", "timestamp"], Some(-10), None, None)?);
dbg!(query.search_and_format(Index::Height, &["date"], Some(-1), None, None)?);
dbg!(query.search_and_format(Index::Height, &["date"], Some(-10), None, None)?);
dbg!(query.search_and_format(Index::Height, &["date", "timestamp"], Some(-10), None, None)?);
Ok(())
}

View File

@@ -5,6 +5,7 @@
use brk_computer::Computer;
use brk_indexer::Indexer;
use brk_vec::AnyStorableVec;
use tabled::settings::Style;
mod format;
@@ -50,14 +51,7 @@ impl<'a> Query<'a> {
}
}
pub fn search(
&self,
index: Index,
ids: &[&str],
from: Option<i64>,
to: Option<i64>,
format: Option<Format>,
) -> color_eyre::Result<Output> {
pub fn search(&self, index: Index, ids: &[&str]) -> Vec<(String, &&dyn AnyStorableVec)> {
let tuples = ids
.iter()
.flat_map(|s| {
@@ -84,14 +78,22 @@ impl<'a> Query<'a> {
.map(|(id, vec)| (id, vec.unwrap()))
.collect::<Vec<_>>();
if tuples.is_empty() {
return Ok(Output::default(format));
}
let mut values = tuples
tuples
.iter()
.flat_map(|(_, i_to_v)| i_to_v.get(&index))
.map(|vec| -> brk_vec::Result<Vec<serde_json::Value>> {
.flat_map(|(str, i_to_v)| i_to_v.get(&index).map(|vec| (str.to_owned(), vec)))
.collect::<Vec<_>>()
}
pub fn format(
&self,
vecs: Vec<(String, &&dyn AnyStorableVec)>,
from: Option<i64>,
to: Option<i64>,
format: Option<Format>,
) -> color_eyre::Result<Output> {
let mut values = vecs
.iter()
.map(|(_, vec)| -> brk_vec::Result<Vec<serde_json::Value>> {
vec.collect_range_values(from, to)
})
.collect::<brk_vec::Result<Vec<_>>>()?;
@@ -100,7 +102,7 @@ impl<'a> Query<'a> {
return Ok(Output::default(format));
}
let ids_last_i = tuples.len() - 1;
let ids_last_i = vecs.len() - 1;
Ok(match format {
Some(Format::CSV) | Some(Format::TSV) => {
@@ -110,9 +112,9 @@ impl<'a> Query<'a> {
'\t'
};
let mut text = tuples
.into_iter()
.map(|(id, _)| id)
let mut text = vecs
.iter()
.map(|(id, _)| id.to_owned())
.collect::<Vec<_>>()
.join(&delimiter.to_string());
@@ -141,7 +143,7 @@ impl<'a> Query<'a> {
}
Some(Format::MD) => {
let mut table =
values.to_table(tuples.iter().map(|(s, _)| s.to_owned()).collect::<Vec<_>>());
values.to_table(vecs.iter().map(|(s, _)| s.to_owned()).collect::<Vec<_>>());
table.with(Style::markdown());
@@ -162,4 +164,15 @@ impl<'a> Query<'a> {
}
})
}
pub fn search_and_format(
&self,
index: Index,
ids: &[&str],
from: Option<i64>,
to: Option<i64>,
format: Option<Format>,
) -> color_eyre::Result<Output> {
self.format(self.search(index, ids), from, to, format)
}
}

View File

@@ -8,7 +8,10 @@ use axum::{
};
use brk_query::{Format, Index, Output, Params};
use crate::{log_result, traits::HeaderMapExtended};
use crate::{
log_result,
traits::{HeaderMapExtended, ModifiedState, ResponseExtended},
};
use super::AppState;
@@ -52,13 +55,32 @@ fn req_to_response_res(
) -> color_eyre::Result<Response> {
let index = Index::try_from(index.as_str())?;
let output = query.search(
let vecs = query.search(
index,
&values.iter().map(|v| v.as_str()).collect::<Vec<_>>(),
from,
to,
format,
)?;
);
let mut date_modified_opt = None;
if to.is_none() {
let not_modified = vecs
.iter()
.map(|(_, vec)| headers.check_if_modified_since(&vec.path_vec()))
.all(|res| {
res.is_ok_and(|(modified, date_modified)| {
if date_modified_opt.is_none_or(|dm| dm > date_modified) {
date_modified_opt.replace(date_modified);
}
modified == ModifiedState::NotModifiedSince
})
});
if not_modified {
return Ok(Response::new_not_modified());
}
}
let output = query.format(vecs, from, to, format)?;
let mut response = match output {
Output::CSV(s) => s.into_response(),
@@ -74,7 +96,10 @@ fn req_to_response_res(
let headers = response.headers_mut();
headers.insert_cors();
// headers.insert_last_modified(date_modified);
if let Some(date_modified) = date_modified_opt {
headers.insert_last_modified(date_modified);
}
match format {
Some(format) => {

View File

@@ -26,7 +26,8 @@ pub trait HeaderMapExtended {
fn insert_cors(&mut self);
fn get_if_modified_since(&self) -> Option<DateTime>;
fn check_if_modified_since(&self, path: &Path) -> color_eyre::Result<(ModifiedState, DateTime)>;
fn check_if_modified_since(&self, path: &Path)
-> color_eyre::Result<(ModifiedState, DateTime)>;
fn insert_cache_control_immutable(&mut self);
#[allow(unused)]
@@ -114,8 +115,15 @@ impl HeaderMapExtended for HeaderMap {
self.insert(header::LAST_MODIFIED, formatted.parse().unwrap());
}
fn check_if_modified_since(&self, path: &Path) -> color_eyre::Result<(ModifiedState, DateTime)> {
let duration = path.metadata()?.modified()?.duration_since(time::UNIX_EPOCH).unwrap();
fn check_if_modified_since(
&self,
path: &Path,
) -> color_eyre::Result<(ModifiedState, DateTime)> {
let duration = path
.metadata()?
.modified()?
.duration_since(time::UNIX_EPOCH)
.unwrap();
let date = Timestamp::new(duration.as_secs() as i64, 0)
.unwrap()
.to_zoned(TimeZone::UTC)
@@ -177,7 +185,10 @@ impl HeaderMapExtended for HeaderMap {
}
fn insert_content_type_application_javascript(&mut self) {
self.insert(header::CONTENT_TYPE, "application/javascript".parse().unwrap());
self.insert(
header::CONTENT_TYPE,
"application/javascript".parse().unwrap(),
);
}
fn insert_content_type_application_json(&mut self) {
@@ -185,7 +196,10 @@ impl HeaderMapExtended for HeaderMap {
}
fn insert_content_type_application_manifest_json(&mut self) {
self.insert(header::CONTENT_TYPE, "application/manifest+json".parse().unwrap());
self.insert(
header::CONTENT_TYPE,
"application/manifest+json".parse().unwrap(),
);
}
fn insert_content_type_application_pdf(&mut self) {
@@ -201,7 +215,10 @@ impl HeaderMapExtended for HeaderMap {
}
fn insert_content_type_text_tsv(&mut self) {
self.insert(header::CONTENT_TYPE, "text/tab-separated-values".parse().unwrap());
self.insert(
header::CONTENT_TYPE,
"text/tab-separated-values".parse().unwrap(),
);
}
fn insert_content_type_text_html(&mut self) {

View File

@@ -1,4 +1,4 @@
use std::io;
use std::{io, path::PathBuf};
use crate::{Result, StorableVec};
@@ -15,6 +15,7 @@ pub trait AnyStorableVec: Send + Sync {
to: Option<i64>,
) -> Result<Vec<serde_json::Value>>;
fn flush(&mut self) -> io::Result<()>;
fn path_vec(&self) -> PathBuf;
}
impl<I, T> AnyStorableVec for StorableVec<I, T>
@@ -53,4 +54,8 @@ where
.map(|v| serde_json::to_value(v).unwrap())
.collect::<Vec<_>>())
}
fn path_vec(&self) -> PathBuf {
self.base().path_vec()
}
}