feature: svp

This commit is contained in:
Dominic Harris 2022-03-26 08:19:15 -04:00
parent dc5c178152
commit c179f8bf90
No known key found for this signature in database
GPG Key ID: 93CCF85F3E2A4F65
3 changed files with 42 additions and 13 deletions

View File

@ -2,10 +2,13 @@ CREATE TABLE IF NOT EXISTS pastes (
"id" TEXT PRIMARY KEY,
"content" TEXT NOT NULL,
"views" BIGINT DEFAULT 0,
"single_view" BOOLEAN DEFAULT false,
"expires_at" TIMESTAMP WITHOUT TIME ZONE,
"created_at" TIMESTAMP WITHOUT TIME ZONE DEFAULT(NOW() AT TIME ZONE 'utc')
);
-- ALTER TABLE pastes ADD COLUMN single_view BOOLEAN DEFAULT false;
CREATE OR REPLACE FUNCTION deleteExpiredPastes() RETURNS trigger AS $pastes_expire$ BEGIN
DELETE FROM pastes
WHERE "expires_at" IS NOT NULL

View File

@ -7,12 +7,14 @@ pub struct Paste {
pub id: String,
pub content: String,
pub views: i64,
pub single_view: bool,
pub expires_at: Option<NaiveDateTime>,
}
#[derive(Deserialize)]
pub struct PartialPaste {
pub content: String,
pub single_view: bool
}
#[derive(Serialize)]
@ -25,6 +27,7 @@ pub struct ApiResponse<T> {
pub struct NewPasteResponse {
pub id: String,
pub content: String,
pub single_view: bool,
}
#[derive(Serialize)]
@ -32,6 +35,7 @@ pub struct GetPasteResponse {
pub id: String,
pub content: String,
pub views: i64,
pub single_view: bool,
pub expires_at: Option<NaiveDateTime>,
}

View File

@ -32,11 +32,18 @@ pub async fn get_paste(state: web::Data<AppState>, id: web::Path<String>) -> imp
match res {
Ok(p) => {
// this may be worth handling at some point..
let _ = sqlx::query(r#"UPDATE pastes SET "views" = "views" + 1 WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
// Only increment views if its not a single view paste
if p.single_view {
let _ = sqlx::query(r#"DELETE FORM pastes WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
} else {
let _ = sqlx::query(r#"UPDATE pastes SET "views" = "views" + 1 WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
}
if state.config.logging.on_get_paste {
println!("[GET] id={} views={}", id, p.views + 1);
@ -48,6 +55,7 @@ pub async fn get_paste(state: web::Data<AppState>, id: web::Path<String>) -> imp
id: p.id,
content: p.content,
views: p.views + 1,
single_view: p.single_view,
expires_at: p.expires_at,
},
})
@ -87,13 +95,21 @@ pub async fn get_raw_paste(state: web::Data<AppState>, id: web::Path<String>) ->
match res {
Ok(p) => {
// this may be worth handling at some point..
let _ = sqlx::query(r#"UPDATE pastes SET "views" = "views" + 1 WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
if p.single_view {
let _ = sqlx::query(r#"DELETE FORM pastes WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
} else {
let _ = sqlx::query(r#"UPDATE pastes SET "views" = "views" + 1 WHERE "id" = $1"#)
.bind(id.clone())
.execute(&state.pool)
.await;
}
HttpResponse::Ok().content_type("text/plain").body(p.content)
HttpResponse::Ok()
.content_type("text/plain")
.body(p.content)
}
Err(e) => match e {
sqlx::Error::RowNotFound => {
@ -144,11 +160,13 @@ pub async fn new_paste(
};
let content = data.content.clone();
let single_view = data.single_view;
let res =
sqlx::query(r#"INSERT INTO pastes("id", "content", "expires_at") VALUES ($1, $2, $3)"#)
sqlx::query(r#"INSERT INTO pastes("id", "content", "single_view", "expires_at") VALUES ($1, $2, $3, $4)"#)
.bind(id.clone())
.bind(content.clone())
.bind(single_view)
.bind(expires_at)
.execute(&state.pool)
.await;
@ -160,7 +178,11 @@ pub async fn new_paste(
}
HttpResponse::Ok().json(ApiResponse {
success: true,
data: NewPasteResponse { id, content },
data: NewPasteResponse {
id,
content,
single_view,
},
})
}
Err(e) => {