Working unified index.

This commit is contained in:
Syfaro 2020-01-25 01:25:43 -06:00
parent 764f081338
commit ce52f145d9
4 changed files with 77 additions and 67 deletions

View File

@ -7,17 +7,17 @@ pub fn search(db: Pool) -> impl Filter<Extract = impl Reply, Error = Rejection>
search_image(db.clone())
.or(search_hashes(db.clone()))
.or(stream_search_image(db.clone()))
// .or(search_file(db))
.or(search_file(db))
}
// pub fn search_file(db: Pool) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
// warp::path("file")
// .and(warp::get())
// .and(warp::query::<FileSearchOpts>())
// .and(with_pool(db))
// .and(with_api_key())
// .and_then(handlers::search_file)
// }
pub fn search_file(db: Pool) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path("file")
.and(warp::get())
.and(warp::query::<FileSearchOpts>())
.and(with_pool(db))
.and(with_api_key())
.and_then(handlers::search_file)
}
pub fn search_image(db: Pool) -> impl Filter<Extract = impl Reply, Error = Rejection> + Clone {
warp::path("image")

View File

@ -206,68 +206,72 @@ pub async fn search_hashes(
Ok(warp::reply::json(&matches))
}
// pub async fn search_file(
// opts: FileSearchOpts,
// db: Pool,
// api_key: String,
// ) -> Result<impl Reply, Rejection> {
// let db = db.get().await.map_err(map_bb8_err)?;
pub async fn search_file(
opts: FileSearchOpts,
db: Pool,
api_key: String,
) -> Result<impl Reply, Rejection> {
let db = db.get().await.map_err(map_bb8_err)?;
// rate_limit!(&api_key, &db, name_limit, "file");
rate_limit!(&api_key, &db, name_limit, "file");
// let (filter, val): (&'static str, &(dyn tokio_postgres::types::ToSql + Sync)) =
// if let Some(ref id) = opts.id {
// ("file_id = $1", id)
// } else if let Some(ref name) = opts.name {
// ("lower(filename) = lower($1)", name)
// } else if let Some(ref url) = opts.url {
// ("lower(url) = lower($1)", url)
// } else {
// return Err(warp::reject::custom(Error::InvalidData));
// };
let (filter, val): (&'static str, &(dyn tokio_postgres::types::ToSql + Sync)) =
if let Some(ref id) = opts.id {
("file_id = $1", id)
} else if let Some(ref name) = opts.name {
("lower(filename) = lower($1)", name)
} else if let Some(ref url) = opts.url {
("lower(url) = lower($1)", url)
} else {
return Err(warp::reject::custom(Error::InvalidData));
};
// debug!("Searching for {:?}", opts);
debug!("Searching for {:?}", opts);
// let query = format!(
// "SELECT
// submission.id,
// submission.url,
// submission.filename,
// submission.file_id,
// artist.name
// FROM
// submission
// JOIN artist
// ON artist.id = submission.artist_id
// WHERE
// {}
// LIMIT 10",
// filter
// );
let query = format!(
"SELECT
submission.id,
submission.url,
submission.filename,
submission.file_id,
artist.name,
hashes.id hash_id
FROM
submission
JOIN artist
ON artist.id = submission.artist_id
JOIN hashes
ON hashes.furaffinity_id = submission.id
WHERE
{}
LIMIT 10",
filter
);
// let matches: Vec<_> = db
// .query::<str>(&*query, &[val])
// .await
// .map_err(map_postgres_err)?
// .into_iter()
// .map(|row| File {
// id: row.get::<&str, i32>("id") as i64,
// id_str: row.get::<&str, i32>("id").to_string(),
// url: row.get("url"),
// filename: row.get("filename"),
// artists: row
// .get::<&str, Option<String>>("name")
// .map(|artist| vec![artist]),
// distance: None,
// hash: None,
// site_info: Some(SiteInfo::FurAffinity(FurAffinityFile {
// file_id: row.get("file_id"),
// })),
// })
// .collect();
let matches: Vec<_> = db
.query::<str>(&*query, &[val])
.await
.map_err(map_postgres_err)?
.into_iter()
.map(|row| File {
id: row.get("hash_id"),
site_id: row.get::<&str, i32>("id") as i64,
site_id_str: row.get::<&str, i32>("id").to_string(),
url: row.get("url"),
filename: row.get("filename"),
artists: row
.get::<&str, Option<String>>("name")
.map(|artist| vec![artist]),
distance: None,
hash: None,
site_info: Some(SiteInfo::FurAffinity(FurAffinityFile {
file_id: row.get("file_id"),
})),
})
.collect();
// Ok(warp::reply::json(&matches))
// }
Ok(warp::reply::json(&matches))
}
pub async fn handle_rejection(err: Rejection) -> Result<impl Reply, std::convert::Infallible> {
info!("Had rejection: {:?}", err);

View File

@ -59,6 +59,12 @@ pub fn image_query_sync(
distance: i64,
hash: Option<Vec<u8>>,
) -> tokio::sync::mpsc::Receiver<Result<Vec<File>, tokio_postgres::Error>> {
log::trace!(
"Running image query on {} hashes with distance {}",
hashes.len(),
distance
);
let (mut tx, rx) = tokio::sync::mpsc::channel(1);
tokio::spawn(async move {
@ -71,7 +77,7 @@ pub fn image_query_sync(
let mut hash_where_clause = Vec::with_capacity(hashes.len());
for (idx, hash) in hashes.iter().enumerate() {
params.push(hash);
hash_where_clause.push(format!(" hash <@ (${}, $1)", idx + 2));
hash_where_clause.push(format!(" hashes.hash <@ (${}, $1)", idx + 2));
}
let hash_where_clause = hash_where_clause.join(" OR ");

View File

@ -25,7 +25,7 @@ pub enum RateLimit {
/// A general type for every file.
#[derive(Debug, Default, Serialize)]
pub struct File {
pub id: i64,
pub id: i32,
pub site_id: i64,
pub site_id_str: String,