diff --git a/examples/todo/Cargo.toml b/examples/todo/Cargo.toml index bbfb7de7..525e7896 100644 --- a/examples/todo/Cargo.toml +++ b/examples/todo/Cargo.toml @@ -9,8 +9,10 @@ rocket_codegen = { path = "../../codegen" } serde = "0.9" serde_json = "0.9" serde_derive = "0.9" +r2d2 = "0.7" diesel = { version = "0.10", features = ["sqlite"] } diesel_codegen = { version = "0.10", features = ["sqlite"] } +r2d2-diesel = { version = "0.10", features = ["sqlite"] } [dependencies.rocket_contrib] path = "../../contrib" diff --git a/examples/todo/src/main.rs b/examples/todo/src/main.rs index 8f6a813a..4bb15102 100644 --- a/examples/todo/src/main.rs +++ b/examples/todo/src/main.rs @@ -7,34 +7,38 @@ extern crate serde_json; #[macro_use] extern crate diesel_codegen; #[macro_use] extern crate serde_derive; extern crate rocket_contrib; +extern crate r2d2; +extern crate r2d2_diesel; mod static_files; mod task; +mod db; use rocket::request::{Form, FlashMessage}; use rocket::response::{Flash, Redirect}; use rocket_contrib::Template; + use task::Task; #[derive(Debug, Serialize)] struct Context<'a, 'b>{ msg: Option<(&'a str, &'b str)>, tasks: Vec } impl<'a, 'b> Context<'a, 'b> { - pub fn err(msg: &'a str) -> Context<'static, 'a> { - Context{msg: Some(("error", msg)), tasks: Task::all()} + pub fn err(conn: &db::Conn, msg: &'a str) -> Context<'static, 'a> { + Context{msg: Some(("error", msg)), tasks: Task::all(conn)} } - pub fn raw(msg: Option<(&'a str, &'b str)>) -> Context<'a, 'b> { - Context{msg: msg, tasks: Task::all()} + pub fn raw(conn: &db::Conn, msg: Option<(&'a str, &'b str)>) -> Context<'a, 'b> { + Context{msg: msg, tasks: Task::all(conn)} } } #[post("/", data = "")] -fn new(todo_form: Form) -> Flash { +fn new(todo_form: Form, conn: db::Conn) -> Flash { let todo = todo_form.into_inner(); if todo.description.is_empty() { Flash::error(Redirect::to("/"), "Description cannot be empty.") - } else if todo.insert() { + } else if todo.insert(&conn) { Flash::success(Redirect::to("/"), "Todo successfully added.") } else { Flash::error(Redirect::to("/"), "Whoops! The server failed.") @@ -42,33 +46,34 @@ fn new(todo_form: Form) -> Flash { } #[put("/")] -fn toggle(id: i32) -> Result { - if Task::toggle_with_id(id) { +fn toggle(id: i32, conn: db::Conn) -> Result { + if Task::toggle_with_id(id, &conn) { Ok(Redirect::to("/")) } else { - Err(Template::render("index", &Context::err("Couldn't toggle task."))) + Err(Template::render("index", &Context::err(&conn, "Couldn't toggle task."))) } } #[delete("/")] -fn delete(id: i32) -> Result, Template> { - if Task::delete_with_id(id) { +fn delete(id: i32, conn: db::Conn) -> Result, Template> { + if Task::delete_with_id(id, &conn) { Ok(Flash::success(Redirect::to("/"), "Todo was deleted.")) } else { - Err(Template::render("index", &Context::err("Couldn't delete task."))) + Err(Template::render("index", &Context::err(&conn, "Couldn't delete task."))) } } #[get("/")] -fn index(msg: Option) -> Template { +fn index(msg: Option, conn: db::Conn) -> Template { Template::render("index", &match msg { - Some(ref msg) => Context::raw(Some((msg.name(), msg.msg()))), - None => Context::raw(None), + Some(ref msg) => Context::raw(&conn, Some((msg.name(), msg.msg()))), + None => Context::raw(&conn, None), }) } fn main() { rocket::ignite() + .manage(db::init_pool()) .mount("/", routes![index, static_files::all]) .mount("/todo/", routes![new, toggle, delete]) .launch(); diff --git a/examples/todo/src/task.rs b/examples/todo/src/task.rs index a11a0733..e470f6bf 100644 --- a/examples/todo/src/task.rs +++ b/examples/todo/src/task.rs @@ -1,19 +1,14 @@ use diesel; use diesel::prelude::*; use diesel::sqlite::SqliteConnection; + use self::schema::tasks; use self::schema::tasks::dsl::{tasks as all_tasks, completed as task_completed}; -const DATABASE_FILE: &'static str = env!("DATABASE_URL"); - mod schema { infer_schema!("env:DATABASE_URL"); } -fn db() -> SqliteConnection { - SqliteConnection::establish(DATABASE_FILE).expect("Failed to connect to db.") -} - #[table_name = "tasks"] #[derive(Serialize, Queryable, Insertable, FromForm, Debug, Clone)] pub struct Task { @@ -23,27 +18,27 @@ pub struct Task { } impl Task { - pub fn all() -> Vec { - all_tasks.order(tasks::id.desc()).load::(&db()).unwrap() + pub fn all(conn: &SqliteConnection) -> Vec { + all_tasks.order(tasks::id.desc()).load::(conn).unwrap() } - pub fn insert(&self) -> bool { - diesel::insert(self).into(tasks::table).execute(&db()).is_ok() + pub fn insert(&self, conn: &SqliteConnection) -> bool { + diesel::insert(self).into(tasks::table).execute(conn).is_ok() } - pub fn toggle_with_id(id: i32) -> bool { - let task = all_tasks.find(id).get_result::(&db()); + pub fn toggle_with_id(id: i32, conn: &SqliteConnection) -> bool { + let task = all_tasks.find(id).get_result::(conn); if task.is_err() { return false; } let new_status = !task.unwrap().completed.unwrap(); let updated_task = diesel::update(all_tasks.find(id)); - updated_task.set(task_completed.eq(new_status)).execute(&db()).is_ok() + updated_task.set(task_completed.eq(new_status)).execute(conn).is_ok() } - pub fn delete_with_id(id: i32) -> bool { - diesel::delete(all_tasks.find(id)).execute(&db()).is_ok() + pub fn delete_with_id(id: i32, conn: &SqliteConnection) -> bool { + diesel::delete(all_tasks.find(id)).execute(conn).is_ok() } }