mirror of
https://github.com/okiba-org/backend.git
synced 2025-02-23 17:52:03 +00:00
add /paste route and setup db
Signed-off-by: alok8bb <alok8bb@gmail.com>
This commit is contained in:
parent
de72d0be60
commit
0923b46377
25
Cargo.lock
generated
25
Cargo.lock
generated
@ -935,10 +935,15 @@ dependencies = [
|
|||||||
"actix-web",
|
"actix-web",
|
||||||
"config",
|
"config",
|
||||||
"deadpool-postgres",
|
"deadpool-postgres",
|
||||||
|
"derive_more",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"log",
|
"log",
|
||||||
|
"rand",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tokio-pg-mapper",
|
||||||
|
"tokio-pg-mapper-derive",
|
||||||
"tokio-postgres",
|
"tokio-postgres",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -1515,6 +1520,26 @@ dependencies = [
|
|||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-pg-mapper"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "93f2b78f3566383ffabc553c72bbb2f129962a54886c5c4d8e8c706f84eceab8"
|
||||||
|
dependencies = [
|
||||||
|
"tokio-postgres",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-pg-mapper-derive"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8548f756cd6eb4069c5af0fb0cec57001fb42bd1fb7330d8f24067ee3fa62608"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
"tokio-postgres",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-postgres"
|
name = "tokio-postgres"
|
||||||
version = "0.7.8"
|
version = "0.7.8"
|
||||||
|
@ -9,8 +9,13 @@ edition = "2021"
|
|||||||
actix-web = "4"
|
actix-web = "4"
|
||||||
config = "0.13.3"
|
config = "0.13.3"
|
||||||
deadpool-postgres = { version = "0.10.5", features = ["serde"] }
|
deadpool-postgres = { version = "0.10.5", features = ["serde"] }
|
||||||
|
derive_more = "0.99.17"
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
env_logger = "0.10.0"
|
env_logger = "0.10.0"
|
||||||
log = "0.4.19"
|
log = "0.4.19"
|
||||||
|
rand = "0.8.5"
|
||||||
serde = { version = "1.0.178", features = ["derive"] }
|
serde = { version = "1.0.178", features = ["derive"] }
|
||||||
|
serde_json = "1.0.104"
|
||||||
|
tokio-pg-mapper = "0.2.0"
|
||||||
|
tokio-pg-mapper-derive = "0.2.0"
|
||||||
tokio-postgres = "0.7.8"
|
tokio-postgres = "0.7.8"
|
||||||
|
65
src/db.rs
Normal file
65
src/db.rs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
use deadpool_postgres::Client;
|
||||||
|
|
||||||
|
use self::errors::MyError;
|
||||||
|
|
||||||
|
mod models {
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tokio_pg_mapper_derive::PostgresMapper;
|
||||||
|
|
||||||
|
#[derive(Deserialize, PostgresMapper, Serialize)]
|
||||||
|
#[pg_mapper(table = "pastes")]
|
||||||
|
pub struct Paste {
|
||||||
|
pub endpoint: String,
|
||||||
|
pub content: String,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod errors {
|
||||||
|
use actix_web::{HttpResponse, ResponseError};
|
||||||
|
use deadpool_postgres::PoolError;
|
||||||
|
use derive_more::{Display, From};
|
||||||
|
use serde_json::json;
|
||||||
|
use tokio_pg_mapper::Error as PGMError;
|
||||||
|
use tokio_postgres::error::Error as PGError;
|
||||||
|
|
||||||
|
#[derive(Display, From, Debug)]
|
||||||
|
pub enum MyError {
|
||||||
|
NotFound,
|
||||||
|
PGError(PGError),
|
||||||
|
PGMError(PGMError),
|
||||||
|
PoolError(PoolError),
|
||||||
|
}
|
||||||
|
impl std::error::Error for MyError {}
|
||||||
|
|
||||||
|
impl ResponseError for MyError {
|
||||||
|
fn error_response(&self) -> HttpResponse {
|
||||||
|
match *self {
|
||||||
|
MyError::NotFound => HttpResponse::NotFound().json(json!({
|
||||||
|
"message": "record not found"
|
||||||
|
})),
|
||||||
|
MyError::PoolError(ref err) => HttpResponse::InternalServerError().json(json!({
|
||||||
|
"message": err.to_string()
|
||||||
|
})),
|
||||||
|
_ => HttpResponse::InternalServerError().json(json!({
|
||||||
|
"message": "internal server error"
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn paste_id_exists(client: &Client, paste_id: &String) -> Result<bool, MyError> {
|
||||||
|
let stmt_ = format!("SELECT 1 FROM bin.pastes WHERE paste_id = $1 LIMIT 1");
|
||||||
|
let stmt = client.prepare(&stmt_).await.unwrap();
|
||||||
|
|
||||||
|
let rows = client.query(&stmt, &[&paste_id]).await?;
|
||||||
|
Ok(!rows.is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn add_paste(client: &Client, endpoint: &String, content: String) -> Result<(), MyError> {
|
||||||
|
let insert_stmt_ = format!("INSERT INTO bin.pastes(paste_id, content) VALUES($1, $2)");
|
||||||
|
let insert_stmt = client.prepare(&insert_stmt_).await.unwrap();
|
||||||
|
|
||||||
|
client.query(&insert_stmt, &[&endpoint, &content]).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
41
src/main.rs
41
src/main.rs
@ -1,18 +1,46 @@
|
|||||||
mod cfg;
|
mod cfg;
|
||||||
|
mod db;
|
||||||
|
use crate::db::errors::MyError;
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
post,
|
post,
|
||||||
web::{self, Bytes},
|
web::{self},
|
||||||
App, HttpServer,
|
App, Error, HttpResponse, HttpServer,
|
||||||
};
|
};
|
||||||
use cfg::AppConfig;
|
use cfg::AppConfig;
|
||||||
|
use deadpool_postgres::{Client, Pool};
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
|
use rand::{distributions::Alphanumeric, Rng};
|
||||||
|
use serde_json::json;
|
||||||
use std::str::{self};
|
use std::str::{self};
|
||||||
use tokio_postgres::NoTls;
|
use tokio_postgres::NoTls;
|
||||||
|
|
||||||
|
fn generate_endpoint(length: u8) -> String {
|
||||||
|
rand::thread_rng()
|
||||||
|
.sample_iter(&Alphanumeric)
|
||||||
|
.take(length as usize)
|
||||||
|
.map(char::from)
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/paste")]
|
#[post("/paste")]
|
||||||
async fn greet(bytes: Bytes) -> &'static str {
|
async fn paste(db_pool: web::Data<Pool>, body: String) -> Result<HttpResponse, Error> {
|
||||||
let payload = str::from_utf8(&bytes).unwrap();
|
let client: Client = db_pool.get().await.map_err(MyError::PoolError)?;
|
||||||
"Hello World!"
|
|
||||||
|
let mut endpoint = generate_endpoint(5);
|
||||||
|
// check if endpoint already exists
|
||||||
|
loop {
|
||||||
|
if db::paste_id_exists(&client, &endpoint).await? {
|
||||||
|
endpoint = generate_endpoint(5)
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
db::add_paste(&client, &endpoint, body).await?;
|
||||||
|
Ok(HttpResponse::Ok().json(json!({
|
||||||
|
"paste_id": endpoint,
|
||||||
|
"message": "code pasted successfully",
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
@ -22,12 +50,13 @@ 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"));
|
||||||
|
|
||||||
let config = AppConfig::from_env().unwrap();
|
let config = AppConfig::from_env().unwrap();
|
||||||
|
log::info!("Connecting database");
|
||||||
let pool = config.pg.create_pool(None, NoTls).unwrap();
|
let pool = config.pg.create_pool(None, NoTls).unwrap();
|
||||||
|
|
||||||
let server = HttpServer::new(move || {
|
let server = HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
.app_data(web::Data::new(pool.clone()))
|
.app_data(web::Data::new(pool.clone()))
|
||||||
.service(greet)
|
.service(paste)
|
||||||
})
|
})
|
||||||
.bind(ADDR)?
|
.bind(ADDR)?
|
||||||
.run();
|
.run();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user