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
extern crate mysql; use mysql::{Params, Row, Error}; use mysql::conn::GenericConnection; pub trait Repository { fn where_one<T, P, Where>(conn: &mut T, sql: &str, params: P) -> Result<Option<Where>, Error> where T: GenericConnection, Where: Whereable<Self>, P: Into<Params>, Self: Sized { let out = conn.prep_exec(Where::wrapped_sql(sql), params.into())? .flat_map(|x| x) .flat_map(|x| Where::from_row(x) ) .next(); Ok(out) } fn where_all<T, P, Where>(conn: &mut T, sql: &str, params: P) -> Result<Vec<Where>, Error> where T: GenericConnection, Where: Whereable<Self>, P: Into<::mysql::Params>, Self: Sized { let out = conn.prep_exec(Where::wrapped_sql(sql), params.into())? .flat_map(|x| x) .flat_map(|x| Where::from_row(x) ) .collect(); Ok(out) } fn find<T, Find>(conn: &mut T, id: u64) -> Result<Option<Find>, Error> where T: GenericConnection, Find: Findable<Self>, Self: Sized { let out = conn.prep_exec(Find::sql(), (id,))? .flat_map(|x| x) .flat_map(|x| Find::from_row(x) ) .next(); Ok(out) } fn insert<T, Ins>(conn: &mut T, obj: Ins) -> Result<u64, Error> where T: GenericConnection, Ins: Insertable<Self>, Self: Sized { let res = conn.prep_exec(Ins::sql(), obj.to_params())?; let id = res.last_insert_id(); Ok(id) } fn update<T, Up>(conn: &mut T, obj: Up) -> Result<(), Error> where T: GenericConnection, Up: Updatable<Self>, Self: Sized { conn.prep_exec(Up::sql(), obj.to_params())?; Ok(()) } fn delete<T, Del>(conn: &mut T, obj: Del) -> Result<(), Error> where T: GenericConnection, Del: Deletable<Self>, Self: Sized { conn.prep_exec(Del::sql(), obj.to_params())?; Ok(()) } } pub trait Whereable<R: Repository>: Sized { fn wrapped_sql(sql: &str) -> String; fn from_row(row: Row) -> Result<Self, Error>; } pub trait Insertable<R: Repository> { fn sql() -> &'static str; fn to_params(&self) -> Params; } pub trait Updatable<R: Repository>: Sized { fn sql() -> &'static str; fn to_params(&self) -> Params; } pub trait Findable<R: Repository>: Sized { fn sql() -> &'static str; fn from_row(row: Row) -> Result<Self, Error>; } pub trait Deletable<R: Repository> { fn sql() -> &'static str; fn to_params(&self) -> Params; }