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
use {validate, Client, Result};
use db::{column, table};
use models::{Pledge, Project, User};
use postgres::error::SqlState;
use rustorm::database::DbError;
use rustorm::query::Query;
use std::error::Error as ErrorTrait;
impl Pledge {
pub fn create(client: &Client, user: &str, project_name: &str, card: &str, amount: f64) -> Result<Pledge> {
try!(Pledge::validate_args(user, project_name, card));
let amount = try!(validate::currency(amount));
let uid = try!(User::upsert(client, user));
let pid = try!(Project::get_id(client, project_name));
let mut res = Query::insert()
.set(column::user_id, &uid)
.set(column::project_id, &pid)
.set(column::card, &card)
.set(column::amount, &amount)
.into_table(&client.table(table::pledge))
.return_all()
.collect_one(client.db());
Pledge::check_valid_errors(&mut res, user, project_name, card);
let pledge = try!(res);
Ok(pledge)
}
fn check_valid_errors(res: &mut ::std::result::Result<Pledge, DbError>,
user: &str, project_name: &str, card: &str) {
let mut message = String::new();
if let &mut Err(ref err) = res {
if let Some(SqlState::UniqueViolation) = err.code {
if err.description().contains(&"pkey") {
message = format!("User '{}' has already backed project '{}'.",
user, project_name)
} else if err.description().contains(&"pledge_project_card") {
message = format!("Credit card '{}' has already been used to back project '{}'.",
card, project_name)
}
}
}
if !message.is_empty() {
*res = Err(DbError::with_code(&message, SqlState::UniqueViolation));
}
}
fn validate_args(user: &str, project_name: &str, card: &str) -> Result<()> {
try!(validate::length(project_name, 4, 20));
try!(validate::length(user, 4, 20));
try!(validate::length(card, 1, 19));
try!(validate::alphanumeric(project_name));
try!(validate::alphanumeric(user));
try!(validate::luhn10(card));
Ok(())
}
}