Переписал на pool
This commit is contained in:
parent
6fb20ef6d7
commit
3360706756
32
Cargo.lock
generated
32
Cargo.lock
generated
@ -1244,6 +1244,8 @@ dependencies = [
|
|||||||
"deadpool-postgres",
|
"deadpool-postgres",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
|
"r2d2",
|
||||||
|
"r2d2_sqlite",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
"serde",
|
"serde",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
@ -1644,6 +1646,27 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r2d2"
|
||||||
|
version = "0.8.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51de85fb3fb6524929c8a2eb85e6b6d363de4e8c48f9e2c2eac4944abc181c93"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"parking_lot 0.12.1",
|
||||||
|
"scheduled-thread-pool",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r2d2_sqlite"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b4f5d0337e99cd5cacd91ffc326c6cc9d8078def459df560c4f9bf9ba4a51034"
|
||||||
|
dependencies = [
|
||||||
|
"r2d2",
|
||||||
|
"rusqlite",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@ -1786,6 +1809,15 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scheduled-thread-pool"
|
||||||
|
version = "0.2.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "977a7519bff143a44f842fd07e80ad1329295bd71686457f18e496736f4bf9bf"
|
||||||
|
dependencies = [
|
||||||
|
"parking_lot 0.12.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.1.0"
|
version = "1.1.0"
|
||||||
|
@ -13,6 +13,8 @@ serde = "1.0.8"
|
|||||||
deadpool-postgres = { version = "0.10.2", features = ["serde"] }
|
deadpool-postgres = { version = "0.10.2", features = ["serde"] }
|
||||||
tokio-postgres = "0.7.6"
|
tokio-postgres = "0.7.6"
|
||||||
rusqlite = { version = "0.28.0", features = ["bundled"] }
|
rusqlite = { version = "0.28.0", features = ["bundled"] }
|
||||||
|
r2d2 = "0.8"
|
||||||
|
r2d2_sqlite = "0.21"
|
||||||
actix-files = "0.6"
|
actix-files = "0.6"
|
||||||
env_logger = "0.9.0"
|
env_logger = "0.9.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
@ -1,8 +1,7 @@
|
|||||||
use rusqlite::{Connection, Error, Result};
|
use rusqlite::{Error, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Cat {
|
pub struct Cat {
|
||||||
id: i32,
|
id: i32,
|
||||||
@ -20,22 +19,26 @@ pub type CatsResult = Result<Vec<Cat>, Error>;
|
|||||||
pub type ColorsResult = Result<Vec<Color>, Error>;
|
pub type ColorsResult = Result<Vec<Color>, Error>;
|
||||||
pub type CatResult = Result<Cat, Error>;
|
pub type CatResult = Result<Cat, Error>;
|
||||||
pub type ColorResult = Result<Color, Error>;
|
pub type ColorResult = Result<Color, Error>;
|
||||||
|
pub type Pool = r2d2::Pool<r2d2_sqlite::SqliteConnectionManager>;
|
||||||
|
|
||||||
// Сервис базы данных
|
// Сервис базы данных
|
||||||
|
#[derive(std::clone::Clone)]
|
||||||
pub struct Service {
|
pub struct Db {
|
||||||
db: rusqlite::Connection,
|
pool: Pool,
|
||||||
}
|
}
|
||||||
impl Service {
|
|
||||||
|
impl Db {
|
||||||
|
pub async fn new(pool: Pool) -> Db {
|
||||||
|
return Db { pool: pool };
|
||||||
|
}
|
||||||
// Создание сервиса
|
// Создание сервиса
|
||||||
pub fn new() -> Service {
|
pub async fn init(&self) {
|
||||||
let conn = Connection::open("cats.db");
|
let conn = match self.pool.get() {
|
||||||
let db_con = match conn {
|
|
||||||
Ok(conn) => conn,
|
Ok(conn) => conn,
|
||||||
Err(error) => panic!("Problem opening the db: {:?}", error),
|
Err(err) => panic!("{}", err),
|
||||||
};
|
};
|
||||||
db_con
|
|
||||||
.execute(
|
conn.execute(
|
||||||
"create table if not exists cat_colors (
|
"create table if not exists cat_colors (
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
name text not null unique
|
name text not null unique
|
||||||
@ -43,8 +46,7 @@ impl Service {
|
|||||||
[],
|
[],
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
db_con
|
conn.execute(
|
||||||
.execute(
|
|
||||||
"create table if not exists cats (
|
"create table if not exists cats (
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
name text not null,
|
name text not null,
|
||||||
@ -57,27 +59,29 @@ impl Service {
|
|||||||
cat_colors.insert(String::from("Blue"), vec!["Tigger", "Sammy"]);
|
cat_colors.insert(String::from("Blue"), vec!["Tigger", "Sammy"]);
|
||||||
cat_colors.insert(String::from("Black"), vec!["Oreo", "Biscuit"]);
|
cat_colors.insert(String::from("Black"), vec!["Oreo", "Biscuit"]);
|
||||||
for (color, catnames) in &cat_colors {
|
for (color, catnames) in &cat_colors {
|
||||||
db_con
|
conn.execute(
|
||||||
.execute(
|
|
||||||
"INSERT INTO cat_colors (name) values (?1)",
|
"INSERT INTO cat_colors (name) values (?1)",
|
||||||
&[&color.to_string()],
|
&[&color.to_string()],
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
let last_id: String = db_con.last_insert_rowid().to_string();
|
let last_id: String = conn.last_insert_rowid().to_string();
|
||||||
for cat in catnames {
|
for cat in catnames {
|
||||||
db_con
|
conn.execute(
|
||||||
.execute(
|
|
||||||
"INSERT INTO cats (name, color_id) values (?1, ?2)",
|
"INSERT INTO cats (name, color_id) values (?1, ?2)",
|
||||||
&[&cat.to_string(), &last_id],
|
&[&cat.to_string(), &last_id],
|
||||||
)
|
)
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Service { db: db_con };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Получение кошек
|
// Получение кошек
|
||||||
pub fn get_cats(&self) -> CatsResult {
|
pub fn get_cats(&self) -> CatsResult {
|
||||||
let mut stmt = self.db.prepare(
|
let conn = match self.pool.get() {
|
||||||
|
Ok(conn) => conn,
|
||||||
|
Err(err) => panic!("{}", err),
|
||||||
|
};
|
||||||
|
let mut stmt = conn.prepare(
|
||||||
"SELECT c.id, c.name, cc.name from cats c INNER JOIN cat_colors cc ON cc.id = c.color_id;",
|
"SELECT c.id, c.name, cc.name from cats c INNER JOIN cat_colors cc ON cc.id = c.color_id;",
|
||||||
)?;
|
)?;
|
||||||
return stmt
|
return stmt
|
||||||
@ -93,7 +97,11 @@ impl Service {
|
|||||||
|
|
||||||
// Получение цветов
|
// Получение цветов
|
||||||
pub fn get_colors(&self) -> ColorsResult {
|
pub fn get_colors(&self) -> ColorsResult {
|
||||||
let mut stmt = self.db.prepare("SELECT id, name from cat_colors")?;
|
let conn = match self.pool.get() {
|
||||||
|
Ok(conn) => conn,
|
||||||
|
Err(err) => panic!("{}", err),
|
||||||
|
};
|
||||||
|
let mut stmt = conn.prepare("SELECT id, name from cat_colors")?;
|
||||||
return stmt
|
return stmt
|
||||||
.query_map([], |row| {
|
.query_map([], |row| {
|
||||||
Ok(Color {
|
Ok(Color {
|
||||||
@ -106,7 +114,11 @@ impl Service {
|
|||||||
|
|
||||||
// Добавление кошки
|
// Добавление кошки
|
||||||
pub fn add_cat(&self, cat_name: String, cat_color: String) -> CatResult {
|
pub fn add_cat(&self, cat_name: String, cat_color: String) -> CatResult {
|
||||||
return self.db.query_row("INSERT INTO cats (name, color_id) SELECT ?1, id FROM cat_colors cc WHERE name = ?2 RETURNING id, name, ?2",
|
let conn = match self.pool.get() {
|
||||||
|
Ok(conn) => conn,
|
||||||
|
Err(err) => panic!("{}", err),
|
||||||
|
};
|
||||||
|
return conn.query_row("INSERT INTO cats (name, color_id) SELECT ?1, id FROM cat_colors cc WHERE name = ?2 RETURNING id, name, ?2",
|
||||||
[cat_name, cat_color],
|
[cat_name, cat_color],
|
||||||
|row| {
|
|row| {
|
||||||
Ok(Cat {
|
Ok(Cat {
|
||||||
@ -119,7 +131,11 @@ impl Service {
|
|||||||
}
|
}
|
||||||
// Добавление цвета
|
// Добавление цвета
|
||||||
pub fn add_color(&self, color_name: String) -> ColorResult {
|
pub fn add_color(&self, color_name: String) -> ColorResult {
|
||||||
return self.db.query_row(
|
let conn = match self.pool.get() {
|
||||||
|
Ok(conn) => conn,
|
||||||
|
Err(err) => panic!("{}", err),
|
||||||
|
};
|
||||||
|
return conn.query_row(
|
||||||
"INSERT INTO cat_colors (name) VALUES (?1) RETURNING id, name",
|
"INSERT INTO cat_colors (name) VALUES (?1) RETURNING id, name",
|
||||||
[color_name],
|
[color_name],
|
||||||
|row| {
|
|row| {
|
||||||
|
@ -1,35 +1,32 @@
|
|||||||
pub mod db;
|
pub mod db;
|
||||||
use actix_web::{get,post, web, HttpResponse, Responder, Result};
|
use db::{Db};
|
||||||
|
use actix_web::{get, post, web, HttpResponse, Responder, Result};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub struct Service {
|
|
||||||
pub db: db::Service,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct ArrayResponse<T> {
|
struct ArrayResponse<T> {
|
||||||
result: Vec<T>,
|
result: Vec<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct AddColorRequest {
|
pub struct AddColorRequest {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/cats")]
|
#[get("/cats")]
|
||||||
pub async fn get_cats(ctx: web::Data<Service>) -> Result<impl Responder> {
|
pub async fn get_cats(db: web::Data<Db>) -> Result<impl Responder> {
|
||||||
let cats = ctx.db.get_cats();
|
|
||||||
|
let cats = db.get_cats();
|
||||||
let res = match cats {
|
let res = match cats {
|
||||||
Ok(v) => ArrayResponse{ result: v },
|
Ok(v) => ArrayResponse { result: v },
|
||||||
Err(_err) => ArrayResponse { result: vec![] },
|
Err(_err) => ArrayResponse { result: vec![] },
|
||||||
};
|
};
|
||||||
return Ok(HttpResponse::Ok().json(res));
|
return Ok(HttpResponse::Ok().json(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/colors")]
|
#[get("/colors")]
|
||||||
pub async fn get_colors(ctx: web::Data<Service>) -> Result<impl Responder> {
|
pub async fn get_colors(db: web::Data<Db>) -> Result<impl Responder> {
|
||||||
let colors = ctx.db.get_colors();
|
let colors = db.get_colors();
|
||||||
let res = match colors {
|
let res = match colors {
|
||||||
Ok(v) => ArrayResponse { result: v },
|
Ok(v) => ArrayResponse { result: v },
|
||||||
Err(_err) => ArrayResponse { result: vec![] },
|
Err(_err) => ArrayResponse { result: vec![] },
|
||||||
@ -43,14 +40,13 @@ pub struct AddCatRequest {
|
|||||||
pub color: String,
|
pub color: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[post("/add/cat")]
|
#[post("/add/cat")]
|
||||||
pub async fn add_cat(
|
pub async fn add_cat(
|
||||||
ctx: web::Data<Service>,
|
db: web::Data<Db>,
|
||||||
cat: web::Json<AddCatRequest>,
|
cat: web::Json<AddCatRequest>,
|
||||||
) -> Result<impl Responder> {
|
) -> Result<impl Responder> {
|
||||||
let _cat = cat.into_inner();
|
let _cat = cat.into_inner();
|
||||||
let cat = ctx.db.add_cat(_cat.name, _cat.color);
|
let cat = db.add_cat(_cat.name, _cat.color);
|
||||||
let res = match cat {
|
let res = match cat {
|
||||||
Ok(v) => ArrayResponse { result: vec![v] },
|
Ok(v) => ArrayResponse { result: vec![v] },
|
||||||
Err(_err) => panic!("{:?}", _err),
|
Err(_err) => panic!("{:?}", _err),
|
||||||
@ -60,15 +56,14 @@ pub async fn add_cat(
|
|||||||
|
|
||||||
#[post("/add/color")]
|
#[post("/add/color")]
|
||||||
pub async fn add_color(
|
pub async fn add_color(
|
||||||
ctx: web::Data<Service>,
|
db: web::Data<Db>,
|
||||||
cat: web::Json<AddColorRequest>,
|
cat: web::Json<AddColorRequest>,
|
||||||
) -> Result<impl Responder> {
|
) -> Result<impl Responder> {
|
||||||
let _color = cat.into_inner();
|
let _color = cat.into_inner();
|
||||||
let cat = ctx.db.add_color(_color.name);
|
let cat = db.add_color(_color.name);
|
||||||
let res = match cat {
|
let res = match cat {
|
||||||
Ok(v) => ArrayResponse { result: vec![v] },
|
Ok(v) => ArrayResponse { result: vec![v] },
|
||||||
Err(_err) => panic!("{:?}", _err),
|
Err(_err) => panic!("{:?}", _err),
|
||||||
};
|
};
|
||||||
return Ok(HttpResponse::Ok().json(res));
|
return Ok(HttpResponse::Ok().json(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
18
src/main.rs
18
src/main.rs
@ -1,8 +1,10 @@
|
|||||||
use config::Config;
|
use config::Config;
|
||||||
mod cfg;
|
|
||||||
mod cats;
|
mod cats;
|
||||||
|
mod cfg;
|
||||||
use actix_files::Files;
|
use actix_files::Files;
|
||||||
use actix_web::{web, App, HttpServer};
|
use actix_web::{middleware, web, App, HttpServer};
|
||||||
|
use cats::db::{Db, Pool};
|
||||||
|
use r2d2_sqlite::{self, SqliteConnectionManager};
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
pub async fn main() -> std::io::Result<()> {
|
pub async fn main() -> std::io::Result<()> {
|
||||||
@ -18,11 +20,15 @@ pub async fn main() -> std::io::Result<()> {
|
|||||||
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
|
||||||
log::info!("starting HTTP server at http://{}:{}", app.host, app.port);
|
log::info!("starting HTTP server at http://{}:{}", app.host, app.port);
|
||||||
|
|
||||||
HttpServer::new(|| {
|
let manager = SqliteConnectionManager::file("cats.db");
|
||||||
|
let pool = Pool::new(manager).unwrap();
|
||||||
|
let db = Db::new(pool.clone()).await;
|
||||||
|
db.init().await;
|
||||||
|
|
||||||
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(web::Data::new(cats::Service {
|
.app_data(web::Data::new(db.clone()))
|
||||||
db: cats::db::Service::new(),
|
.wrap(middleware::Logger::default())
|
||||||
}))
|
|
||||||
.service(cats::get_cats)
|
.service(cats::get_cats)
|
||||||
.service(cats::get_colors)
|
.service(cats::get_colors)
|
||||||
.service(cats::add_cat)
|
.service(cats::add_cat)
|
||||||
|
Loading…
Reference in New Issue
Block a user