first working version

main
Mathias Rothenhaeusler 2023-03-31 18:14:48 +02:00
parent 88a70e911d
commit 33fbe778e7
5 changed files with 1779 additions and 2 deletions

1659
Cargo.lock generated 100644

File diff suppressed because it is too large Load Diff

View File

@ -6,3 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
directories = "5.0.0"
dotenv = "0.15.0"
mysql = "23.0.1"
sprintf = "0.1.3"

View File

@ -0,0 +1,60 @@
use mysql::{Pool, PooledConn, Opts};
use sprintf::sprintf;
use std::{env, path::PathBuf};
use directories::BaseDirs;
#[derive(Debug)]
pub struct Db {
location: String,
user: String,
port: String,
password: String,
db_name: String,
}
impl Db {
pub fn initialize() -> Self {
let base_dir: BaseDirs = match BaseDirs::new() {
Some(dirs) => dirs,
None => panic!("No config folder found."),
};
let config_file_path: PathBuf = base_dir.config_dir().join("rcc/.env");
match dotenv::from_path(config_file_path.as_path()) {
Ok(env) => env,
Err(_) => panic!("Could not load .env file {:?}", config_file_path.as_path()),
};
Db {
location: env::var("LOCATION").unwrap_or_else(|_| "localhost".to_string()),
user: env::var("USERNAME").unwrap(),
port: env::var("PORT").unwrap_or_else(|_| "3306".to_string()),
password: env::var("PASSWORD").unwrap(),
db_name: env::var("DB").unwrap_or_else(|_| "efulfilment".to_string()),
}
}
pub fn get_connection(&self) -> PooledConn {
let url = sprintf!(
"mysql://%s:%s@%s:%s/%s",
self.user,
self.password,
self.location,
self.port,
self.db_name
).unwrap();
let pool = match Pool::new(Opts::from_url(&url).unwrap()) {
Ok(p) => p,
Err(e) => panic!("Cannot initialiaz pool: {e}"),
};
let conn: PooledConn = match pool.get_conn() {
Ok(db) => db,
Err(_) => panic!("Cannot connect to DB"),
};
conn
}
}

View File

@ -0,0 +1 @@
pub mod database;

View File

@ -1,3 +1,56 @@
fn main() {
println!("Hello, world!");
use config::database::Db;
use mysql::{prelude::Queryable, PooledConn, params};
pub mod config;
#[derive(Debug, PartialEq, Eq)]
struct Payment {
customer_id: i32,
amount: i32,
account_name: Option<String>,
}
fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
let db = Db::initialize();
let mut conn: PooledConn = db.get_connection();
conn.query_drop(
r"CREATE TEMPORARY TABLE payment (
customer_id int not null,
amount int not null,
account_name text
)")?;
let payments = vec![
Payment { customer_id: 1, amount: 2, account_name: None },
Payment { customer_id: 3, amount: 4, account_name: Some("foo".into()) },
Payment { customer_id: 5, amount: 6, account_name: None },
Payment { customer_id: 7, amount: 8, account_name: None },
Payment { customer_id: 9, amount: 10, account_name: Some("bar".into()) },
];
// Now let's insert payments to the database
conn.exec_batch(
r"INSERT INTO payment (customer_id, amount, account_name)
VALUES (:customer_id, :amount, :account_name)",
payments.iter().map(|p| params! {
"customer_id" => p.customer_id,
"amount" => p.amount,
"account_name" => &p.account_name,
})
)?;
// Let's select payments from database. Type inference should do the trick here.
let selected_payments = conn
.query_map(
"SELECT customer_id, amount, account_name from payment",
|(customer_id, amount, account_name)| {
Payment { customer_id, amount, account_name }
},
)?;
for payment in selected_payments {
println!("{:?}", payment);
}
Ok(())
}