-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproducers.rs
121 lines (114 loc) · 4.2 KB
/
producers.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
use crate::error::{RestResult, VinotecaError};
use crate::models::{Producer, ProducerForm};
use crate::schema::{producers, purchases, regions, wines};
use crate::wine_types::TopWineType;
use crate::DbConn;
use diesel::dsl::sql;
use diesel::prelude::*;
use diesel::sql_types::{Float, Integer};
use rocket_contrib::json::Json;
use validator::Validate;
#[get("/producers?<id>&<name>&<region_id>&<region_name>")]
pub fn get(
id: Option<i32>,
name: Option<String>,
region_id: Option<i32>,
region_name: Option<String>,
connection: DbConn,
) -> RestResult<Vec<Producer>> {
let mut query = producers::table.inner_join(regions::table).into_boxed();
if let Some(id) = id {
query = query.filter(producers::id.eq(id));
}
if let Some(name) = name {
query = query.filter(producers::name.eq(name));
}
if let Some(region_id) = region_id {
query = query.filter(regions::id.eq(region_id))
}
if let Some(region_name) = region_name {
query = query.filter(regions::name.eq(region_name));
}
let final_query = query
.select((producers::id, producers::name, producers::region_id))
.distinct();
final_query
.load::<Producer>(&*connection)
.map(Json)
.map_err(VinotecaError::from)
}
pub fn top<Table: diesel::Table + diesel::query_dsl::InternalJoinDsl<_, diesel::query_source::joins::Inner, _>>(table: Table, limit: usize, connection: DbConn) -> RestResult<Vec<TopWineType>> {
table
.inner_join(wines::table.inner_join(purchases::table))
.group_by((producers::id, producers::name))
.select((
wines::id,
wines::name,
sql::<Integer>("sum(purchases.quantity)"),
// Should probably be distinct
sql::<Integer>("count(wines.id)"),
sql::<Float>("avg(purchases.price)"),
))
.order_by(sql::<Integer>("sum(purchases.quantity) DESC"))
.limit(limit as i64)
.load::<TopWineType>(&*connection)
.map(Json)
.map_err(VinotecaError::from)
}
#[get("/producers/top?<limit>")]
pub fn top2(limit: Option<usize>, connection: DbConn) -> RestResult<Vec<TopWineType>> {
let limit = limit.unwrap_or(10);
producers::table
.inner_join(wines::table.inner_join(purchases::table))
.group_by((producers::id, producers::name))
.select((
producers::id,
producers::name,
sql::<Integer>("sum(purchases.quantity)"),
// Should probably be distinct
sql::<Integer>("count(wines.id)"),
sql::<Float>("avg(purchases.price)"),
))
.order_by(sql::<Integer>("sum(purchases.quantity) DESC"))
.limit(limit as i64)
.load::<TopWineType>(&*connection)
.map(Json)
.map_err(VinotecaError::from)
}
#[post("/producers", format = "json", data = "<producer_form>")]
pub fn post(producer_form: Json<ProducerForm>, connection: DbConn) -> RestResult<Producer> {
let producer_form = producer_form.into_inner();
producer_form.validate()?;
diesel::insert_into(producers::table)
.values(&producer_form)
.execute(&*connection)
.and_then(|_| {
producers::table
.filter(producers::name.eq((*producer_form.name).to_owned()))
.first(&*connection)
.map(Json)
})
.map_err(VinotecaError::from)
}
#[put("/producers/<id>", format = "json", data = "<producer_form>")]
pub fn put(id: i32, producer_form: Json<ProducerForm>, connection: DbConn) -> RestResult<Producer> {
let producer_form = producer_form.into_inner();
producer_form.validate()?;
diesel::update(producers::table.filter(producers::id.eq(id)))
.set(producer_form)
.execute(&*connection)
.and_then(|_| {
producers::table
.filter(producers::id.eq(id))
.first(&*connection)
.map(Json)
})
.map_err(VinotecaError::from)
}
#[delete("/producers/<id>")]
pub fn delete(id: i32, connection: DbConn) -> Result<(), VinotecaError> {
diesel::delete(producers::table.filter(producers::id.eq(id)))
.execute(&*connection)
.map(|_| ())
.map_err(VinotecaError::from)
}