1
0
mirror of https://github.com/actix/examples synced 2024-11-23 22:41:07 +01:00

add mysql example to workspace

This commit is contained in:
Rob Ede 2023-07-17 17:55:17 +01:00
parent 8e736d9ea4
commit dfd925d4c1
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
18 changed files with 312 additions and 171 deletions

157
Cargo.lock generated
View File

@ -2531,6 +2531,16 @@ dependencies = [
"darling_macro 0.14.4", "darling_macro 0.14.4",
] ]
[[package]]
name = "darling"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e"
dependencies = [
"darling_core 0.20.3",
"darling_macro 0.20.3",
]
[[package]] [[package]]
name = "darling_core" name = "darling_core"
version = "0.13.4" version = "0.13.4"
@ -2559,6 +2569,20 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "darling_core"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.23",
]
[[package]] [[package]]
name = "darling_macro" name = "darling_macro"
version = "0.13.4" version = "0.13.4"
@ -2581,6 +2605,17 @@ dependencies = [
"syn 1.0.109", "syn 1.0.109",
] ]
[[package]]
name = "darling_macro"
version = "0.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core 0.20.3",
"quote",
"syn 2.0.23",
]
[[package]] [[package]]
name = "data-encoding" name = "data-encoding"
version = "2.4.0" version = "2.4.0"
@ -4199,7 +4234,7 @@ dependencies = [
"env_logger", "env_logger",
"juniper", "juniper",
"log", "log",
"mysql", "mysql 23.0.1",
"r2d2", "r2d2",
"r2d2_mysql", "r2d2_mysql",
"serde", "serde",
@ -4471,6 +4506,15 @@ dependencies = [
"hashbrown 0.12.3", "hashbrown 0.12.3",
] ]
[[package]]
name = "lru"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670"
dependencies = [
"hashbrown 0.13.2",
]
[[package]] [[package]]
name = "lru-cache" name = "lru-cache"
version = "0.1.2" version = "0.1.2"
@ -4827,6 +4871,17 @@ dependencies = [
"tokio 1.29.1", "tokio 1.29.1",
] ]
[[package]]
name = "mysql"
version = "1.0.0"
dependencies = [
"actix-web",
"chrono",
"dotenv",
"mysql 24.0.0",
"serde",
]
[[package]] [[package]]
name = "mysql" name = "mysql"
version = "23.0.1" version = "23.0.1"
@ -4839,12 +4894,12 @@ dependencies = [
"flate2", "flate2",
"io-enum", "io-enum",
"libc", "libc",
"lru", "lru 0.8.1",
"mysql_common", "mysql_common 0.29.2",
"named_pipe", "named_pipe",
"native-tls", "native-tls",
"once_cell", "once_cell",
"pem", "pem 1.1.1",
"percent-encoding", "percent-encoding",
"serde", "serde",
"serde_json", "serde_json",
@ -4853,6 +4908,50 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "mysql"
version = "24.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe2babc5f5b354eab9c0a0e40da3e69c4d77421c8b9b6ee03f97acc75bd7955"
dependencies = [
"bufstream",
"bytes 1.4.0",
"crossbeam",
"flate2",
"io-enum",
"libc",
"lru 0.10.1",
"mysql_common 0.30.6",
"named_pipe",
"native-tls",
"once_cell",
"pem 2.0.1",
"percent-encoding",
"serde",
"serde_json",
"socket2 0.5.3",
"twox-hash",
"url",
]
[[package]]
name = "mysql-common-derive"
version = "0.30.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56b0d8a0db9bf6d2213e11f2c701cb91387b0614361625ab7b9743b41aa4938f"
dependencies = [
"darling 0.20.3",
"heck",
"num-bigint",
"proc-macro-crate 1.3.1",
"proc-macro-error",
"proc-macro2",
"quote",
"syn 2.0.23",
"termcolor",
"thiserror",
]
[[package]] [[package]]
name = "mysql_common" name = "mysql_common"
version = "0.29.2" version = "0.29.2"
@ -4890,6 +4989,44 @@ dependencies = [
"uuid 1.4.0", "uuid 1.4.0",
] ]
[[package]]
name = "mysql_common"
version = "0.30.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57349d5a326b437989b6ee4dc8f2f34b0cc131202748414712a8e7d98952fc8c"
dependencies = [
"base64 0.21.2",
"bigdecimal",
"bindgen",
"bitflags 2.3.3",
"bitvec",
"byteorder",
"bytes 1.4.0",
"cc",
"cmake",
"crc32fast",
"flate2",
"frunk",
"lazy_static",
"lexical",
"mysql-common-derive",
"num-bigint",
"num-traits",
"rand 0.8.5",
"regex",
"rust_decimal",
"saturating",
"serde",
"serde_json",
"sha1 0.10.5",
"sha2",
"smallvec 1.11.0",
"subprocess",
"thiserror",
"time 0.3.22",
"uuid 1.4.0",
]
[[package]] [[package]]
name = "named_pipe" name = "named_pipe"
version = "0.4.1" version = "0.4.1"
@ -5267,6 +5404,16 @@ dependencies = [
"base64 0.13.1", "base64 0.13.1",
] ]
[[package]]
name = "pem"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a"
dependencies = [
"base64 0.21.2",
"serde",
]
[[package]] [[package]]
name = "pem-rfc7468" name = "pem-rfc7468"
version = "0.7.0" version = "0.7.0"
@ -5704,7 +5851,7 @@ version = "23.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9733d738ce65959a744f387bae69aa690a867e18d48e5486b171c47bc7b0c575" checksum = "9733d738ce65959a744f387bae69aa690a867e18d48e5486b171c47bc7b0c575"
dependencies = [ dependencies = [
"mysql", "mysql 23.0.1",
"r2d2", "r2d2",
] ]

View File

@ -17,6 +17,7 @@ members = [
"data-factory", "data-factory",
"databases/diesel", "databases/diesel",
"databases/mongodb", "databases/mongodb",
"databases/mysql",
"databases/postgres", "databases/postgres",
"databases/redis", "databases/redis",
"databases/sqlite", "databases/sqlite",

View File

@ -1,13 +1,11 @@
[package] [package]
name = "mysql" name = "mysql"
version = "0.1.0" version = "1.0.0"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
actix-web = "4.3.1" actix-web = "4"
serde = { version = "1.0.136", features = ["derive"] } chrono = { version = "0.4.26", default-features = false, features = ["clock"] }
mysql = "24.0.0" dotenv = "0.15"
dotenv = "0.15.0" mysql = "24"
chrono = "0.4.26" serde = { version = "1", features = ["derive"] }

View File

@ -1,8 +1,9 @@
# mysql # MySQL
This RESTful Actix Web API examples illustrates how to connect to MySQL database using Mysql client library implemented in rust i.e MySql database driver This RESTful Actix Web API examples illustrates how to connect to MySQL database using a MySQL client library implemented in Rust; e.g., MySQL database driver.
Below APIs are supported:
Below APIs are supported:
- Add Bank - Add Bank
- Add Branch - Add Branch
- Add Teller - Add Teller
@ -13,10 +14,11 @@ Below APIs are supported:
- Get Customer - Get Customer
The RESTful Actix Web API has below listed dependencies: The RESTful Actix Web API has below listed dependencies:
- [Actix Web](https://github.com/actix/actix-web) web framework for Rust - [Actix Web](https://github.com/actix/actix-web) web framework for Rust
- [Serde](https://github.com/serde-rs/serde) for serializing and deserializing Rust data structures - [Serde](https://github.com/serde-rs/serde) for serializing and deserializing Rust data structures
- [MySQL](https://github.com/mysql/mysql-server) MySQL database server - [MySQL Server](https://github.com/mysql/mysql-server) MySQL database server
- [mysql](https://github.com/blackbeam/rust-mysql-simple) MySql database driver - [MySQL](https://github.com/blackbeam/rust-mysql-simple) MySQL database driver
## Instructions ## Instructions
@ -24,27 +26,28 @@ The RESTful Actix Web API has below listed dependencies:
You may need to ensure that you are running the commands with the correct MySQL user/password. You may need to ensure that you are running the commands with the correct MySQL user/password.
1. Access MySQL Server 1. Access MySQL Server:
Log in to the MySQL Server using a user account that has the CREATE DATABASE privilege. Log in to the MySQL Server using a user account that has the `CREATE DATABASE` privilege.
2. Create database 1. Create database:
```sql ```sql
CREATE DATABASE my_bank; CREATE DATABASE my_bank;
``` ```
3. Create tables in the database 1. Create tables in the database:
Directory "mysql\sql" contains below listed ".sql" files: Directory "mysql\sql" contains below listed ".sql" files:
- bankdetails.sql
- branch_details.sql - `bankdetails.sql`
- teller_details.sql - `branch_details.sql`
- customer_details.sql - `teller_details.sql`
- `customer_details.sql`
Copy the contents of each of the ".sql" and execute them separately on MySQL Server. This will create four tables in the database. Copy the contents of each of the ".sql" and execute them separately on MySQL Server. This will create four tables in the database.
4. Create `.env` file: 1. Create `.env` file:
```ini ```ini
SERVER_ADDR=127.0.0.1:8080 SERVER_ADDR=127.0.0.1:8080
@ -54,27 +57,27 @@ You may need to ensure that you are running the commands with the correct MySQL
MYSQL_PORT=3306 MYSQL_PORT=3306
MYSQL_DBNAME=my_bank MYSQL_DBNAME=my_bank
``` ```
Update "MYSQL_USER" and "MYSQL_PASSWORD" values with the correct MySQL user/password. Update "MYSQL_USER" and "MYSQL_PASSWORD" values with the correct MySQL user/password.
If your password contains dollar sign "$", then remember to escape it eg "123$abc" will need to be changed to "123\\$abc" If your password contains dollar sign "$", then remember to escape it eg "123$abc" will need to be changed to "123\\$abc"
5. Run the server: 1. Run the server:
```shell ```shell
cargo run cargo run
``` ```
6. Using a different terminal send an HTTP GET/POST requests to the running server: 1. Using a different terminal send an HTTP GET/POST requests to the running server:
Directory "mysql\apis" contains below listed api's files: Directory "mysql/apis" contains below listed API's files:
- addbank.txt
- addbranch.txt
- addteller.txt
- addcustomer.txt
- getbank.txt
- getbranch.txt
- getteller.txt
- getcustomer.txt
Copy the curl request on each of the ".txt" and execute them on separate terminals. Each ".txt" contains curl request and expected json reponse data. - `addbank.txt`
- `addbranch.txt`
- `addteller.txt`
- `addcustomer.txt`
- `getbank.txt`
- `getbranch.txt`
- `getteller.txt`
- `getcustomer.txt`
Copy the curl request on each of the ".txt" and execute them on separate terminals. Each ".txt" contains curl request and expected JSON response data.

View File

@ -9,9 +9,9 @@ Windows
curl -H "Content-type:application/json" --data-binary "{\"bank_name\":\"Bank ABC\",\"country\":\"Kenya\"}" http://127.0.0.1:8080/addbank curl -H "Content-type:application/json" --data-binary "{\"bank_name\":\"Bank ABC\",\"country\":\"Kenya\"}" http://127.0.0.1:8080/addbank
3. 3.
Json response JSON response
{ {
"status_code": 0, "status_code": 0,
"status_description": "Successful" "status_description": "Successful"
} }

View File

@ -10,9 +10,9 @@ curl -H "Content-type:application/json" --data-binary "{\"branch_name\":\"HQ bra
3. 3.
Json response JSON response
{ {
"status_code": 0, "status_code": 0,
"status_description": "Successful" "status_description": "Successful"
} }

View File

@ -10,9 +10,9 @@ curl -H "Content-type:application/json" --data-binary "{\"customer_name\":\"Pete
3. 3.
Json response JSON response
{ {
"status_code": 0, "status_code": 0,
"status_description": "Successful" "status_description": "Successful"
} }

View File

@ -10,9 +10,9 @@ curl -H "Content-type:application/json" --data-binary "{\"teller_name\":\"John D
3. 3.
Json response JSON response
{ {
"status_code": 0, "status_code": 0,
"status_description": "Successful" "status_description": "Successful"
} }

View File

@ -9,7 +9,7 @@ Windows
curl http://localhost:8080/getbank curl http://localhost:8080/getbank
3. 3.
Json response JSON response
{ {
"status_code": 0, "status_code": 0,
@ -20,4 +20,4 @@ Json response
"country": "kenya" "country": "kenya"
} }
] ]
} }

View File

@ -9,7 +9,7 @@ Windows
curl http://localhost:8080/getbranch curl http://localhost:8080/getbranch
3. 3.
Json response JSON response
{ {
"status_code": 0, "status_code": 0,
@ -20,4 +20,4 @@ Json response
"location": "central business district" "location": "central business district"
} }
] ]
} }

View File

@ -9,7 +9,7 @@ Windows
curl http://localhost:8080/getcustomer curl http://localhost:8080/getcustomer
3. 3.
Json response JSON response
{ {
"status_code": 0, "status_code": 0,
@ -20,4 +20,4 @@ Json response
"branch_name": "central business district" "branch_name": "central business district"
} }
] ]
} }

View File

@ -9,7 +9,7 @@ Windows
curl http://localhost:8080/getteller curl http://localhost:8080/getteller
3. 3.
Json response JSON response
{ {
"status_code": 0, "status_code": 0,
@ -20,4 +20,4 @@ Json response
"branch_name": "central business district" "branch_name": "central business district"
} }
] ]
} }

View File

@ -1,7 +1,7 @@
CREATE TABLE `bank_details` ( CREATE TABLE `bank_details` (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`bank_name` varchar(30) DEFAULT '', `bank_name` VARCHAR(30) DEFAULT '',
`country` varchar(30) DEFAULT '', `country` VARCHAR(30) DEFAULT '',
`date_added` datetime DEFAULT CURRENT_TIMESTAMP, `date_added` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

View File

@ -1,7 +1,7 @@
CREATE TABLE `branch_details` ( CREATE TABLE `branch_details` (
`id` int NOT NULL AUTO_INCREMENT, `id` int NOT NULL AUTO_INCREMENT,
`branch_name` varchar(30) DEFAULT '', `branch_name` VARCHAR(30) DEFAULT '',
`location` varchar(30) DEFAULT '', `location` VARCHAR(30) DEFAULT '',
`date_added` datetime DEFAULT CURRENT_TIMESTAMP, `date_added` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

View File

@ -1,7 +1,7 @@
CREATE TABLE `customer_details` ( CREATE TABLE `customer_details` (
`id` int NOT NULL AUTO_INCREMENT, `id` INT NOT NULL AUTO_INCREMENT,
`customer_name` varchar(100) DEFAULT '', `customer_name` VARCHAR(100) DEFAULT '',
`branch_name` varchar(30) DEFAULT '', `branch_name` VARCHAR(30) DEFAULT '',
`date_added` datetime DEFAULT CURRENT_TIMESTAMP, `date_added` DATETIME DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`) PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4; ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

View File

@ -1,33 +1,32 @@
use crate::BankDetails;
use crate::BankResponseData;
use crate::BranchDetails;
use crate::BranchResponseData;
use crate::CustomerDetails;
use crate::CustomerResponseData;
use crate::ResponseStatus;
use crate::TellerDetails;
use crate::TellerResponseData;
use actix_web::web; use actix_web::web;
use mysql::prelude::*; use mysql::{params, prelude::*};
use mysql::*;
const ERROR_MESSAGE: &str = "Error occured during processing, please try again."; use crate::{
BankDetails, BankResponseData, BranchDetails, BranchResponseData, CustomerDetails,
CustomerResponseData, ResponseStatus, TellerDetails, TellerResponseData,
};
pub fn create_bank(data: &web::Data<Pool>, bank_name: String, _country: String) -> ResponseStatus { const ERROR_MESSAGE: &str = "Error occurred during processing, please try again.";
pub fn create_bank(
data: &web::Data<mysql::Pool>,
bank_name: String,
_country: String,
) -> ResponseStatus {
let my_status_code: u8 = 1; let my_status_code: u8 = 1;
let my_status_description: String = ERROR_MESSAGE.to_string(); let my_status_description = ERROR_MESSAGE.to_owned();
let mut response_status = ResponseStatus { let mut response_status = ResponseStatus {
status_code: my_status_code, status_code: my_status_code,
status_description: my_status_description, status_description: my_status_description,
}; };
if bank_name.replace(" ", "").trim().len() == 0 { if bank_name.replace(' ', "").trim().is_empty() {
response_status.status_description = String::from("Bank name is empty!"); response_status.status_description = String::from("Bank name is empty!");
return response_status; return response_status;
} }
if _country.replace(" ", "").trim().len() == 0 { if _country.replace(' ', "").trim().is_empty() {
response_status.status_description = String::from("Country is empty!"); response_status.status_description = String::from("Country is empty!");
return response_status; return response_status;
} }
@ -41,31 +40,31 @@ pub fn create_bank(data: &web::Data<Pool>, bank_name: String, _country: String)
response_status.status_description = String::from("Successful"); response_status.status_description = String::from("Successful");
} }
} }
Err(e) => println!("Failed to open DB connection. create_bank {:?}", e), Err(err) => println!("Failed to open DB connection. create_bank {err:?}"),
} }
response_status response_status
} }
pub fn create_branch( pub fn create_branch(
data: &web::Data<Pool>, data: &web::Data<mysql::Pool>,
branch_name: String, branch_name: String,
_location: String, _location: String,
) -> ResponseStatus { ) -> ResponseStatus {
let my_status_code: u8 = 1; let my_status_code: u8 = 1;
let my_status_description: String = ERROR_MESSAGE.to_string(); let my_status_description = ERROR_MESSAGE.to_owned();
let mut response_status = ResponseStatus { let mut response_status = ResponseStatus {
status_code: my_status_code, status_code: my_status_code,
status_description: my_status_description, status_description: my_status_description,
}; };
if branch_name.replace(" ", "").trim().len() == 0 { if branch_name.replace(' ', "").trim().is_empty() {
response_status.status_description = String::from("Branch name is empty!"); response_status.status_description = String::from("Branch name is empty!");
return response_status; return response_status;
} }
if _location.replace(" ", "").trim().len() == 0 { if _location.replace(' ', "").trim().is_empty() {
response_status.status_description = String::from("Location is empty!"); response_status.status_description = String::from("Location is empty!");
return response_status; return response_status;
} }
@ -83,31 +82,31 @@ pub fn create_branch(
response_status.status_description = String::from("Successful"); response_status.status_description = String::from("Successful");
} }
} }
Err(e) => println!("Failed to open DB connection. create_branch {:?}", e), Err(err) => println!("Failed to open DB connection. create_branch {err:?}"),
} }
response_status response_status
} }
pub fn create_teller( pub fn create_teller(
data: &web::Data<Pool>, data: &web::Data<mysql::Pool>,
teller_name: String, teller_name: String,
branch_name: String, branch_name: String,
) -> ResponseStatus { ) -> ResponseStatus {
let my_status_code: u8 = 1; let my_status_code: u8 = 1;
let my_status_description: String = ERROR_MESSAGE.to_string(); let my_status_description = ERROR_MESSAGE.to_owned();
let mut response_status = ResponseStatus { let mut response_status = ResponseStatus {
status_code: my_status_code, status_code: my_status_code,
status_description: my_status_description, status_description: my_status_description,
}; };
if teller_name.replace(" ", "").trim().len() == 0 { if teller_name.replace(' ', "").trim().is_empty() {
response_status.status_description = String::from("Teller name is empty!"); response_status.status_description = String::from("Teller name is empty!");
return response_status; return response_status;
} }
if branch_name.replace(" ", "").trim().len() == 0 { if branch_name.replace(' ', "").trim().is_empty() {
response_status.status_description = String::from("Branch name is empty!"); response_status.status_description = String::from("Branch name is empty!");
return response_status; return response_status;
} }
@ -125,31 +124,31 @@ pub fn create_teller(
response_status.status_description = String::from("Successful"); response_status.status_description = String::from("Successful");
} }
} }
Err(e) => println!("Failed to open DB connection. create_teller {:?}", e), Err(err) => println!("Failed to open DB connection. create_teller {err:?}"),
} }
response_status response_status
} }
pub fn create_customer( pub fn create_customer(
data: &web::Data<Pool>, data: &web::Data<mysql::Pool>,
customer_name: String, customer_name: String,
branch_name: String, branch_name: String,
) -> ResponseStatus { ) -> ResponseStatus {
let my_status_code: u8 = 1; let my_status_code: u8 = 1;
let my_status_description: String = ERROR_MESSAGE.to_string(); let my_status_description = ERROR_MESSAGE.to_owned();
let mut response_status = ResponseStatus { let mut response_status = ResponseStatus {
status_code: my_status_code, status_code: my_status_code,
status_description: my_status_description, status_description: my_status_description,
}; };
if customer_name.replace(" ", "").trim().len() == 0 { if customer_name.replace(' ', "").trim().is_empty() {
response_status.status_description = String::from("Customer name is empty!"); response_status.status_description = String::from("Customer name is empty!");
return response_status; return response_status;
} }
if branch_name.replace(" ", "").trim().len() == 0 { if branch_name.replace(' ', "").trim().is_empty() {
response_status.status_description = String::from("Branch name is empty!"); response_status.status_description = String::from("Branch name is empty!");
return response_status; return response_status;
} }
@ -167,13 +166,13 @@ pub fn create_customer(
response_status.status_description = String::from("Successful"); response_status.status_description = String::from("Successful");
} }
} }
Err(e) => println!("Failed to open DB connection. create_customer {:?}", e), Err(err) => println!("Failed to open DB connection. create_customer {err:?}"),
} }
response_status response_status
} }
pub fn get_bank_data(data: &web::Data<Pool>) -> BankResponseData { pub fn get_bank_data(data: &web::Data<mysql::Pool>) -> BankResponseData {
let mut vec_bank_data = Vec::new(); let mut vec_bank_data = Vec::new();
let mut my_status_code: u8 = 1; let mut my_status_code: u8 = 1;
let mut my_status_description: String = String::from("Record not found"); let mut my_status_description: String = String::from("Record not found");
@ -185,25 +184,24 @@ pub fn get_bank_data(data: &web::Data<Pool>) -> BankResponseData {
Ok(s) => { Ok(s) => {
vec_bank_data = s; vec_bank_data = s;
} }
Err(e) => println!("Failed to open DB connection. {:?}", e), Err(err) => println!("Failed to open DB connection. {err:?}"),
} }
if vec_bank_data.len() > 0 { if !vec_bank_data.is_empty() {
my_status_code = 0; my_status_code = 0;
my_status_description = String::from("Successful"); my_status_description = String::from("Successful");
} }
//Assign values to struct variable //Assign values to struct variable
let output_data = BankResponseData {
BankResponseData {
status_code: my_status_code, status_code: my_status_code,
status_description: my_status_description, status_description: my_status_description,
bank_data: vec_bank_data, bank_data: vec_bank_data,
}; }
output_data
} }
pub fn get_branch_data(data: &web::Data<Pool>) -> BranchResponseData { pub fn get_branch_data(data: &web::Data<mysql::Pool>) -> BranchResponseData {
let mut vec_branch_data = Vec::new(); let mut vec_branch_data = Vec::new();
let mut my_status_code: u8 = 1; let mut my_status_code: u8 = 1;
let mut my_status_description: String = String::from("Record not found"); let mut my_status_description: String = String::from("Record not found");
@ -215,25 +213,24 @@ pub fn get_branch_data(data: &web::Data<Pool>) -> BranchResponseData {
Ok(s) => { Ok(s) => {
vec_branch_data = s; vec_branch_data = s;
} }
Err(e) => println!("Failed to open DB connection. {:?}", e), Err(err) => println!("Failed to open DB connection. {err:?}"),
} }
if vec_branch_data.len() > 0 { if !vec_branch_data.is_empty() {
my_status_code = 0; my_status_code = 0;
my_status_description = String::from("Successful"); my_status_description = String::from("Successful");
} }
//Assign values to struct variable //Assign values to struct variable
let output_data = BranchResponseData {
BranchResponseData {
status_code: my_status_code, status_code: my_status_code,
status_description: my_status_description, status_description: my_status_description,
branch_data: vec_branch_data, branch_data: vec_branch_data,
}; }
output_data
} }
pub fn get_teller_data(data: &web::Data<Pool>) -> TellerResponseData { pub fn get_teller_data(data: &web::Data<mysql::Pool>) -> TellerResponseData {
let mut vec_teller_data = Vec::new(); let mut vec_teller_data = Vec::new();
let mut my_status_code: u8 = 1; let mut my_status_code: u8 = 1;
let mut my_status_description: String = String::from("Record not found"); let mut my_status_description: String = String::from("Record not found");
@ -245,25 +242,23 @@ pub fn get_teller_data(data: &web::Data<Pool>) -> TellerResponseData {
Ok(s) => { Ok(s) => {
vec_teller_data = s; vec_teller_data = s;
} }
Err(e) => println!("Failed to open DB connection. {:?}", e), Err(err) => println!("Failed to open DB connection. {err:?}"),
} }
if vec_teller_data.len() > 0 { if !vec_teller_data.is_empty() {
my_status_code = 0; my_status_code = 0;
my_status_description = String::from("Successful"); my_status_description = String::from("Successful");
} }
//Assign values to struct variable // assign values to struct variable
let output_data = TellerResponseData { TellerResponseData {
status_code: my_status_code, status_code: my_status_code,
status_description: my_status_description, status_description: my_status_description,
teller_data: vec_teller_data, teller_data: vec_teller_data,
}; }
output_data
} }
pub fn get_customer_data(data: &web::Data<Pool>) -> CustomerResponseData { pub fn get_customer_data(data: &web::Data<mysql::Pool>) -> CustomerResponseData {
let mut vec_customer_data = Vec::new(); let mut vec_customer_data = Vec::new();
let mut my_status_code: u8 = 1; let mut my_status_code: u8 = 1;
let mut my_status_description: String = String::from("Record not found"); let mut my_status_description: String = String::from("Record not found");
@ -275,26 +270,24 @@ pub fn get_customer_data(data: &web::Data<Pool>) -> CustomerResponseData {
Ok(s) => { Ok(s) => {
vec_customer_data = s; vec_customer_data = s;
} }
Err(e) => println!("Failed to open DB connection. {:?}", e), Err(err) => println!("Failed to open DB connection. {err:?}"),
} }
if vec_customer_data.len() > 0 { if !vec_customer_data.is_empty() {
my_status_code = 0; my_status_code = 0;
my_status_description = String::from("Successful"); my_status_description = String::from("Successful");
} }
//Assign values to struct variable // assign values to struct variable
let output_data = CustomerResponseData { CustomerResponseData {
status_code: my_status_code, status_code: my_status_code,
status_description: my_status_description, status_description: my_status_description,
customer_data: vec_customer_data, customer_data: vec_customer_data,
}; }
output_data
} }
fn insert_bank_data( fn insert_bank_data(
conn: &mut PooledConn, conn: &mut mysql::PooledConn,
my_bank_name: String, my_bank_name: String,
my_country: String, my_country: String,
) -> std::result::Result<u64, mysql::error::Error> { ) -> std::result::Result<u64, mysql::error::Error> {
@ -306,11 +299,11 @@ fn insert_bank_data(
"country" => my_country, "country" => my_country,
}, },
) )
.and_then(|_| Ok(conn.last_insert_id())) .map(|_| conn.last_insert_id())
} }
fn insert_branch_data( fn insert_branch_data(
conn: &mut PooledConn, conn: &mut mysql::PooledConn,
my_branch_name: String, my_branch_name: String,
my_location: String, my_location: String,
) -> std::result::Result<u64, mysql::error::Error> { ) -> std::result::Result<u64, mysql::error::Error> {
@ -322,11 +315,11 @@ fn insert_branch_data(
"location" => my_location, "location" => my_location,
}, },
) )
.and_then(|_| Ok(conn.last_insert_id())) .map(|_| conn.last_insert_id())
} }
fn insert_teller_data( fn insert_teller_data(
conn: &mut PooledConn, conn: &mut mysql::PooledConn,
my_teller_name: String, my_teller_name: String,
my_branch_name: String, my_branch_name: String,
) -> std::result::Result<u64, mysql::error::Error> { ) -> std::result::Result<u64, mysql::error::Error> {
@ -337,12 +330,11 @@ fn insert_teller_data(
"teller_name" => my_teller_name, "teller_name" => my_teller_name,
"branch_name" => my_branch_name, "branch_name" => my_branch_name,
}, },
) ).map(|_| conn.last_insert_id())
.and_then(|_| Ok(conn.last_insert_id()))
} }
fn insert_customer_data( fn insert_customer_data(
conn: &mut PooledConn, conn: &mut mysql::PooledConn,
my_customer_name: String, my_customer_name: String,
my_branch_name: String, my_branch_name: String,
) -> std::result::Result<u64, mysql::error::Error> { ) -> std::result::Result<u64, mysql::error::Error> {
@ -353,12 +345,11 @@ fn insert_customer_data(
"customer_name" => my_customer_name, "customer_name" => my_customer_name,
"branch_name" => my_branch_name, "branch_name" => my_branch_name,
}, },
) ).map(|_| conn.last_insert_id())
.and_then(|_| Ok(conn.last_insert_id()))
} }
fn select_bank_details( fn select_bank_details(
conn: &mut PooledConn, conn: &mut mysql::PooledConn,
) -> std::result::Result<Vec<BankDetails>, mysql::error::Error> { ) -> std::result::Result<Vec<BankDetails>, mysql::error::Error> {
let mut bank_data = Vec::new(); let mut bank_data = Vec::new();
@ -368,12 +359,11 @@ fn select_bank_details(
let bank_details = BankDetails { bank_name: my_bank_name, country: my_country, }; let bank_details = BankDetails { bank_name: my_bank_name, country: my_country, };
bank_data.push(bank_details); bank_data.push(bank_details);
}, },
) ).map(|_| bank_data)
.and_then(|_| Ok(bank_data))
} }
fn select_branch_details( fn select_branch_details(
conn: &mut PooledConn, conn: &mut mysql::PooledConn,
) -> std::result::Result<Vec<BranchDetails>, mysql::error::Error> { ) -> std::result::Result<Vec<BranchDetails>, mysql::error::Error> {
let mut branch_data = Vec::new(); let mut branch_data = Vec::new();
@ -383,12 +373,11 @@ fn select_branch_details(
let branch_details = BranchDetails { branch_name: my_branch_name, location: my_location, }; let branch_details = BranchDetails { branch_name: my_branch_name, location: my_location, };
branch_data.push(branch_details); branch_data.push(branch_details);
}, },
) ).map(|_| branch_data)
.and_then(|_| Ok(branch_data))
} }
fn select_teller_details( fn select_teller_details(
conn: &mut PooledConn, conn: &mut mysql::PooledConn,
) -> std::result::Result<Vec<TellerDetails>, mysql::error::Error> { ) -> std::result::Result<Vec<TellerDetails>, mysql::error::Error> {
let mut teller_data = Vec::new(); let mut teller_data = Vec::new();
@ -398,12 +387,11 @@ fn select_teller_details(
let teller_details = TellerDetails { teller_name: my_teller_name, branch_name: my_branch_name, }; let teller_details = TellerDetails { teller_name: my_teller_name, branch_name: my_branch_name, };
teller_data.push(teller_details); teller_data.push(teller_details);
}, },
) ).map(|_| teller_data)
.and_then(|_| Ok(teller_data))
} }
fn select_customer_details( fn select_customer_details(
conn: &mut PooledConn, conn: &mut mysql::PooledConn,
) -> std::result::Result<Vec<CustomerDetails>, mysql::error::Error> { ) -> std::result::Result<Vec<CustomerDetails>, mysql::error::Error> {
let mut customer_data = Vec::new(); let mut customer_data = Vec::new();
@ -413,6 +401,5 @@ fn select_customer_details(
let teller_details = CustomerDetails { customer_name: my_customer_name, branch_name: my_branch_name, }; let teller_details = CustomerDetails { customer_name: my_customer_name, branch_name: my_branch_name, };
customer_data.push(teller_details); customer_data.push(teller_details);
}, },
) ).map(|_| customer_data)
.and_then(|_| Ok(customer_data))
} }

View File

@ -1,11 +1,10 @@
mod db_layer; mod db_layer;
use std::{env, str};
use actix_web::{get, post, web, App, HttpServer, Responder}; use actix_web::{get, post, web, App, HttpServer, Responder};
use dotenv::dotenv; use dotenv::dotenv;
use mysql::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::env;
use std::str;
#[derive(Deserialize)] #[derive(Deserialize)]
struct BankData { struct BankData {
@ -92,11 +91,11 @@ pub struct CustomerResponseData {
#[get("/")] #[get("/")]
async fn index() -> impl Responder { async fn index() -> impl Responder {
format!("") String::new()
} }
#[post("/addbank")] #[post("/addbank")]
async fn add_bank(bank_data: web::Json<BankData>, data: web::Data<Pool>) -> impl Responder { async fn add_bank(bank_data: web::Json<BankData>, data: web::Data<mysql::Pool>) -> impl Responder {
let bank_name = &bank_data.bank_name; let bank_name = &bank_data.bank_name;
let _country = &bank_data.country; let _country = &bank_data.country;
@ -106,7 +105,10 @@ async fn add_bank(bank_data: web::Json<BankData>, data: web::Data<Pool>) -> impl
} }
#[post("/addbranch")] #[post("/addbranch")]
async fn add_branch(branch_data: web::Json<BranchData>, data: web::Data<Pool>) -> impl Responder { async fn add_branch(
branch_data: web::Json<BranchData>,
data: web::Data<mysql::Pool>,
) -> impl Responder {
let branch_name = &branch_data.branch_name; let branch_name = &branch_data.branch_name;
let _location = &branch_data.location; let _location = &branch_data.location;
@ -117,7 +119,10 @@ async fn add_branch(branch_data: web::Json<BranchData>, data: web::Data<Pool>) -
} }
#[post("/addteller")] #[post("/addteller")]
async fn add_teller(teller_data: web::Json<TellerData>, data: web::Data<Pool>) -> impl Responder { async fn add_teller(
teller_data: web::Json<TellerData>,
data: web::Data<mysql::Pool>,
) -> impl Responder {
let teller_name = &teller_data.teller_name; let teller_name = &teller_data.teller_name;
let branch_name = &teller_data.branch_name; let branch_name = &teller_data.branch_name;
@ -130,7 +135,7 @@ async fn add_teller(teller_data: web::Json<TellerData>, data: web::Data<Pool>) -
#[post("/addcustomer")] #[post("/addcustomer")]
async fn add_customer( async fn add_customer(
customer_data: web::Json<CustomerData>, customer_data: web::Json<CustomerData>,
data: web::Data<Pool>, data: web::Data<mysql::Pool>,
) -> impl Responder { ) -> impl Responder {
let customer_name = &customer_data.customer_name; let customer_name = &customer_data.customer_name;
let branch_name = &customer_data.branch_name; let branch_name = &customer_data.branch_name;
@ -142,28 +147,28 @@ async fn add_customer(
} }
#[get("/getbank")] #[get("/getbank")]
async fn get_bank(data: web::Data<Pool>) -> impl Responder { async fn get_bank(data: web::Data<mysql::Pool>) -> impl Responder {
let bank_response_data = db_layer::get_bank_data(&data); let bank_response_data = db_layer::get_bank_data(&data);
web::Json(bank_response_data) web::Json(bank_response_data)
} }
#[get("/getbranch")] #[get("/getbranch")]
async fn get_branch(data: web::Data<Pool>) -> impl Responder { async fn get_branch(data: web::Data<mysql::Pool>) -> impl Responder {
let branch_response_data = db_layer::get_branch_data(&data); let branch_response_data = db_layer::get_branch_data(&data);
web::Json(branch_response_data) web::Json(branch_response_data)
} }
#[get("/getteller")] #[get("/getteller")]
async fn get_teller(data: web::Data<Pool>) -> impl Responder { async fn get_teller(data: web::Data<mysql::Pool>) -> impl Responder {
let teller_response_data = db_layer::get_teller_data(&data); let teller_response_data = db_layer::get_teller_data(&data);
web::Json(teller_response_data) web::Json(teller_response_data)
} }
#[get("/getcustomer")] #[get("/getcustomer")]
async fn get_customer(data: web::Data<Pool>) -> impl Responder { async fn get_customer(data: web::Data<mysql::Pool>) -> impl Responder {
let customer_response_data = db_layer::get_customer_data(&data); let customer_response_data = db_layer::get_customer_data(&data);
web::Json(customer_response_data) web::Json(customer_response_data)
@ -175,14 +180,13 @@ fn get_conn_builder(
db_host: String, db_host: String,
db_port: u16, db_port: u16,
db_name: String, db_name: String,
) -> OptsBuilder { ) -> mysql::OptsBuilder {
let builder = OptsBuilder::new() mysql::OptsBuilder::new()
.ip_or_hostname(Some(db_host)) .ip_or_hostname(Some(db_host))
.tcp_port(db_port) .tcp_port(db_port)
.db_name(Some(db_name)) .db_name(Some(db_name))
.user(Some(db_user)) .user(Some(db_user))
.pass(Some(db_password)); .pass(Some(db_password))
builder
} }
#[actix_web::main] #[actix_web::main]
@ -198,13 +202,14 @@ async fn main() {
let mut http_server_status = String::from("[info] ActixWebHttpServer - Listening for HTTP on "); let mut http_server_status = String::from("[info] ActixWebHttpServer - Listening for HTTP on ");
let db_port: u16 = match my_db_port.parse::<u16>() { let db_port: u16 = match my_db_port.parse::<u16>() {
Ok(a) => a, Ok(a) => a,
Err(e) => 0, Err(_err) => 0,
}; };
http_server_status.push_str(&server_addr); http_server_status.push_str(&server_addr);
let builder: OptsBuilder = get_conn_builder(db_user, db_password, db_host, db_port, db_name); let builder: mysql::OptsBuilder =
let pool = match Pool::new(builder) { get_conn_builder(db_user, db_password, db_host, db_port, db_name);
let pool = match mysql::Pool::new(builder) {
Ok(pool) => pool, Ok(pool) => pool,
Err(e) => { Err(e) => {
println!("Failed to open DB connection. {:?}", e); println!("Failed to open DB connection. {:?}", e);

View File

@ -106,6 +106,6 @@ mod tests {
assert_eq!(resp.status(), http::StatusCode::OK); assert_eq!(resp.status(), http::StatusCode::OK);
let body_bytes = to_bytes(resp.into_body()).await.unwrap(); let body_bytes = to_bytes(resp.into_body()).await.unwrap();
assert_eq!(body_bytes, r##"{"name":"my-name","number":43}"##); assert_eq!(body_bytes, r#"{"name":"my-name","number":43}"#);
} }
} }