mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-11 06:39:08 -07:00
server: add not_modified check when no 'to' param
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -193,6 +193,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[allow(clippy::wrong_self_convention)]
|
||||
pub fn from_aligned<I2>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user