From 7487a81e90014aef1c3938f8a05dd45490494906 Mon Sep 17 00:00:00 2001 From: "Daniel T. Rodrigues" <45438149+danitrod@users.noreply.github.com> Date: Wed, 3 Mar 2021 11:37:17 -0300 Subject: [PATCH] Fix sqlx_todo CI checks (#415) --- .github/workflows/clippy-fmt.yml | 8 + .github/workflows/linux.yml | 8 + Cargo.lock | 222 +++++++++++++++++- Cargo.toml | 1 + database_interactions/sqlx_todo/.env.example | 2 +- database_interactions/sqlx_todo/.gitignore | 1 + database_interactions/sqlx_todo/Cargo.toml | 2 +- database_interactions/sqlx_todo/README.md | 8 +- database_interactions/sqlx_todo/schema.sql | 2 +- database_interactions/sqlx_todo/src/main.rs | 4 +- .../sqlx_todo/src/todo/model.rs | 18 +- .../sqlx_todo/src/todo/routes.rs | 12 +- 12 files changed, 262 insertions(+), 26 deletions(-) diff --git a/.github/workflows/clippy-fmt.yml b/.github/workflows/clippy-fmt.yml index 4bd5bde..28a36ce 100644 --- a/.github/workflows/clippy-fmt.yml +++ b/.github/workflows/clippy-fmt.yml @@ -49,6 +49,14 @@ jobs: toolchain: stable components: clippy override: true + + - name: create test db for sqlx + run: | + sudo apt-get update && sudo apt-get install sqlite3 + cd database_interactions/sqlx_todo + cp .env.example .env + cat schema.sql | sqlite3 test.db + chmod a+rwx test.db - name: clippy uses: actions-rs/clippy-check@v1 diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index c23b66f..617364e 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -37,6 +37,14 @@ jobs: toolchain: ${{ matrix.version }} override: true + - name: create test db for sqlx + run: | + sudo apt-get update && sudo apt-get install sqlite3 + cd database_interactions/sqlx_todo + cp .env.example .env + cat schema.sql | sqlite3 test.db + chmod a+rwx test.db + - name: cargo check uses: actions-rs/cargo@v1 timeout-minutes: 30 diff --git a/Cargo.lock b/Cargo.lock index e2a031d..ff37d84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -800,7 +800,7 @@ dependencies = [ "async-graphql-parser", "async-graphql-value", "async-mutex", - "async-stream", + "async-stream 0.3.0", "async-trait", "blocking", "bson", @@ -924,6 +924,34 @@ dependencies = [ "event-listener", ] +[[package]] +name = "async-native-tls" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33" +dependencies = [ + "async-std", + "native-tls", + "thiserror", + "url", +] + +[[package]] +name = "async-process" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef37b86e2fa961bae5a4d212708ea0154f904ce31d1a4a7f47e1bbc33a0c040b" +dependencies = [ + "async-io", + "blocking", + "cfg-if 1.0.0", + "event-listener", + "futures-lite", + "once_cell", + "signal-hook", + "winapi 0.3.9", +] + [[package]] name = "async-std" version = "1.8.0" @@ -934,6 +962,7 @@ dependencies = [ "async-global-executor", "async-io", "async-mutex", + "async-process", "blocking", "crossbeam-utils 0.8.1", "futures-channel", @@ -952,16 +981,37 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "async-stream" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22068c0c19514942eefcfd4daf8976ef1aad84e61539f95cd200c35202f80af5" +dependencies = [ + "async-stream-impl 0.2.1", + "futures-core", +] + [[package]] name = "async-stream" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3670df70cbc01729f901f94c887814b3c68db038aad1329a418bae178bc5295c" dependencies = [ - "async-stream-impl", + "async-stream-impl 0.3.0", "futures-core", ] +[[package]] +name = "async-stream-impl" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f9db3b38af870bf7e5cc649167533b493928e50744e2c30ae350230b414670" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-stream-impl" version = "0.3.0" @@ -1232,6 +1282,18 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "bitvec" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ba35e9565969edb811639dbebfe34edc0368e472c5018474c8eb2543397f81" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake2b_simd" version = "0.5.11" @@ -2245,6 +2307,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" +[[package]] +name = "funty" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fed34cd105917e91daa4da6b3728c47b068749d6a62c59811f06ed2ac71d9da7" + [[package]] name = "futf" version = "0.1.4" @@ -3060,6 +3128,7 @@ version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56d90181c2904c287e5390186be820e5ef311a3c62edebb7d6ca3d6a48ce041d" dependencies = [ + "cc", "pkg-config", "vcpkg", ] @@ -3159,6 +3228,17 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "listenfd" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "492158e732f2e2de81c592f0a2427e57e12cd3d59877378fe7af624b6bbe0ca1" +dependencies = [ + "libc", + "uuid 0.6.5", + "winapi 0.3.9", +] + [[package]] name = "lock_api" version = "0.4.2" @@ -3571,6 +3651,19 @@ dependencies = [ "version_check 0.9.2", ] +[[package]] +name = "nom" +version = "6.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7413f999671bd4745a7b624bd370a569fb6bc574b23c83a3c5ed2e453f3d5e2" +dependencies = [ + "bitvec", + "funty", + "lexical-core 0.7.4", + "memchr", + "version_check 0.9.2", +] + [[package]] name = "num-bigint" version = "0.2.6" @@ -4150,6 +4243,12 @@ dependencies = [ "rusqlite", ] +[[package]] +name = "radium" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "941ba9d78d8e2f7ce474c015eea4d9c6d25b6a3327f9832ee29a4de27f91bbb8" + [[package]] name = "rand" version = "0.7.3" @@ -4861,6 +4960,16 @@ dependencies = [ "tokio", ] +[[package]] +name = "signal-hook" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7f3f92a1da3d6b1d32245d0cbcbbab0cfc45996d8df619c42bccfa6d2bbb5f" +dependencies = [ + "libc", + "signal-hook-registry", +] + [[package]] name = "signal-hook-registry" version = "1.3.0" @@ -4956,6 +5065,88 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef7b840d5ef62f81f50649ade37112748461256c64a70bccefeabb4d02c515c5" +[[package]] +name = "sqlformat" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d86e3c77ff882a828346ba401a7ef4b8e440df804491c6064fe8295765de71c" +dependencies = [ + "lazy_static", + "maplit", + "nom 6.1.2", + "regex", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8974cacd80085fbe49e778708d660dec6fb351604dc34c3905b26efb2803b038" +dependencies = [ + "sqlx-core", + "sqlx-macros", +] + +[[package]] +name = "sqlx-core" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ac5a436f941c42eac509471a730df5c3c58e1450e68cd39afedbd948206273" +dependencies = [ + "async-native-tls", + "async-std", + "async-stream 0.2.1", + "bitflags", + "byteorder", + "crossbeam-queue", + "crossbeam-utils 0.7.2", + "futures-channel", + "futures-core", + "futures-util", + "hex", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "percent-encoding", + "sqlformat", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de2ae78b783af5922d811b14665a5a3755e531c3087bb805cf24cf71f15e6780" +dependencies = [ + "async-std", + "dotenv", + "futures", + "heck", + "proc-macro2", + "quote", + "sqlx-core", + "syn", + "url", +] + +[[package]] +name = "sqlx_todo" +version = "0.1.0" +dependencies = [ + "actix-web", + "anyhow", + "dotenv", + "env_logger 0.7.1", + "futures", + "listenfd", + "log", + "serde 1.0.117", + "serde_json", + "sqlx", +] + [[package]] name = "standback" version = "0.2.13" @@ -5159,6 +5350,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b625cb7d76f7bb1887a11d2e7b97677539924010773844ed17252c6ec7877595" +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "tempfile" version = "3.1.0" @@ -5805,6 +6002,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "universal-hash" version = "0.4.0" @@ -5847,6 +6050,15 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05e42f7c18b8f902290b009cde6d651262f956c98bc51bca4cd1d511c9cd85c7" +[[package]] +name = "uuid" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1436e58182935dcd9ce0add9ea0b558e8a87befe01c1a301e6020aeb0876363" +dependencies = [ + "cfg-if 0.1.10", +] + [[package]] name = "uuid" version = "0.7.4" @@ -6324,6 +6536,12 @@ dependencies = [ "winapi-build", ] +[[package]] +name = "wyz" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e60b0d1b5f99db2556934e21937020776a5d31520bf169e851ac44e6420214" + [[package]] name = "xml-rs" version = "0.8.3" diff --git a/Cargo.toml b/Cargo.toml index b475aa4..429362a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ members = [ "database_interactions/r2d2", "database_interactions/redis", "database_interactions/simple-auth-server", + "database_interactions/sqlx_todo", "forms/form", "forms/multipart", "forms/multipart-async-std", diff --git a/database_interactions/sqlx_todo/.env.example b/database_interactions/sqlx_todo/.env.example index b2ee297..0715908 100644 --- a/database_interactions/sqlx_todo/.env.example +++ b/database_interactions/sqlx_todo/.env.example @@ -1,4 +1,4 @@ HOST=127.0.0.1 PORT=5000 -DATABASE_URL="postgres://user:pass@192.168.33.11/actix_sqlx_todo" +DATABASE_URL=sqlite://database_interactions/sqlx_todo/test.db RUST_LOG=sqlx_todo=info,actix=info diff --git a/database_interactions/sqlx_todo/.gitignore b/database_interactions/sqlx_todo/.gitignore index fedaa2b..ef82c96 100644 --- a/database_interactions/sqlx_todo/.gitignore +++ b/database_interactions/sqlx_todo/.gitignore @@ -1,2 +1,3 @@ /target .env +test.db diff --git a/database_interactions/sqlx_todo/Cargo.toml b/database_interactions/sqlx_todo/Cargo.toml index 8c0a430..b256311 100644 --- a/database_interactions/sqlx_todo/Cargo.toml +++ b/database_interactions/sqlx_todo/Cargo.toml @@ -11,7 +11,7 @@ actix-web = "3" listenfd = "0.3.3" serde = "1.0.106" serde_json = "1.0.51" -sqlx = { version = "0.3", features = [ "postgres" ] } +sqlx = { version = "0.3", features = [ "sqlite" ] } dotenv = "0.15.0" env_logger = "0.7.1" log = "0.4.8" diff --git a/database_interactions/sqlx_todo/README.md b/database_interactions/sqlx_todo/README.md index bf95ffb..4210931 100644 --- a/database_interactions/sqlx_todo/README.md +++ b/database_interactions/sqlx_todo/README.md @@ -1,13 +1,13 @@ # actix-sqlx-todo -Example Todo application using Actix-web and [SQLx](https://github.com/launchbadge/sqlx) with posgresql +Example Todo application using Actix-web and [SQLx](https://github.com/launchbadge/sqlx) with sqlite # Usage ## Prerequisites * Rust -* PostgreSQL +* SQLite ## Change into the project sub-directory @@ -20,7 +20,7 @@ cd examples/sqlx_todo ## 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 +* Copy `.env-example` into `.env` and adjust DATABASE_URL to match your SQLite address, username and password ## Run the application @@ -30,4 +30,4 @@ To run the application execute: 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 +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 diff --git a/database_interactions/sqlx_todo/schema.sql b/database_interactions/sqlx_todo/schema.sql index dd9dc7f..30a6cdc 100644 --- a/database_interactions/sqlx_todo/schema.sql +++ b/database_interactions/sqlx_todo/schema.sql @@ -1,5 +1,5 @@ CREATE TABLE IF NOT EXISTS todos ( - id SERIAL PRIMARY KEY, + id INTEGER PRIMARY KEY NOT NULL, description TEXT NOT NULL, done BOOLEAN NOT NULL DEFAULT FALSE ); diff --git a/database_interactions/sqlx_todo/src/main.rs b/database_interactions/sqlx_todo/src/main.rs index e32c1fb..845e3d7 100644 --- a/database_interactions/sqlx_todo/src/main.rs +++ b/database_interactions/sqlx_todo/src/main.rs @@ -5,7 +5,7 @@ use actix_web::{web, App, HttpResponse, HttpServer, Responder}; use anyhow::Result; use dotenv::dotenv; use listenfd::ListenFd; -use sqlx::PgPool; +use sqlx::SqlitePool; use std::env; // import todo module (routes and model) @@ -35,7 +35,7 @@ async fn main() -> Result<()> { let database_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file"); - let db_pool = PgPool::new(&database_url).await?; + let db_pool = SqlitePool::new(&database_url).await?; let mut server = HttpServer::new(move || { App::new() diff --git a/database_interactions/sqlx_todo/src/todo/model.rs b/database_interactions/sqlx_todo/src/todo/model.rs index b3ce06a..1cf24f1 100644 --- a/database_interactions/sqlx_todo/src/todo/model.rs +++ b/database_interactions/sqlx_todo/src/todo/model.rs @@ -2,8 +2,8 @@ use actix_web::{Error, HttpRequest, HttpResponse, Responder}; use anyhow::Result; use futures::future::{ready, Ready}; use serde::{Deserialize, Serialize}; -use sqlx::postgres::PgRow; -use sqlx::{FromRow, PgPool, Row}; +use sqlx::sqlite::SqliteRow; +use sqlx::{FromRow, Row, SqlitePool}; // this struct will use to receive user input #[derive(Serialize, Deserialize)] @@ -36,7 +36,7 @@ impl Responder for Todo { // Implementation for Todo struct, functions for read/write/update and delete todo from database impl Todo { - pub async fn find_all(pool: &PgPool) -> Result> { + pub async fn find_all(pool: &SqlitePool) -> Result> { let mut todos = vec![]; let recs = sqlx::query!( r#" @@ -59,7 +59,7 @@ impl Todo { Ok(todos) } - pub async fn find_by_id(id: i32, pool: &PgPool) -> Result { + pub async fn find_by_id(id: i32, pool: &SqlitePool) -> Result { let rec = sqlx::query!( r#" SELECT * FROM todos WHERE id = $1 @@ -76,12 +76,12 @@ impl Todo { }) } - pub async fn create(todo: TodoRequest, pool: &PgPool) -> Result { + pub async fn create(todo: TodoRequest, pool: &SqlitePool) -> 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| { + .map(|row: SqliteRow| { Todo { id: row.get(0), description: row.get(1), @@ -95,13 +95,13 @@ impl Todo { Ok(todo) } - pub async fn update(id: i32, todo: TodoRequest, pool: &PgPool) -> Result { + pub async fn update(id: i32, todo: TodoRequest, pool: &SqlitePool) -> 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| { + .map(|row: SqliteRow| { Todo { id: row.get(0), description: row.get(1), @@ -115,7 +115,7 @@ impl Todo { Ok(todo) } - pub async fn delete(id: i32, pool: &PgPool) -> Result { + pub async fn delete(id: i32, pool: &SqlitePool) -> Result { let mut tx = pool.begin().await?; let deleted = sqlx::query("DELETE FROM todos WHERE id = $1") .bind(id) diff --git a/database_interactions/sqlx_todo/src/todo/routes.rs b/database_interactions/sqlx_todo/src/todo/routes.rs index 4e7c9a3..a857de0 100644 --- a/database_interactions/sqlx_todo/src/todo/routes.rs +++ b/database_interactions/sqlx_todo/src/todo/routes.rs @@ -1,9 +1,9 @@ use crate::todo::{Todo, TodoRequest}; use actix_web::{delete, get, post, put, web, HttpResponse, Responder}; -use sqlx::PgPool; +use sqlx::SqlitePool; #[get("/todos")] -async fn find_all(db_pool: web::Data) -> impl Responder { +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), @@ -13,7 +13,7 @@ async fn find_all(db_pool: web::Data) -> impl Responder { } #[get("/todo/{id}")] -async fn find(id: web::Path, db_pool: web::Data) -> impl Responder { +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), @@ -24,7 +24,7 @@ async fn find(id: web::Path, db_pool: web::Data) -> impl Responder #[post("/todo")] async fn create( todo: web::Json, - db_pool: web::Data, + db_pool: web::Data, ) -> impl Responder { let result = Todo::create(todo.into_inner(), db_pool.get_ref()).await; match result { @@ -37,7 +37,7 @@ async fn create( async fn update( id: web::Path, todo: web::Json, - db_pool: web::Data, + db_pool: web::Data, ) -> impl Responder { let result = Todo::update(id.into_inner(), todo.into_inner(), db_pool.get_ref()).await; @@ -48,7 +48,7 @@ async fn update( } #[delete("/todo/{id}")] -async fn delete(id: web::Path, db_pool: web::Data) -> impl Responder { +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) => {