Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions r2d2_firebird/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,12 @@ rsfbclient = { version = "0.25.2", path = "../", default-features = false }
rsfbclient-core = { version = "0.25.2", path = "../rsfbclient-core" }
r2d2 = "0.8.9"

diesel = { version = "2.0.0", optional = true }
rsfbclient-diesel = { version = "0.25.1", path = "../rsfbclient-diesel", optional = true }

[features]
default=[]
diesel_pool=["diesel", "rsfbclient-diesel"]

[dev-dependencies]
rsfbclient = { version = "0.25.2", path = "../", features = ["pure_rust"], default-features = false }
45 changes: 45 additions & 0 deletions r2d2_firebird/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,48 @@ where
false
}
}

// Implementation for Diesel
#[cfg(feature = "diesel_pool")]
mod diesel_manager {
use diesel::prelude::*;
use diesel::{sql_query, Connection, ConnectionError};
use rsfbclient_diesel::FbConnection;

pub struct DieselConnectionManager {
connection_string: String,
}

impl DieselConnectionManager {
pub fn new(database_url: &str) -> Self {
Self {
connection_string: database_url.to_string(),
}
}
}

impl r2d2::ManageConnection for DieselConnectionManager {
type Connection = FbConnection;
type Error = ConnectionError;

fn connect(&self) -> Result<Self::Connection, Self::Error> {
FbConnection::establish(&self.connection_string)
}

fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> {
sql_query("SELECT 1 FROM RDB$DATABASE")
.execute(conn)
.map(|_| ())
.map_err(|_| {
ConnectionError::BadConnection("Diesel pooled connection check failed.".into())
})
}

fn has_broken(&self, _conn: &mut Self::Connection) -> bool {
false
}
}
}

#[cfg(feature = "diesel_pool")]
pub use diesel_manager::DieselConnectionManager;
19 changes: 19 additions & 0 deletions rsfbclient-diesel/examples/employee_pool/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Cargo
# will have compiled files and executables
/target/
lcov.info

# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock

# These are backup files generated by rustfmt
**/*.rs.bk

tests/use

# firebird lib
fbclient.lib

# vscode conf folder
.vscode
16 changes: 16 additions & 0 deletions rsfbclient-diesel/examples/employee_pool/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "employee-pool"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
diesel = "2.0.0"
rsfbclient-diesel = "0.25.0"
r2d2 = "0.8.10"
rsfbclient = "0.25.2"
r2d2_firebird = {version="0.25.2", path="../../../r2d2_firebird", features=["diesel_pool"]}
rsfbclient-core = "0.25.2"

[workspace]
4 changes: 4 additions & 0 deletions rsfbclient-diesel/examples/employee_pool/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

# Diesel with connection pooling example.

This example use the `employee.fdb` database, present in your Firebird instalation. You also can get this database in `examples/empbuild` folder from the [official instalation files](https://firebirdsql.org/en/firebird-4-0/)
51 changes: 51 additions & 0 deletions rsfbclient-diesel/examples/employee_pool/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use diesel::{QueryDsl, RunQueryDsl};
use r2d2::Pool;
use r2d2_firebird::DieselConnectionManager;
use std::{env, sync::Arc, thread, time::Duration};

use schema::{job::dsl::*, Job};

mod schema;

fn main() {

let connecton_string = env::var("DIESELFDB_CONN").expect("DIESELFDB_CONN env not found");

let manager = DieselConnectionManager::new(&connecton_string);
let pool = Arc::new(
Pool::builder()
.max_size(4)
.build(manager)
.expect("Failed to build connection pooling."),
);

let mut tasks = vec![];

for n in 0..3 {
let pool = pool.clone();
let th = thread::spawn(move || loop {

match pool.get() {
Ok(mut conn) => match job.offset(n).limit(1).first::<Job>(&mut *conn) {
Ok(model) => {
println!("Thread {}: {}", n, model.title)
}

Err(e) => println!("Execute query error in line:{} ! error: {:?}", line!(), e),
},
Err(e) => println!(
"Get connection from pool error in line:{} ! error: {:?}",
line!(),
e
),
}

thread::sleep(Duration::from_secs(1));
});
tasks.push(th);
}

for th in tasks {
let _ = th.join();
}
}
28 changes: 28 additions & 0 deletions rsfbclient-diesel/examples/employee_pool/src/schema.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
use diesel::{ Queryable };

#[allow(dead_code)]
#[derive(Queryable)]
#[diesel(table_name = job)]
pub struct Job {
#[diesel(column_name = job_code)]
pub code: String,
#[diesel(column_name = job_title)]
pub title: String,
#[diesel(column_name = job_country)]
pub country: String,
#[diesel(column_name = job_grade)]
pub grade: i16,
pub min_salary: f32,
pub max_salary: f32,
}

diesel::table! {
job(job_code) {
job_code -> Text,
job_title -> Text,
job_country -> Text,
job_grade -> Smallint,
min_salary -> Float,
max_salary -> Float,
}
}
Loading