From f66025b460af9cf1ea0a8c288ffe55d5336f2d39 Mon Sep 17 00:00:00 2001 From: Ryan Leckey Date: Mon, 27 Jul 2020 02:12:11 -0700 Subject: [PATCH] remove examples/postgres/todo-api as there is now a similar example in actix/examples --- examples/postgres/todo-api/.env-example | 4 - examples/postgres/todo-api/.gitignore | 2 - examples/postgres/todo-api/Cargo.toml | 20 --- examples/postgres/todo-api/README.md | 33 ----- examples/postgres/todo-api/schema.sql | 5 - examples/postgres/todo-api/src/main.rs | 65 --------- examples/postgres/todo-api/src/todo/mod.rs | 5 - examples/postgres/todo-api/src/todo/model.rs | 130 ------------------ examples/postgres/todo-api/src/todo/routes.rs | 63 --------- 9 files changed, 327 deletions(-) delete mode 100644 examples/postgres/todo-api/.env-example delete mode 100644 examples/postgres/todo-api/.gitignore delete mode 100644 examples/postgres/todo-api/Cargo.toml delete mode 100644 examples/postgres/todo-api/README.md delete mode 100644 examples/postgres/todo-api/schema.sql delete mode 100644 examples/postgres/todo-api/src/main.rs delete mode 100644 examples/postgres/todo-api/src/todo/mod.rs delete mode 100644 examples/postgres/todo-api/src/todo/model.rs delete mode 100644 examples/postgres/todo-api/src/todo/routes.rs diff --git a/examples/postgres/todo-api/.env-example b/examples/postgres/todo-api/.env-example deleted file mode 100644 index f474e6dd..00000000 --- a/examples/postgres/todo-api/.env-example +++ /dev/null @@ -1,4 +0,0 @@ -HOST=127.0.0.1 -PORT=5000 -DATABASE_URL="postgres://user:pass@192.168.33.11/actix_sqlx_todo" -RUST_LOG=todo_api=info,actix=info diff --git a/examples/postgres/todo-api/.gitignore b/examples/postgres/todo-api/.gitignore deleted file mode 100644 index fedaa2b1..00000000 --- a/examples/postgres/todo-api/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/target -.env diff --git a/examples/postgres/todo-api/Cargo.toml b/examples/postgres/todo-api/Cargo.toml deleted file mode 100644 index e010355b..00000000 --- a/examples/postgres/todo-api/Cargo.toml +++ /dev/null @@ -1,20 +0,0 @@ -[package] -name = "todo_api" -version = "0.1.0" -authors = ["Milan Zivkovic "] -edition = "2018" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -listenfd = "0.3.3" -actix-web = "3.0.0-alpha.1" -actix-rt = "1.1.0" -serde = "1.0.106" -serde_json = "1.0.51" -sqlx = { version = "0.3", features = [ "postgres" ] } -futures = "0.3.4" -dotenv = "0.15.0" -env_logger = "0.7.1" -log = "0.4.8" -anyhow = "1.0.28" \ No newline at end of file diff --git a/examples/postgres/todo-api/README.md b/examples/postgres/todo-api/README.md deleted file mode 100644 index 05661b8d..00000000 --- a/examples/postgres/todo-api/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# actix-sqlx-todo - -Example Todo API using [Actix-web](https://github.com/actix/actix-web) and SQLx with posgresql - -# Usage - -## Prerequisites - -* Rust -* PostgreSQL - -## Change into the project sub-directory - -All instructions assume you have changed into this folder: - -```bash -cd examples/postgres/todo-api -``` - -## Set up the database - -* Create new database using `schema.sql` -* Copy `.env-example` into `.env` and adjust DATABASE_URL to match your PostgreSQL address, username and password - -## Run the application - -To run the application execute: - -```bash -cargo run -``` - -By default application will be available on `http://localhost:5000`. If you wish to change address or port you can do it inside `.env` file. \ No newline at end of file diff --git a/examples/postgres/todo-api/schema.sql b/examples/postgres/todo-api/schema.sql deleted file mode 100644 index dd9dc7ff..00000000 --- a/examples/postgres/todo-api/schema.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE TABLE IF NOT EXISTS todos ( - id SERIAL PRIMARY KEY, - description TEXT NOT NULL, - done BOOLEAN NOT NULL DEFAULT FALSE -); diff --git a/examples/postgres/todo-api/src/main.rs b/examples/postgres/todo-api/src/main.rs deleted file mode 100644 index 030a80fb..00000000 --- a/examples/postgres/todo-api/src/main.rs +++ /dev/null @@ -1,65 +0,0 @@ -#[macro_use] -extern crate log; - -use actix_web::{web, App, HttpResponse, HttpServer, Responder}; -use anyhow::Result; -use dotenv::dotenv; -use listenfd::ListenFd; -use sqlx::PgPool; -use std::env; - -// import todo module (routes and model) -mod todo; - -// default / handler -async fn index() -> impl Responder { - HttpResponse::Ok().body(r#" - Welcome to Actix-web with SQLx Todos example. - Available routes: - GET /todos -> list of all todos - POST /todo -> create new todo, example: { "description": "learn actix and sqlx", "done": false } - GET /todo/{id} -> show one todo with requested id - PUT /todo/{id} -> update todo with requested id, example: { "description": "learn actix and sqlx", "done": true } - DELETE /todo/{id} -> delete todo with requested id - "# - ) -} - -#[actix_rt::main] -async fn main() -> Result<()> { - dotenv().ok(); - env_logger::init(); - - // this will enable us to keep application running during recompile: systemfd --no-pid -s http::5000 -- cargo watch -x run - let mut listenfd = ListenFd::from_env(); - - let database_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file"); - // PgPool::builder() - // .max_connections(5) // maximum number of connections in the pool - // .build(env::var("DATABASE_URL")?).await?; - let db_pool = PgPool::new(&database_url).await?; - - let mut server = HttpServer::new(move || { - App::new() - .data(db_pool.clone()) // pass database pool to application so we can access it inside handlers - .route("/", web::get().to(index)) - .configure(todo::init) // init todo routes - }); - - server = match listenfd.take_tcp_listener(0)? { - Some(listener) => server.listen(listener)?, - None => { - let host = env::var("HOST").expect("HOST is not set in .env file"); - let port = env::var("PORT").expect("PORT is not set in .env file"); - server.bind(format!("{}:{}", host, port))? - } - }; - - info!("Starting server"); - server.run().await?; - - Ok(()) -} - -// export DATABASE_URL="postgres://pguser:zx@192.168.33.11/realworld" -// systemfd --no-pid -s http::5000 -- cargo watch -x run diff --git a/examples/postgres/todo-api/src/todo/mod.rs b/examples/postgres/todo-api/src/todo/mod.rs deleted file mode 100644 index 61f924b1..00000000 --- a/examples/postgres/todo-api/src/todo/mod.rs +++ /dev/null @@ -1,5 +0,0 @@ -mod model; -mod routes; - -pub use model::*; -pub use routes::init; \ No newline at end of file diff --git a/examples/postgres/todo-api/src/todo/model.rs b/examples/postgres/todo-api/src/todo/model.rs deleted file mode 100644 index bc96b001..00000000 --- a/examples/postgres/todo-api/src/todo/model.rs +++ /dev/null @@ -1,130 +0,0 @@ -use serde::{Serialize, Deserialize}; -use actix_web::{HttpResponse, HttpRequest, Responder, Error}; -use futures::future::{ready, Ready}; -use sqlx::{PgPool, FromRow, Row}; -use sqlx::postgres::PgRow; -use anyhow::Result; - -// this struct will use to receive user input -#[derive(Serialize, Deserialize)] -pub struct TodoRequest { - pub description: String, - pub done: bool -} - -// this struct will be used to represent database record -#[derive(Serialize, FromRow)] -pub struct Todo { - pub id: i32, - pub description: String, - pub done: bool, -} - -// implementation of Actix Responder for Todo struct so we can return Todo from action handler -impl Responder for Todo { - type Error = Error; - type Future = Ready>; - - fn respond_to(self, _req: &HttpRequest) -> Self::Future { - let body = serde_json::to_string(&self).unwrap(); - // create response and set content type - ready(Ok( - HttpResponse::Ok() - .content_type("application/json") - .body(body) - )) - } -} - -// Implementation for Todo struct, functions for read/write/update and delete todo from database -impl Todo { - pub async fn find_all(pool: &PgPool) -> Result> { - let mut todos = vec![]; - let recs = sqlx::query!( - r#" - SELECT id, description, done - FROM todos - ORDER BY id - "# - ) - .fetch_all(pool) - .await?; - - for rec in recs { - todos.push(Todo { - id: rec.id, - description: rec.description, - done: rec.done - }); - } - - Ok(todos) - } - - pub async fn find_by_id(id: i32, pool: &PgPool) -> Result { - let rec = sqlx::query!( - r#" - SELECT * FROM todos WHERE id = $1 - "#, - id - ) - .fetch_one(&*pool) - .await?; - - Ok(Todo { - id: rec.id, - description: rec.description, - done: rec.done - }) - } - - pub async fn create(todo: TodoRequest, pool: &PgPool) -> Result { - let mut tx = pool.begin().await?; - let todo = sqlx::query("INSERT INTO todos (description, done) VALUES ($1, $2) RETURNING id, description, done") - .bind(&todo.description) - .bind(todo.done) - .map(|row: PgRow| { - Todo { - id: row.get(0), - description: row.get(1), - done: row.get(2) - } - }) - .fetch_one(&mut tx) - .await?; - - tx.commit().await?; - Ok(todo) - } - - pub async fn update(id: i32, todo: TodoRequest, pool: &PgPool) -> Result { - let mut tx = pool.begin().await.unwrap(); - let todo = sqlx::query("UPDATE todos SET description = $1, done = $2 WHERE id = $3 RETURNING id, description, done") - .bind(&todo.description) - .bind(todo.done) - .bind(id) - .map(|row: PgRow| { - Todo { - id: row.get(0), - description: row.get(1), - done: row.get(2) - } - }) - .fetch_one(&mut tx) - .await?; - - tx.commit().await.unwrap(); - Ok(todo) - } - - pub async fn delete(id: i32, pool: &PgPool) -> Result { - let mut tx = pool.begin().await?; - let deleted = sqlx::query("DELETE FROM todos WHERE id = $1") - .bind(id) - .execute(&mut tx) - .await?; - - tx.commit().await?; - Ok(deleted) - } -} diff --git a/examples/postgres/todo-api/src/todo/routes.rs b/examples/postgres/todo-api/src/todo/routes.rs deleted file mode 100644 index 58b5a904..00000000 --- a/examples/postgres/todo-api/src/todo/routes.rs +++ /dev/null @@ -1,63 +0,0 @@ -use crate::todo::{Todo, TodoRequest}; -use actix_web::{delete, get, post, put, web, HttpResponse, Responder}; -use sqlx::PgPool; - -#[get("/todos")] -async fn find_all(db_pool: web::Data) -> impl Responder { - let result = Todo::find_all(db_pool.get_ref()).await; - match result { - Ok(todos) => HttpResponse::Ok().json(todos), - _ => HttpResponse::BadRequest().body("Error trying to read all todos from database") - } -} - -#[get("/todo/{id}")] -async fn find(id: web::Path, db_pool: web::Data) -> impl Responder { - let result = Todo::find_by_id(id.into_inner(), db_pool.get_ref()).await; - match result { - Ok(todo) => HttpResponse::Ok().json(todo), - _ => HttpResponse::BadRequest().body("Todo not found") - } -} - -#[post("/todo")] -async fn create(todo: web::Json, db_pool: web::Data) -> impl Responder { - let result = Todo::create(todo.into_inner(), db_pool.get_ref()).await; - match result { - Ok(todo) => HttpResponse::Ok().json(todo), - _ => HttpResponse::BadRequest().body("Error trying to create new todo") - } -} - -#[put("/todo/{id}")] -async fn update(id: web::Path, todo: web::Json, db_pool: web::Data) -> impl Responder { - let result = Todo::update(id.into_inner(), todo.into_inner(),db_pool.get_ref()).await; - match result { - Ok(todo) => HttpResponse::Ok().json(todo), - _ => HttpResponse::BadRequest().body("Todo not found") - } -} - -#[delete("/todo/{id}")] -async fn delete(id: web::Path, db_pool: web::Data) -> impl Responder { - let result = Todo::delete(id.into_inner(), db_pool.get_ref()).await; - match result { - Ok(rows) => { - if rows > 0 { - HttpResponse::Ok().body(format!("Successfully deleted {} record(s)", rows)) - } else { - HttpResponse::BadRequest().body("Todo not found") - } - }, - _ => HttpResponse::BadRequest().body("Todo not found") - } -} - -// function that will be called on new Application to configure routes for this module -pub fn init(cfg: &mut web::ServiceConfig) { - cfg.service(find_all); - cfg.service(find); - cfg.service(create); - cfg.service(update); - cfg.service(delete); -} \ No newline at end of file