mirror of
https://github.com/Dangoware/confetti-box.git
synced 2025-06-22 22:53:02 -05:00
start implementing diesel and SQLite db
This commit is contained in:
parent
5a8a19cb64
commit
21977fe74f
10 changed files with 79 additions and 24 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -8,3 +8,6 @@ settings.toml
|
||||||
test/
|
test/
|
||||||
|
|
||||||
Cargo.lock
|
Cargo.lock
|
||||||
|
|
||||||
|
.env
|
||||||
|
*.db
|
|
@ -9,7 +9,7 @@ members = [
|
||||||
authors = ["G2-Games <ke0bhogsg@gmail.com>", "MrDulfin"]
|
authors = ["G2-Games <ke0bhogsg@gmail.com>", "MrDulfin"]
|
||||||
|
|
||||||
[workspace.lints.rust]
|
[workspace.lints.rust]
|
||||||
unsafe_code = "forbid"
|
# unsafe_code = "forbid"
|
||||||
|
|
||||||
[profile.production]
|
[profile.production]
|
||||||
inherits = "release"
|
inherits = "release"
|
||||||
|
|
|
@ -29,6 +29,10 @@ toml = "0.8"
|
||||||
unidecode = "0.3"
|
unidecode = "0.3"
|
||||||
urlencoding = "2.1"
|
urlencoding = "2.1"
|
||||||
uuid = { version = "1.11", features = ["serde", "v4"] }
|
uuid = { version = "1.11", features = ["serde", "v4"] }
|
||||||
|
diesel = { version = "2.2.0", features = ["sqlite", "returning_clauses_for_sqlite_3_35", "chrono"] }
|
||||||
|
libsqlite3-sys = { version = "0.30", features = ["bundled"] }
|
||||||
|
dotenvy = "0.15"
|
||||||
|
diesel-derive-newtype = "2.1.2"
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -1,33 +1,31 @@
|
||||||
|
mod schema;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{hash_map::Values, HashMap, HashSet},
|
collections::{hash_map::Values, HashMap, HashSet},
|
||||||
ffi::OsStr,
|
ffi::OsStr,
|
||||||
fs::{self, File},
|
fs::{self, File},
|
||||||
io::{self, Write},
|
io::{self, Write},
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{Arc, RwLock},
|
sync::{Arc, Mutex, RwLock},
|
||||||
};
|
};
|
||||||
|
|
||||||
use blake3::Hash;
|
use blake3::Hash;
|
||||||
use chrono::{DateTime, TimeDelta, Utc};
|
use chrono::{DateTime, NaiveDateTime, TimeDelta, Utc};
|
||||||
use ciborium::{from_reader, into_writer};
|
use ciborium::{from_reader, into_writer};
|
||||||
|
use diesel::{prelude::Queryable, Selectable};
|
||||||
use log::{error, info, warn};
|
use log::{error, info, warn};
|
||||||
use rand::distributions::{Alphanumeric, DistString};
|
use rand::distributions::{Alphanumeric, DistString};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
form::{self, FromFormField, ValueField},
|
form::{self, FromFormField, ValueField},
|
||||||
serde::{Deserialize, Serialize},
|
serde::{Deserialize, Serialize},
|
||||||
};
|
};
|
||||||
use serde_with::{serde_as, DisplayFromStr};
|
use serde_with::serde_as;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
|
||||||
pub struct Mochibase {
|
pub struct Mochibase {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
|
/// connection to the db
|
||||||
/// Every hash in the database along with the [`Mmid`]s associated with them
|
db: Arc<Mutex<diesel::sqlite::SqliteConnection>>,
|
||||||
hashes: HashMap<Hash, HashSet<Mmid>>,
|
|
||||||
|
|
||||||
/// All entries in the database
|
|
||||||
entries: HashMap<Mmid, MochiFile>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Mochibase {
|
impl Mochibase {
|
||||||
|
@ -150,8 +148,10 @@ impl Mochibase {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An entry in the database storing metadata about a file
|
/// An entry in the database storing metadata about a file
|
||||||
#[serde_as]
|
#[derive(Queryable, Selectable)]
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
#[diesel(table_name = crate::database::schema::mochifiles)]
|
||||||
|
#[diesel(check_for_backend(diesel::sqlite::Sqlite))]
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct MochiFile {
|
pub struct MochiFile {
|
||||||
/// A unique identifier describing this file
|
/// A unique identifier describing this file
|
||||||
mmid: Mmid,
|
mmid: Mmid,
|
||||||
|
@ -163,25 +163,25 @@ pub struct MochiFile {
|
||||||
mime_type: String,
|
mime_type: String,
|
||||||
|
|
||||||
/// The Blake3 hash of the file
|
/// The Blake3 hash of the file
|
||||||
#[serde_as(as = "DisplayFromStr")]
|
hash: String,
|
||||||
hash: Hash,
|
|
||||||
|
|
||||||
/// The datetime when the file was uploaded
|
/// The datetime when the file was uploaded
|
||||||
upload_datetime: DateTime<Utc>,
|
upload_datetime: chrono::NaiveDateTime,
|
||||||
|
|
||||||
/// The datetime when the file is set to expire
|
/// The datetime when the file is set to expire
|
||||||
expiry_datetime: DateTime<Utc>,
|
expiry_datetime: chrono::NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl MochiFile {
|
impl MochiFile {
|
||||||
/// Create a new file that expires in `expiry`.
|
/// Create a new file that expires in `expiry`.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mmid: Mmid,
|
mmid: Mmid,
|
||||||
name: String,
|
name: String,
|
||||||
mime_type: String,
|
mime_type: String,
|
||||||
hash: Hash,
|
hash: String,
|
||||||
upload: DateTime<Utc>,
|
upload: NaiveDateTime,
|
||||||
expiry: DateTime<Utc>,
|
expiry: NaiveDateTime,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
mmid,
|
mmid,
|
||||||
|
@ -197,16 +197,16 @@ impl MochiFile {
|
||||||
&self.name
|
&self.name
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expiry(&self) -> DateTime<Utc> {
|
pub fn expiry(&self) -> NaiveDateTime {
|
||||||
self.expiry_datetime
|
self.expiry_datetime
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_expired(&self) -> bool {
|
pub fn is_expired(&self) -> bool {
|
||||||
let datetime = Utc::now();
|
let datetime = Utc::now();
|
||||||
datetime > self.expiry_datetime
|
datetime > self.expiry_datetime.and_utc()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hash(&self) -> &Hash {
|
pub fn hash(&self) -> &String {
|
||||||
&self.hash
|
&self.hash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +219,8 @@ impl MochiFile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Clean the database. Removes files which are past their expiry
|
/// Clean the database. Removes files which are past their expiry
|
||||||
/// [`chrono::DateTime`]. Also removes files which no longer exist on the disk.
|
/// [`chrono::DateTime`]. Also removes files which no longer exist on the disk.
|
||||||
pub fn clean_database(db: &Arc<RwLock<Mochibase>>, file_path: &Path) {
|
pub fn clean_database(db: &Arc<RwLock<Mochibase>>, file_path: &Path) {
|
||||||
|
@ -262,7 +264,8 @@ pub fn clean_database(db: &Arc<RwLock<Mochibase>>, file_path: &Path) {
|
||||||
|
|
||||||
/// A unique identifier for an entry in the database, 8 characters long,
|
/// A unique identifier for an entry in the database, 8 characters long,
|
||||||
/// consists of ASCII alphanumeric characters (`a-z`, `A-Z`, and `0-9`).
|
/// consists of ASCII alphanumeric characters (`a-z`, `A-Z`, and `0-9`).
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Deserialize, Serialize)]
|
#[derive(diesel_derive_newtype::DieselNewType)]
|
||||||
|
#[derive(Debug, PartialEq, Eq, Clone, Hash, Serialize, Deserialize)]
|
||||||
pub struct Mmid(String);
|
pub struct Mmid(String);
|
||||||
|
|
||||||
impl Mmid {
|
impl Mmid {
|
12
confetti-box/src/database/schema.rs
Normal file
12
confetti-box/src/database/schema.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// @generated automatically by Diesel CLI.
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
mochifiles (mmid) {
|
||||||
|
mmid -> Text,
|
||||||
|
name -> Text,
|
||||||
|
mime_type -> Text,
|
||||||
|
hash -> Text,
|
||||||
|
upload_datetime -> Timestamp,
|
||||||
|
expiry_datetime -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
9
diesel.toml
Normal file
9
diesel.toml
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# For documentation on how to configure this file,
|
||||||
|
# see https://diesel.rs/guides/configuring-diesel-cli
|
||||||
|
|
||||||
|
[print_schema]
|
||||||
|
file = "confetti-box/src/database/schema.rs"
|
||||||
|
custom_type_derives = ["diesel::query_builder::QueryId", "Clone"]
|
||||||
|
|
||||||
|
[migrations_directory]
|
||||||
|
dir = "migrations/"
|
0
migrations/.keep
Normal file
0
migrations/.keep
Normal file
2
migrations/2025-05-22-234448_create_files/down.sql
Normal file
2
migrations/2025-05-22-234448_create_files/down.sql
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
-- This file should undo anything in `up.sql`
|
||||||
|
DROP TABLE mochifiles
|
10
migrations/2025-05-22-234448_create_files/up.sql
Normal file
10
migrations/2025-05-22-234448_create_files/up.sql
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
-- Your SQL goes here
|
||||||
|
|
||||||
|
CREATE TABLE mochifiles (
|
||||||
|
mmid TEXT PRIMARY KEY NOT NULL,
|
||||||
|
name TEXT NOT NULL,
|
||||||
|
mime_type TEXT NOT NULL,
|
||||||
|
hash TEXT NOT NULL UNIQUE,
|
||||||
|
upload_datetime DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
expiry_datetime DATETIME NOT NULL
|
||||||
|
)
|
12
src/database/schema.rs
Normal file
12
src/database/schema.rs
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// @generated automatically by Diesel CLI.
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
mochifiles (mmid) {
|
||||||
|
mmid -> Nullable<Integer>,
|
||||||
|
name -> Text,
|
||||||
|
mime_type -> Text,
|
||||||
|
hash -> Text,
|
||||||
|
upload_datetime -> Nullable<Timestamp>,
|
||||||
|
expiry_datetime -> Timestamp,
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue