mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-05 19:59:09 -07:00
server: use query for search
This commit is contained in:
@@ -16,14 +16,10 @@ pub fn query(params: QueryParams) -> color_eyre::Result<()> {
|
||||
|
||||
let query = Query::build(&indexer, &computer);
|
||||
|
||||
let ids = params
|
||||
.values
|
||||
.iter()
|
||||
.flat_map(|v| v.split(","))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let index = Index::try_from(params.index.as_str())?;
|
||||
|
||||
let ids = params.values.iter().map(|s| s.as_str()).collect::<Vec<_>>();
|
||||
|
||||
let res = query.search(index, &ids, params.from, params.to, params.format)?;
|
||||
|
||||
if params.format.is_some() {
|
||||
|
||||
@@ -58,9 +58,6 @@ impl Computer {
|
||||
let txinindexes_count = indexer.vecs().txinindex_to_txoutindex.len();
|
||||
let txoutindexes_count = indexer.vecs().txoutindex_to_addressindex.len();
|
||||
|
||||
// TODO: Remove all outdated
|
||||
|
||||
// self.vecs.txindex_to_last_txinindex.compute_last_index_from_first(
|
||||
// starting_indexes.txindex,
|
||||
// &mut indexer.vecs().txindex_to_first_txinindex,
|
||||
// txinindexes_count,
|
||||
|
||||
@@ -5,9 +5,14 @@ use serde::Deserialize;
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, ValueEnum, Deserialize)]
|
||||
pub enum Format {
|
||||
#[serde(alias = "json")]
|
||||
JSON,
|
||||
#[serde(alias = "csv")]
|
||||
CSV,
|
||||
#[serde(alias = "tsv")]
|
||||
TSV,
|
||||
#[serde(alias = "md", alias = "markdown")]
|
||||
#[value(alias("markdown"))]
|
||||
MD,
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ impl Index {
|
||||
impl TryFrom<&str> for Index {
|
||||
type Error = color_eyre::Report;
|
||||
fn try_from(value: &str) -> Result<Self, Self::Error> {
|
||||
Ok(match value {
|
||||
Ok(match value.to_lowercase().as_str() {
|
||||
v if (Self::Dateindex).possible_values().contains(&v) => Self::Dateindex,
|
||||
v if (Self::Height).possible_values().contains(&v) => Self::Height,
|
||||
v if (Self::Txindex).possible_values().contains(&v) => Self::Txindex,
|
||||
|
||||
@@ -60,8 +60,17 @@ impl<'a> Query<'a> {
|
||||
) -> color_eyre::Result<Output> {
|
||||
let tuples = ids
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let mut id = s.to_lowercase().replace("_", "-");
|
||||
.flat_map(|s| {
|
||||
s.to_lowercase()
|
||||
.replace("_", "-")
|
||||
.split_whitespace()
|
||||
.flat_map(|s| {
|
||||
s.split(',')
|
||||
.flat_map(|s| s.split('+').map(|s| s.to_string()))
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.map(|mut id| {
|
||||
let mut res = self.vecid_to_index_to_vec.get(&id);
|
||||
if res.is_none() {
|
||||
if let Ok(index) = Index::try_from(id.as_str()) {
|
||||
|
||||
@@ -21,7 +21,7 @@ color-eyre = { workspace = true }
|
||||
jiff = { workspace = true }
|
||||
log = { workspace = true }
|
||||
minreq = { workspace = true }
|
||||
oxc = { version = "0.54.0", features = ["codegen", "minifier"] }
|
||||
oxc = { version = "0.55.0", features = ["codegen", "minifier"] }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { version = "1.43.0", features = ["full"] }
|
||||
|
||||
@@ -6,7 +6,7 @@ use axum::{
|
||||
http::{HeaderMap, StatusCode, Uri},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use brk_query::{Format, Index, Params};
|
||||
use brk_query::{Format, Index, Output, Params};
|
||||
use color_eyre::eyre::eyre;
|
||||
use serde_json::Value;
|
||||
|
||||
@@ -34,7 +34,8 @@ pub async fn handler(
|
||||
response
|
||||
}
|
||||
Err(error) => {
|
||||
let mut response = (StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response();
|
||||
let mut response =
|
||||
(StatusCode::INTERNAL_SERVER_ERROR, error.to_string()).into_response();
|
||||
log_result(response.status(), path, instant);
|
||||
response.headers_mut().insert_cors();
|
||||
response
|
||||
@@ -53,89 +54,25 @@ fn req_to_response_res(
|
||||
}): AxumQuery<Params>,
|
||||
AppState { query, .. }: AppState,
|
||||
) -> color_eyre::Result<Response> {
|
||||
let indexes = index
|
||||
.to_lowercase()
|
||||
.split(",")
|
||||
.flat_map(|s| Index::try_from(s).ok())
|
||||
.collect::<Vec<_>>();
|
||||
let index = Index::try_from(index.as_str())?;
|
||||
|
||||
if indexes.len() > 1 {
|
||||
return Err(eyre!("Multiple indexes aren't supported"));
|
||||
} else if indexes.is_empty() {
|
||||
return Err(eyre!("Unknown index"));
|
||||
}
|
||||
let output = query.search(
|
||||
index,
|
||||
&values.iter().map(|v| v.as_str()).collect::<Vec<_>>(),
|
||||
from,
|
||||
to,
|
||||
format,
|
||||
)?;
|
||||
|
||||
let ids = values
|
||||
.into_iter()
|
||||
.map(|v| v.to_lowercase())
|
||||
.flat_map(|v| v.split(",").map(|v| v.to_owned()).collect::<Vec<_>>())
|
||||
.map(|s| {
|
||||
let opt = query.vecid_to_index_to_vec.get(&s.replace("_", "-"));
|
||||
(s, opt)
|
||||
})
|
||||
.filter(|(_, opt)| opt.is_some())
|
||||
.map(|(id, vec)| (id, vec.unwrap()))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
if ids.is_empty() {
|
||||
return Ok(Json(()).into_response());
|
||||
}
|
||||
|
||||
let values = ids
|
||||
.iter()
|
||||
.flat_map(|(_, i_to_v)| i_to_v.get(indexes.first().unwrap()))
|
||||
.map(|vec| -> brk_vec::Result<Vec<Value>> { vec.collect_range_values(from, to) })
|
||||
.collect::<brk_vec::Result<Vec<_>>>()?;
|
||||
|
||||
if ids.is_empty() {
|
||||
return Ok(Json(()).into_response());
|
||||
}
|
||||
|
||||
let ids_last_i = ids.len() - 1;
|
||||
|
||||
let mut response = match format {
|
||||
Some(Format::CSV) | Some(Format::TSV) => {
|
||||
let delimiter = if format == Some(Format::CSV) { ',' } else { '\t' };
|
||||
|
||||
let mut csv = ids
|
||||
.into_iter()
|
||||
.map(|(id, _)| id)
|
||||
.collect::<Vec<_>>()
|
||||
.join(&delimiter.to_string());
|
||||
|
||||
csv.push('\n');
|
||||
|
||||
let values_len = values.first().unwrap().len();
|
||||
|
||||
(0..values_len).for_each(|i| {
|
||||
let mut line = "".to_string();
|
||||
values.iter().enumerate().for_each(|(id_i, v)| {
|
||||
line += &v.get(i).unwrap().to_string();
|
||||
if id_i == ids_last_i {
|
||||
line.push('\n');
|
||||
} else {
|
||||
line.push(delimiter);
|
||||
}
|
||||
});
|
||||
csv += &line;
|
||||
});
|
||||
|
||||
csv.into_response()
|
||||
}
|
||||
Some(Format::MD) => "".into_response(),
|
||||
Some(Format::JSON) | None => {
|
||||
if values.len() == 1 {
|
||||
let values = values.first().unwrap();
|
||||
if values.len() == 1 {
|
||||
let value = values.first().unwrap();
|
||||
Json(value).into_response()
|
||||
} else {
|
||||
Json(values).into_response()
|
||||
}
|
||||
} else {
|
||||
Json(values).into_response()
|
||||
}
|
||||
}
|
||||
let mut response = match output {
|
||||
Output::CSV(s) => s.into_response(),
|
||||
Output::TSV(s) => s.into_response(),
|
||||
Output::Json(v) => match v {
|
||||
brk_query::Value::Single(v) => Json(v).into_response(),
|
||||
brk_query::Value::List(l) => Json(l).into_response(),
|
||||
brk_query::Value::Matrix(m) => Json(m).into_response(),
|
||||
},
|
||||
Output::MD(s) => s.into_response(),
|
||||
};
|
||||
|
||||
let headers = response.headers_mut();
|
||||
|
||||
@@ -40,6 +40,9 @@ const DEV_PATH: &str = "../..";
|
||||
const DOWNLOADS: &str = "downloads";
|
||||
const WEBSITES: &str = "websites";
|
||||
|
||||
// TODO
|
||||
pub struct Server;
|
||||
|
||||
pub async fn main(
|
||||
indexer: Indexer,
|
||||
computer: Computer,
|
||||
|
||||
Reference in New Issue
Block a user