Mostly finished DB interaction

This commit is contained in:
Raphaël Thériault 2020-10-01 11:01:07 -04:00
parent b0fcb68589
commit bd30809797
No known key found for this signature in database
GPG Key ID: D4E92B68275D389F
1 changed files with 89 additions and 10 deletions

View File

@ -1,5 +1,6 @@
use crate::config::{Config, DatabaseConfig};
use anyhow::Result;
use chrono::{DateTime, Utc};
use rand::{distributions::Alphanumeric, Rng};
use serde::{Deserialize, Serialize};
use sled::Db;
@ -18,7 +19,9 @@ pub fn connect(config: &DatabaseConfig) -> Result<&'static Db> {
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Filite {
owner: String,
creation: DateTime<Utc>,
inner: FiliteInner,
views: usize,
}
#[derive(Debug, Clone, Deserialize, Serialize)]
@ -29,19 +32,53 @@ pub enum FiliteInner {
}
#[tracing::instrument(level = "debug", skip(db))]
pub fn filite(id: &str, db: &Db) -> Result<Option<Filite>> {
pub fn filite(id: &str, inc: bool, db: &Db) -> Result<Option<Filite>> {
task::block_in_place(move || {
let bytes = match db.get(id)? {
Some(b) => b,
None => return Ok(None),
};
let filite = bincode::deserialize(&bytes)?;
Ok(Some(filite))
if inc {
filite_inc(id, db)
} else {
filite_noinc(id, db)
}
})
}
#[tracing::instrument(level = "debug", skip(db))]
pub fn create_filite(id: &str, filite: Filite, db: &Db) -> Result<bool> {
fn filite_inc(id: &str, db: &Db) -> Result<Option<Filite>> {
macro_rules! tryy {
($op:expr, $default:expr, $val:ident) => {
match $op {
Ok(r) => r,
Err(e) => {
$val = Err(e.into());
return Some($default.to_owned());
}
}
};
}
let mut filite = Ok(None);
db.fetch_and_update(id, |b| match b {
Some(b) => {
let mut f: Filite = tryy!(bincode::deserialize(b), b, filite);
f.views += 1;
let b = tryy!(bincode::serialize(&f), b, filite);
filite = Ok(Some(f));
Some(b)
}
None => None,
})?;
filite
}
fn filite_noinc(id: &str, db: &Db) -> Result<Option<Filite>> {
let bytes = match db.get(id)? {
Some(b) => b,
None => return Ok(None),
};
let filite = bincode::deserialize(&bytes)?;
Ok(Some(filite))
}
fn insert_filite(id: &str, filite: Filite, db: &Db) -> Result<bool> {
task::block_in_place(move || {
if db.contains_key(id)? {
return Ok(false);
@ -52,6 +89,48 @@ pub fn create_filite(id: &str, filite: Filite, db: &Db) -> Result<bool> {
})
}
#[tracing::instrument(level = "debug", skip(db))]
pub fn insert_file(id: &str, owner: String, data: Vec<u8>, mime: String, db: &Db) -> Result<bool> {
insert_filite(
id,
Filite {
owner,
creation: Utc::now(),
inner: FiliteInner::File { data, mime },
views: 0,
},
db,
)
}
#[tracing::instrument(level = "debug", skip(db))]
pub fn insert_link(id: &str, owner: String, location: String, db: &Db) -> Result<bool> {
insert_filite(
id,
Filite {
owner,
creation: Utc::now(),
inner: FiliteInner::Link { location },
views: 0,
},
db,
)
}
#[tracing::instrument(level = "debug", skip(db))]
pub fn insert_text(id: &str, owner: String, data: String, db: &Db) -> Result<bool> {
insert_filite(
id,
Filite {
owner,
creation: Utc::now(),
inner: FiliteInner::Text { data },
views: 0,
},
db,
)
}
#[tracing::instrument(level = "debug", skip(db))]
pub fn random_id(length: usize, db: &Db) -> Result<String> {
task::block_in_place(move || {
@ -88,7 +167,7 @@ pub fn user(id: &str, db: &Db) -> Result<Option<User>> {
}
#[tracing::instrument(level = "debug", skip(password, db))]
pub fn create_user(
pub fn insert_user(
id: &str,
password: &str,
admin: bool,