Added mass select queries

This commit is contained in:
Raphaël Thériault 2019-10-08 12:57:12 -04:00
parent 4653c60f31
commit 6ebc25235e
2 changed files with 140 additions and 3 deletions

View File

@ -3,6 +3,7 @@ extern crate diesel;
#[macro_use]
extern crate serde;
use chrono::{DateTime, Utc};
use diesel::r2d2::{self, ConnectionManager};
use diesel::sqlite::SqliteConnection;
@ -13,3 +14,12 @@ pub mod setup;
/// SQLite database connection pool
pub type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>;
/// Date and time range
type DateTimeRange = (Option<DateTime<Utc>>, Option<DateTime<Utc>>);
/// Date and time range specifying ranges for creation and update
pub struct SelectRange {
created: DateTimeRange,
updated: DateTimeRange,
}

View File

@ -1,18 +1,61 @@
//! Helper functions for SQL queries
// A lot of duplicate code here could be merged by using macros
// but that would make adding different fields more troublesome
/// Queries affecting the `files` table
pub mod files {
use crate::models::files::*;
use crate::schema::files::dsl::*;
use crate::schema::files::table;
use crate::Pool;
use crate::{Pool, SelectRange};
use actix_web::web::Data;
use diesel::prelude::*;
use diesel::result::QueryResult;
/// SELECT multiple file entries
pub fn select(
range: SelectRange,
limit: Option<i64>,
order_asc: bool,
order_created: bool,
pool: Data<Pool>,
) -> QueryResult<Vec<File>> {
let conn: &SqliteConnection = &pool.get().unwrap();
let mut query = files.into_boxed();
if let Some(cf) = range.created.0 {
let timestamp = cf.timestamp() as i32;
query = query.filter(created.ge(timestamp));
}
if let Some(ct) = range.created.1 {
let timestamp = ct.timestamp() as i32;
query = query.filter(created.lt(timestamp));
}
if let Some(uf) = range.updated.0 {
let timestamp = uf.timestamp() as i32;
query = query.filter(updated.ge(timestamp));
}
if let Some(ut) = range.updated.1 {
let timestamp = ut.timestamp() as i32;
query = query.filter(updated.lt(timestamp));
}
if let Some(limit) = limit {
query = query.limit(limit);
}
query = match (order_asc, order_created) {
(false, false) => query.order(updated.desc()),
(true, false) => query.order(updated.asc()),
(false, true) => query.order(created.desc()),
(true, true) => query.order(created.asc()),
};
query.load::<File>(conn)
}
/// SELECT a single file entry given its id
pub fn find(g_id: i32, pool: Data<Pool>) -> QueryResult<File> {
let conn: &SqliteConnection = &pool.get().unwrap();
@ -78,12 +121,54 @@ pub mod links {
use crate::models::links::*;
use crate::schema::links::dsl::*;
use crate::schema::links::table;
use crate::Pool;
use crate::{Pool, SelectRange};
use actix_web::web::Data;
use diesel::prelude::*;
use diesel::result::QueryResult;
/// SELECT multiple link entries
pub fn select(
range: SelectRange,
limit: Option<i64>,
order_asc: bool,
order_created: bool,
pool: Data<Pool>,
) -> QueryResult<Vec<Link>> {
let conn: &SqliteConnection = &pool.get().unwrap();
let mut query = links.into_boxed();
if let Some(cf) = range.created.0 {
let timestamp = cf.timestamp() as i32;
query = query.filter(created.ge(timestamp));
}
if let Some(ct) = range.created.1 {
let timestamp = ct.timestamp() as i32;
query = query.filter(created.lt(timestamp));
}
if let Some(uf) = range.updated.0 {
let timestamp = uf.timestamp() as i32;
query = query.filter(updated.ge(timestamp));
}
if let Some(ut) = range.updated.1 {
let timestamp = ut.timestamp() as i32;
query = query.filter(updated.lt(timestamp));
}
if let Some(limit) = limit {
query = query.limit(limit);
}
query = match (order_asc, order_created) {
(false, false) => query.order(updated.desc()),
(true, false) => query.order(updated.asc()),
(false, true) => query.order(created.desc()),
(true, true) => query.order(created.asc()),
};
query.load::<Link>(conn)
}
/// SELECT a single link entry given its id
pub fn find(g_id: i32, pool: Data<Pool>) -> QueryResult<Link> {
let conn: &SqliteConnection = &pool.get().unwrap();
@ -147,12 +232,54 @@ pub mod texts {
use crate::models::texts::*;
use crate::schema::texts::dsl::*;
use crate::schema::texts::table;
use crate::Pool;
use crate::{Pool, SelectRange};
use actix_web::web::Data;
use diesel::prelude::*;
use diesel::result::QueryResult;
/// SELECT multiple text entries
pub fn select(
range: SelectRange,
limit: Option<i64>,
order_asc: bool,
order_created: bool,
pool: Data<Pool>,
) -> QueryResult<Vec<Text>> {
let conn: &SqliteConnection = &pool.get().unwrap();
let mut query = texts.into_boxed();
if let Some(cf) = range.created.0 {
let timestamp = cf.timestamp() as i32;
query = query.filter(created.ge(timestamp));
}
if let Some(ct) = range.created.1 {
let timestamp = ct.timestamp() as i32;
query = query.filter(created.lt(timestamp));
}
if let Some(uf) = range.updated.0 {
let timestamp = uf.timestamp() as i32;
query = query.filter(updated.ge(timestamp));
}
if let Some(ut) = range.updated.1 {
let timestamp = ut.timestamp() as i32;
query = query.filter(updated.lt(timestamp));
}
if let Some(limit) = limit {
query = query.limit(limit);
}
query = match (order_asc, order_created) {
(false, false) => query.order(updated.desc()),
(true, false) => query.order(updated.asc()),
(false, true) => query.order(created.desc()),
(true, true) => query.order(created.asc()),
};
query.load::<Text>(conn)
}
/// SELECT a single text entry given its id
pub fn find(g_id: i32, pool: Data<Pool>) -> QueryResult<Text> {
let conn: &SqliteConnection = &pool.get().unwrap();