add: move database drivers to oiseau
This commit is contained in:
parent
40fce4bc77
commit
81036e3733
57 changed files with 638 additions and 1106 deletions
16
Cargo.lock
generated
16
Cargo.lock
generated
|
@ -2025,6 +2025,17 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "oiseau"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bb8-postgres",
|
||||
"redis",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"tokio-postgres",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
|
@ -3312,20 +3323,17 @@ dependencies = [
|
|||
"async-recursion",
|
||||
"base16ct",
|
||||
"base64 0.22.1",
|
||||
"bb8-postgres",
|
||||
"bitflags 2.9.1",
|
||||
"emojis",
|
||||
"md-5",
|
||||
"oiseau",
|
||||
"pathbufd",
|
||||
"redis",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tetratto-l10n",
|
||||
"tetratto-shared",
|
||||
"tokio-postgres",
|
||||
"toml",
|
||||
"totp-rs",
|
||||
]
|
||||
|
|
|
@ -120,7 +120,7 @@ macro_rules! get_lang {
|
|||
macro_rules! user_banned {
|
||||
($user:expr, $other_user:ident, $data:ident, $jar:ident) => {
|
||||
let lang = get_lang!($jar, $data.0);
|
||||
let mut context = initial_context(&$data.0.0, lang, &$user).await;
|
||||
let mut context = initial_context(&$data.0.0.0, lang, &$user).await;
|
||||
context.insert("profile", &$other_user);
|
||||
|
||||
return Ok(Html(
|
||||
|
@ -168,7 +168,7 @@ macro_rules! check_user_blocked_or_private {
|
|||
&& !ua.permissions.check(FinePermission::MANAGE_USERS)
|
||||
{
|
||||
let lang = get_lang!($jar, $data.0);
|
||||
let mut context = initial_context(&$data.0.0, lang, &$user).await;
|
||||
let mut context = initial_context(&$data.0.0.0, lang, &$user).await;
|
||||
|
||||
context.insert("profile", &$other_user);
|
||||
context.insert(
|
||||
|
@ -198,7 +198,7 @@ macro_rules! check_user_blocked_or_private {
|
|||
.is_err()
|
||||
{
|
||||
let lang = get_lang!($jar, $data.0);
|
||||
let mut context = initial_context(&$data.0.0, lang, &$user).await;
|
||||
let mut context = initial_context(&$data.0.0.0, lang, &$user).await;
|
||||
|
||||
context.insert("profile", &$other_user);
|
||||
context.insert(
|
||||
|
@ -232,7 +232,7 @@ macro_rules! check_user_blocked_or_private {
|
|||
}
|
||||
} else {
|
||||
let lang = get_lang!($jar, $data.0);
|
||||
let mut context = initial_context(&$data.0.0, lang, &$user).await;
|
||||
let mut context = initial_context(&$data.0.0.0, lang, &$user).await;
|
||||
|
||||
context.insert("profile", &$other_user);
|
||||
context.insert("follow_requested", &false);
|
||||
|
|
|
@ -194,7 +194,8 @@ media_theme_pref();
|
|||
.replaceAll(" months ago", "m")
|
||||
.replaceAll(" month ago", "m")
|
||||
.replaceAll(" years ago", "y")
|
||||
.replaceAll(" year ago", "y") || "";
|
||||
.replaceAll(" year ago", "y")
|
||||
.replaceAll("Yesterday", "1d") || "";
|
||||
|
||||
element.innerText =
|
||||
pretty === undefined ? then.toLocaleDateString() : pretty;
|
||||
|
|
|
@ -92,13 +92,20 @@ pub async fn proxy_request(
|
|||
req.data.insert("format".to_string(), "json".to_string());
|
||||
req.data.insert(
|
||||
"api_key".to_string(),
|
||||
data.0.connections.last_fm_key.as_ref().unwrap().to_string(),
|
||||
data.0
|
||||
.0
|
||||
.connections
|
||||
.last_fm_key
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
);
|
||||
req.data.insert(
|
||||
"api_sig".to_string(),
|
||||
LastFmConnection::signature(
|
||||
req.data.clone(),
|
||||
data.0
|
||||
.0
|
||||
.connections
|
||||
.last_fm_secret
|
||||
.as_ref()
|
||||
|
|
|
@ -17,7 +17,7 @@ pub async fn stripe_webhook(
|
|||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
|
||||
if data.0.stripe.is_none() {
|
||||
if data.0.0.stripe.is_none() {
|
||||
return Json(Error::MiscError("Disabled".to_string()).into());
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,7 @@ pub async fn stripe_webhook(
|
|||
let req = match stripe::Webhook::construct_event(
|
||||
&body,
|
||||
sig.to_str().unwrap(),
|
||||
&data.0.stripe.as_ref().unwrap().webhook_signing_secret,
|
||||
&data.0.0.stripe.as_ref().unwrap().webhook_signing_secret,
|
||||
) {
|
||||
Ok(e) => e,
|
||||
Err(e) => return Json(Error::MiscError(e.to_string()).into()),
|
||||
|
|
|
@ -58,7 +58,7 @@ pub async fn avatar_request(
|
|||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
@ -74,7 +74,7 @@ pub async fn avatar_request(
|
|||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
@ -83,7 +83,7 @@ pub async fn avatar_request(
|
|||
};
|
||||
|
||||
let path = PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"avatars",
|
||||
&format!(
|
||||
"{}.{}",
|
||||
|
@ -96,7 +96,7 @@ pub async fn avatar_request(
|
|||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
@ -126,7 +126,7 @@ pub async fn banner_request(
|
|||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-banner.svg",
|
||||
]))),
|
||||
|
@ -135,7 +135,7 @@ pub async fn banner_request(
|
|||
};
|
||||
|
||||
let path = PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"banners",
|
||||
&format!(
|
||||
"{}.{}",
|
||||
|
@ -148,7 +148,7 @@ pub async fn banner_request(
|
|||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-banner.svg",
|
||||
]))),
|
||||
|
@ -194,7 +194,7 @@ pub async fn upload_avatar_request(
|
|||
// mime changed; delete old image
|
||||
let path = pathd!(
|
||||
"{}/avatars/{}.{}",
|
||||
data.0.dirs.media,
|
||||
data.0.0.dirs.media,
|
||||
&auth_user.id,
|
||||
auth_user.settings.avatar_mime.replace("image/", "")
|
||||
);
|
||||
|
@ -206,7 +206,7 @@ pub async fn upload_avatar_request(
|
|||
|
||||
let path = pathd!(
|
||||
"{}/avatars/{}.{}",
|
||||
data.0.dirs.media,
|
||||
data.0.0.dirs.media,
|
||||
&auth_user.id,
|
||||
mime.replace("image/", "")
|
||||
);
|
||||
|
@ -292,7 +292,7 @@ pub async fn upload_banner_request(
|
|||
// mime changed; delete old image
|
||||
let path = pathd!(
|
||||
"{}/banners/{}.{}",
|
||||
data.0.dirs.media,
|
||||
data.0.0.dirs.media,
|
||||
&auth_user.id,
|
||||
auth_user.settings.banner_mime.replace("image/", "")
|
||||
);
|
||||
|
@ -304,7 +304,7 @@ pub async fn upload_banner_request(
|
|||
|
||||
let path = pathd!(
|
||||
"{}/banners/{}.{}",
|
||||
data.0.dirs.media,
|
||||
data.0.0.dirs.media,
|
||||
&auth_user.id,
|
||||
mime.replace("image/", "")
|
||||
);
|
||||
|
|
|
@ -46,7 +46,7 @@ pub async fn register_request(
|
|||
|
||||
// get real ip
|
||||
let real_ip = headers
|
||||
.get(data.0.security.real_ip_header.to_owned())
|
||||
.get(data.0.0.security.real_ip_header.to_owned())
|
||||
.unwrap_or(&HeaderValue::from_static(""))
|
||||
.to_str()
|
||||
.unwrap_or("")
|
||||
|
@ -62,7 +62,7 @@ pub async fn register_request(
|
|||
}
|
||||
|
||||
// check captcha
|
||||
let client = TurnstileClient::new(data.0.turnstile.secret_key.clone().into());
|
||||
let client = TurnstileClient::new(data.0.0.turnstile.secret_key.clone().into());
|
||||
|
||||
let validated = match client
|
||||
.siteverify(SiteVerifyRequest {
|
||||
|
@ -126,7 +126,7 @@ pub async fn login_request(
|
|||
|
||||
// get real ip
|
||||
let real_ip = headers
|
||||
.get(data.0.security.real_ip_header.to_owned())
|
||||
.get(data.0.0.security.real_ip_header.to_owned())
|
||||
.unwrap_or(&HeaderValue::from_static(""))
|
||||
.to_str()
|
||||
.unwrap_or("")
|
||||
|
|
|
@ -516,7 +516,9 @@ pub async fn subscription_handler(
|
|||
pub async fn handle_socket(socket: WebSocket, db: DataManager, user_id: String, stream_id: String) {
|
||||
let (mut sink, mut stream) = socket.split();
|
||||
let socket_id = tetratto_shared::hash::salt();
|
||||
db.2.incr("atto.active_connections:users".to_string()).await;
|
||||
db.0.1
|
||||
.incr("atto.active_connections:users".to_string())
|
||||
.await;
|
||||
|
||||
// get channel permissions
|
||||
let channel = format!("{user_id}/{stream_id}");
|
||||
|
@ -551,7 +553,7 @@ pub async fn handle_socket(socket: WebSocket, db: DataManager, user_id: String,
|
|||
let heartbeat_c = heartbeat_uri.clone();
|
||||
let mut redis_task = tokio::spawn(async move {
|
||||
// forward messages from redis to the socket
|
||||
let mut pubsub = dbc.2.client.get_async_pubsub().await.unwrap();
|
||||
let mut pubsub = dbc.0.1.client.get_async_pubsub().await.unwrap();
|
||||
|
||||
pubsub.subscribe(channel_c).await.unwrap();
|
||||
pubsub.subscribe(heartbeat_c).await.unwrap();
|
||||
|
@ -581,7 +583,7 @@ pub async fn handle_socket(socket: WebSocket, db: DataManager, user_id: String,
|
|||
}
|
||||
});
|
||||
|
||||
let db2c = db.2.clone();
|
||||
let db2c = db.0.1.clone();
|
||||
let heartbeat_c = heartbeat_uri.clone();
|
||||
let heartbeat_task = tokio::spawn(async move {
|
||||
let mut con = db2c.get_con().await;
|
||||
|
@ -608,7 +610,9 @@ pub async fn handle_socket(socket: WebSocket, db: DataManager, user_id: String,
|
|||
}
|
||||
|
||||
heartbeat_task.abort(); // kill
|
||||
db.2.decr("atto.active_connections:users".to_string()).await;
|
||||
db.0.1
|
||||
.decr("atto.active_connections:users".to_string())
|
||||
.await;
|
||||
tracing::info!("socket terminate");
|
||||
}
|
||||
|
||||
|
@ -628,7 +632,7 @@ pub async fn post_to_socket_request(
|
|||
return Json(Error::NotAllowed.into());
|
||||
}
|
||||
|
||||
let mut con = data.2.get_con().await;
|
||||
let mut con = data.0.1.get_con().await;
|
||||
con.publish::<String, String, ()>(
|
||||
format!("{user_id}/{id}"),
|
||||
serde_json::to_string(&msg).unwrap(),
|
||||
|
|
|
@ -190,7 +190,7 @@ pub async fn handle_socket(socket: WebSocket, db: DataManager, community_id: Str
|
|||
let channel_id_c = channel_id.clone();
|
||||
let mut redis_task = tokio::spawn(async move {
|
||||
// forward messages from redis to the socket
|
||||
let mut pubsub = dbc.2.client.get_async_pubsub().await.unwrap();
|
||||
let mut pubsub = dbc.0.1.client.get_async_pubsub().await.unwrap();
|
||||
|
||||
pubsub.subscribe(user.id).await.unwrap();
|
||||
pubsub.subscribe(channel_id_c).await.unwrap();
|
||||
|
@ -239,7 +239,7 @@ pub async fn handle_socket(socket: WebSocket, db: DataManager, community_id: Str
|
|||
}
|
||||
});
|
||||
|
||||
let db2c = db.2.clone();
|
||||
let db2c = db.0.1.clone();
|
||||
let heartbeat_task = tokio::spawn(async move {
|
||||
let mut con = db2c.get_con().await;
|
||||
let mut heartbeat = tokio::time::interval(Duration::from_secs(10));
|
||||
|
@ -259,7 +259,9 @@ pub async fn handle_socket(socket: WebSocket, db: DataManager, community_id: Str
|
|||
}
|
||||
});
|
||||
|
||||
db.2.incr("atto.active_connections:chats".to_string()).await;
|
||||
db.0.1
|
||||
.incr("atto.active_connections:chats".to_string())
|
||||
.await;
|
||||
|
||||
tokio::select! {
|
||||
_ = (&mut recv_task) => redis_task.abort(),
|
||||
|
@ -267,7 +269,9 @@ pub async fn handle_socket(socket: WebSocket, db: DataManager, community_id: Str
|
|||
}
|
||||
|
||||
heartbeat_task.abort(); // kill
|
||||
db.2.decr("atto.active_connections:chats".to_string()).await;
|
||||
db.0.1
|
||||
.decr("atto.active_connections:chats".to_string())
|
||||
.await;
|
||||
tracing::info!("socket terminate");
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ pub async fn get_request(
|
|||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
@ -47,7 +47,7 @@ pub async fn get_request(
|
|||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
@ -59,13 +59,13 @@ pub async fn get_request(
|
|||
.get_upload_by_id(emoji.0.unwrap().upload_id)
|
||||
.await
|
||||
.unwrap();
|
||||
let path = upload.path(&data.0);
|
||||
let path = upload.path(&data.0.0);
|
||||
|
||||
if !exists(&path).unwrap() {
|
||||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
@ -140,12 +140,12 @@ pub async fn create_request(
|
|||
{
|
||||
Ok(_) => {
|
||||
if is_animated {
|
||||
if let Err(e) = upload.write(&data.0, &img.0) {
|
||||
if let Err(e) = upload.write(&data.0.0, &img.0) {
|
||||
return Json(Error::MiscError(e.to_string()).into());
|
||||
}
|
||||
} else {
|
||||
if let Err(e) =
|
||||
save_webp_buffer(&upload.path(&data.0).to_string(), img.0.to_vec(), None)
|
||||
save_webp_buffer(&upload.path(&data.0.0).to_string(), img.0.to_vec(), None)
|
||||
{
|
||||
return Json(Error::MiscError(e.to_string()).into());
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ pub async fn create_request(
|
|||
})
|
||||
}
|
||||
Err(e) => {
|
||||
if let Err(e) = upload.remove(&data.0) {
|
||||
if let Err(e) = upload.remove(&data.0.0) {
|
||||
return Json(e.into());
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ pub async fn avatar_request(
|
|||
return (
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
@ -34,7 +34,7 @@ pub async fn avatar_request(
|
|||
};
|
||||
|
||||
let path = PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"community_avatars",
|
||||
&format!("{}.avif", &community.id),
|
||||
]);
|
||||
|
@ -43,7 +43,7 @@ pub async fn avatar_request(
|
|||
return (
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
@ -70,7 +70,7 @@ pub async fn banner_request(
|
|||
return (
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-banner.svg",
|
||||
]))),
|
||||
|
@ -79,7 +79,7 @@ pub async fn banner_request(
|
|||
};
|
||||
|
||||
let path = PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"community_banners",
|
||||
&format!("{}.avif", &community.id),
|
||||
]);
|
||||
|
@ -88,7 +88,7 @@ pub async fn banner_request(
|
|||
return (
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-banner.svg",
|
||||
]))),
|
||||
|
@ -130,7 +130,7 @@ pub async fn upload_avatar_request(
|
|||
|
||||
let path = pathd!(
|
||||
"{}/community_avatars/{}.avif",
|
||||
data.0.dirs.media,
|
||||
data.0.0.dirs.media,
|
||||
&community.id
|
||||
);
|
||||
|
||||
|
@ -185,7 +185,7 @@ pub async fn upload_banner_request(
|
|||
|
||||
let path = pathd!(
|
||||
"{}/community_banners/{}.avif",
|
||||
data.0.dirs.media,
|
||||
data.0.0.dirs.media,
|
||||
&community.id
|
||||
);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ pub async fn create_request(
|
|||
|
||||
// get real ip
|
||||
let real_ip = headers
|
||||
.get(data.0.security.real_ip_header.to_owned())
|
||||
.get(data.0.0.security.real_ip_header.to_owned())
|
||||
.unwrap_or(&HeaderValue::from_static(""))
|
||||
.to_str()
|
||||
.unwrap_or("")
|
||||
|
@ -159,7 +159,7 @@ pub async fn create_request(
|
|||
};
|
||||
|
||||
if let Err(e) =
|
||||
save_webp_buffer(&upload.path(&data.0).to_string(), image.to_vec(), None)
|
||||
save_webp_buffer(&upload.path(&data.0.0).to_string(), image.to_vec(), None)
|
||||
{
|
||||
return Json(Error::MiscError(e.to_string()).into());
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ pub async fn create_request(
|
|||
|
||||
// get real ip
|
||||
let real_ip = headers
|
||||
.get(data.0.security.real_ip_header.to_owned())
|
||||
.get(data.0.0.security.real_ip_header.to_owned())
|
||||
.unwrap_or(&HeaderValue::from_static(""))
|
||||
.to_str()
|
||||
.unwrap_or("")
|
||||
|
|
|
@ -13,13 +13,13 @@ pub async fn get_request(
|
|||
let data = &(data.read().await).0;
|
||||
|
||||
let upload = data.get_upload_by_id(id).await.unwrap();
|
||||
let path = upload.path(&data.0);
|
||||
let path = upload.path(&data.0.0);
|
||||
|
||||
if !exists(&path).unwrap() {
|
||||
return Err((
|
||||
[("Content-Type", "image/svg+xml")],
|
||||
Body::from(read_image(PathBufD::current().extend(&[
|
||||
data.0.dirs.media.as_str(),
|
||||
data.0.0.dirs.media.as_str(),
|
||||
"images",
|
||||
"default-avatar.svg",
|
||||
]))),
|
||||
|
|
|
@ -22,7 +22,7 @@ pub async fn proxy_request(
|
|||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await);
|
||||
let http = &data.2;
|
||||
let data = &data.0;
|
||||
let data = &data.0.0;
|
||||
|
||||
let image_url = &props.url;
|
||||
|
||||
|
@ -148,7 +148,7 @@ pub async fn ip_test_request(
|
|||
) -> impl IntoResponse {
|
||||
let data = &(data.read().await).0;
|
||||
headers
|
||||
.get(data.0.security.real_ip_header.to_owned())
|
||||
.get(data.0.0.security.real_ip_header.to_owned())
|
||||
.unwrap_or(&HeaderValue::from_static(""))
|
||||
.to_str()
|
||||
.unwrap_or("")
|
||||
|
|
|
@ -19,7 +19,7 @@ pub async fn login_request(jar: CookieJar, Extension(data): Extension<State>) ->
|
|||
// }
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let context = initial_context(&data.0.0, lang, &user).await;
|
||||
let context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
Html(data.1.render("auth/login.html", &context).unwrap())
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ pub async fn register_request(
|
|||
// }
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let context = initial_context(&data.0.0, lang, &user).await;
|
||||
let context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
Html(data.1.render("auth/register.html", &context).unwrap())
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ pub async fn connection_callback_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("connection_type", &service);
|
||||
Html(data.1.render("auth/connection.html", &context).unwrap())
|
||||
|
|
|
@ -102,7 +102,7 @@ pub async fn app_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user.clone())).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user.clone())).await;
|
||||
|
||||
context.insert("selected_community", &selected_community);
|
||||
context.insert("selected_channel", &selected_channel);
|
||||
|
@ -208,7 +208,7 @@ pub async fn stream_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("messages", &messages);
|
||||
context.insert("message", &message);
|
||||
|
@ -269,7 +269,7 @@ pub async fn message_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("can_manage_messages", &can_manage_messages);
|
||||
context.insert("message", &message);
|
||||
|
@ -338,7 +338,7 @@ pub async fn channels_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("channels", &channels);
|
||||
context.insert("page", &props.page);
|
||||
|
|
|
@ -188,7 +188,7 @@ pub async fn list_request(jar: CookieJar, Extension(data): Extension<State>) ->
|
|||
}
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &communities);
|
||||
context.insert("popular_list", &popular_list);
|
||||
|
@ -225,7 +225,7 @@ pub async fn search_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &communities);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -270,7 +270,7 @@ pub async fn create_post_request(
|
|||
|
||||
let mut communities: Vec<Community> = Vec::new();
|
||||
for membership in memberships {
|
||||
if membership.community == data.0.0.town_square {
|
||||
if membership.community == data.0.0.0.town_square {
|
||||
// we already pulled the town square
|
||||
continue;
|
||||
}
|
||||
|
@ -319,7 +319,7 @@ pub async fn create_post_request(
|
|||
|
||||
// ...
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("draft", &draft);
|
||||
context.insert("drafts", &drafts);
|
||||
|
@ -416,7 +416,7 @@ pub async fn feed_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let (
|
||||
is_owner,
|
||||
|
@ -506,7 +506,7 @@ pub async fn questions_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let (
|
||||
is_owner,
|
||||
|
@ -600,7 +600,7 @@ pub async fn settings_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("community", &community);
|
||||
|
||||
|
@ -745,7 +745,7 @@ pub async fn post_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let (
|
||||
is_owner,
|
||||
|
@ -873,7 +873,7 @@ pub async fn reposts_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let (
|
||||
is_owner,
|
||||
|
@ -1018,7 +1018,7 @@ pub async fn likes_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
let (
|
||||
is_owner,
|
||||
|
@ -1115,7 +1115,7 @@ pub async fn members_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let (
|
||||
is_owner,
|
||||
|
@ -1212,7 +1212,7 @@ pub async fn question_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let (
|
||||
is_owner,
|
||||
|
|
|
@ -53,7 +53,7 @@ pub async fn index_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &None).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &None).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -81,7 +81,7 @@ pub async fn index_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -117,7 +117,7 @@ pub async fn popular_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -159,7 +159,7 @@ pub async fn following_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -197,7 +197,7 @@ pub async fn all_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -233,7 +233,7 @@ pub async fn index_questions_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -273,7 +273,7 @@ pub async fn popular_questions_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -315,7 +315,7 @@ pub async fn following_questions_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -346,7 +346,7 @@ pub async fn all_questions_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -400,7 +400,7 @@ pub async fn notifications_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("page", &props.page);
|
||||
context.insert("profile", &profile);
|
||||
|
@ -490,7 +490,7 @@ pub async fn requests_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("page", &props.page);
|
||||
context.insert("profile", &profile);
|
||||
|
@ -516,7 +516,7 @@ pub async fn markdown_document_request(
|
|||
));
|
||||
}
|
||||
|
||||
let path = PathBufD::current().extend(&[&data.0.0.dirs.docs, &name]);
|
||||
let path = PathBufD::current().extend(&[&data.0.0.0.dirs.docs, &name]);
|
||||
let file = match read_to_string(&path) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
|
@ -527,7 +527,7 @@ pub async fn markdown_document_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
context.insert("file", &file);
|
||||
context.insert("file_name", &name);
|
||||
|
||||
|
@ -616,7 +616,7 @@ pub async fn search_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
context.insert("profile", &profile);
|
||||
|
|
|
@ -123,7 +123,7 @@ pub async fn render_error(
|
|||
user: &Option<User>,
|
||||
) -> String {
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, user).await;
|
||||
context.insert("error_text", &e.to_string());
|
||||
data.1.render("misc/error.html", &context).unwrap()
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ pub async fn audit_log_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
context.insert("items", &items);
|
||||
context.insert("page", &req.page);
|
||||
|
||||
|
@ -76,7 +76,7 @@ pub async fn reports_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
context.insert("items", &items);
|
||||
context.insert("page", &req.page);
|
||||
|
||||
|
@ -107,7 +107,7 @@ pub async fn file_report_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
context.insert("asset", &req.asset);
|
||||
context.insert("asset_type", &req.asset_type);
|
||||
|
||||
|
@ -145,7 +145,7 @@ pub async fn ip_bans_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
context.insert("items", &items);
|
||||
context.insert("page", &req.page);
|
||||
|
||||
|
@ -195,7 +195,7 @@ pub async fn manage_profile_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("profile", &profile);
|
||||
context.insert("associations", &associations);
|
||||
|
@ -242,7 +242,7 @@ pub async fn manage_profile_warnings_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("profile", &profile);
|
||||
context.insert("items", &list);
|
||||
|
@ -271,13 +271,14 @@ pub async fn stats_request(jar: CookieJar, Extension(data): Extension<State>) ->
|
|||
}
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert(
|
||||
"active_users_chats",
|
||||
&data
|
||||
.0
|
||||
.2
|
||||
.0
|
||||
.1
|
||||
.get("atto.active_connections:chats".to_string())
|
||||
.await
|
||||
.unwrap_or("0".to_string())
|
||||
|
@ -288,7 +289,8 @@ pub async fn stats_request(jar: CookieJar, Extension(data): Extension<State>) ->
|
|||
"active_users",
|
||||
&data
|
||||
.0
|
||||
.2
|
||||
.0
|
||||
.1
|
||||
.get("atto.active_connections:users".to_string())
|
||||
.await
|
||||
.unwrap_or("0".to_string())
|
||||
|
|
|
@ -90,7 +90,7 @@ pub async fn settings_request(
|
|||
let tokens = profile.tokens.clone();
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("profile", &profile);
|
||||
context.insert("page", &req.page);
|
||||
|
@ -223,7 +223,7 @@ pub async fn posts_request(
|
|||
// check for warning
|
||||
if props.warning {
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
context.insert("profile", &other_user);
|
||||
context.insert("warning_hash", &hash(other_user.settings.warning.clone()));
|
||||
|
@ -311,7 +311,7 @@ pub async fn posts_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let is_self = if let Some(ref ua) = user {
|
||||
ua.id == other_user.id
|
||||
|
@ -416,7 +416,7 @@ pub async fn replies_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let is_self = if let Some(ref ua) = user {
|
||||
ua.id == other_user.id
|
||||
|
@ -521,7 +521,7 @@ pub async fn media_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let is_self = if let Some(ref ua) = user {
|
||||
ua.id == other_user.id
|
||||
|
@ -628,7 +628,7 @@ pub async fn outbox_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user.clone())).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user.clone())).await;
|
||||
|
||||
let is_self = user.id == other_user.id;
|
||||
|
||||
|
@ -709,7 +709,7 @@ pub async fn following_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let is_self = if let Some(ref ua) = user {
|
||||
ua.id == other_user.id
|
||||
|
@ -803,7 +803,7 @@ pub async fn followers_request(
|
|||
|
||||
// init context
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &user).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &user).await;
|
||||
|
||||
let is_self = if let Some(ref ua) = user {
|
||||
ua.id == other_user.id
|
||||
|
|
|
@ -26,7 +26,7 @@ pub async fn list_request(jar: CookieJar, Extension(data): Extension<State>) ->
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("list", &list);
|
||||
|
||||
|
@ -83,7 +83,7 @@ pub async fn posts_request(
|
|||
};
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("page", &req.page);
|
||||
context.insert("stack", &stack);
|
||||
|
@ -144,7 +144,7 @@ pub async fn manage_request(
|
|||
}
|
||||
|
||||
let lang = get_lang!(jar, data.0);
|
||||
let mut context = initial_context(&data.0.0, lang, &Some(user)).await;
|
||||
let mut context = initial_context(&data.0.0.0, lang, &Some(user)).await;
|
||||
|
||||
context.insert("stack", &stack);
|
||||
context.insert("users", &users);
|
||||
|
|
|
@ -4,9 +4,9 @@ version = "5.0.0"
|
|||
edition = "2024"
|
||||
|
||||
[features]
|
||||
postgres = ["dep:tokio-postgres", "dep:bb8-postgres"]
|
||||
sqlite = ["dep:rusqlite"]
|
||||
redis = ["dep:redis"]
|
||||
postgres = ["oiseau/postgres"]
|
||||
sqlite = ["oiseau/sqlite"]
|
||||
redis = ["oiseau/redis"]
|
||||
default = ["sqlite", "redis"]
|
||||
|
||||
[dependencies]
|
||||
|
@ -22,16 +22,7 @@ bitflags = "2.9.1"
|
|||
async-recursion = "1.1.1"
|
||||
md-5 = "0.10.6"
|
||||
base16ct = { version = "0.2.0", features = ["alloc"] }
|
||||
|
||||
redis = { version = "0.31.0", features = [
|
||||
"aio",
|
||||
"tokio-comp",
|
||||
], optional = true }
|
||||
|
||||
rusqlite = { version = "0.36.0", optional = true }
|
||||
|
||||
tokio-postgres = { version = "0.7.13", optional = true }
|
||||
bb8-postgres = { version = "0.9.0", optional = true }
|
||||
base64 = "0.22.1"
|
||||
emojis = "0.6.4"
|
||||
regex = "1.11.1"
|
||||
oiseau = { version = "0.1.0", path = "../../../oiseau", default-features = false }
|
||||
|
|
77
crates/core/src/cache/mod.rs
vendored
77
crates/core/src/cache/mod.rs
vendored
|
@ -1,77 +0,0 @@
|
|||
#![allow(async_fn_in_trait)]
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
|
||||
pub const EXPIRE_AT: i64 = 3_600_000;
|
||||
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type TimedObject<T: Serialize + DeserializeOwned> = (i64, T);
|
||||
|
||||
#[cfg(feature = "redis")]
|
||||
pub mod redis;
|
||||
|
||||
#[cfg(not(feature = "redis"))]
|
||||
pub mod no_cache;
|
||||
|
||||
/// A simple cache "database".
|
||||
pub trait Cache {
|
||||
type Item;
|
||||
type Client;
|
||||
|
||||
/// Create a new [`Cache`].
|
||||
async fn new() -> Self;
|
||||
/// Get a connection to the cache.
|
||||
async fn get_con(&self) -> Self::Client;
|
||||
|
||||
/// Get a cache object by its identifier
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id
|
||||
async fn get(&self, id: Self::Item) -> Option<String>;
|
||||
/// Set a cache object by its identifier and content
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id
|
||||
/// * `content` - `String` of the object's content
|
||||
async fn set(&self, id: Self::Item, content: Self::Item) -> bool;
|
||||
/// Update a cache object by its identifier and content
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id
|
||||
/// * `content` - `String` of the object's content
|
||||
async fn update(&self, id: Self::Item, content: Self::Item) -> bool;
|
||||
/// Remove a cache object by its identifier
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id
|
||||
async fn remove(&self, id: Self::Item) -> bool;
|
||||
/// Remove a cache object by its identifier('s start)
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id('s start)
|
||||
async fn remove_starting_with(&self, id: Self::Item) -> bool;
|
||||
/// Increment a cache object by its identifier
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id
|
||||
async fn incr(&self, id: Self::Item) -> bool;
|
||||
/// Decrement a cache object by its identifier
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id
|
||||
async fn decr(&self, id: Self::Item) -> bool;
|
||||
|
||||
/// Get a cache object by its identifier
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id
|
||||
async fn get_timed<T: Serialize + DeserializeOwned>(
|
||||
&self,
|
||||
id: Self::Item,
|
||||
) -> Option<TimedObject<T>>;
|
||||
/// Set a cache object by its identifier and content
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `id` - `String` of the object's id
|
||||
/// * `content` - `String` of the object's content
|
||||
async fn set_timed<T: Serialize + DeserializeOwned>(&self, id: Self::Item, content: T) -> bool;
|
||||
}
|
62
crates/core/src/cache/no_cache.rs
vendored
62
crates/core/src/cache/no_cache.rs
vendored
|
@ -1,62 +0,0 @@
|
|||
use serde::{Serialize, de::DeserializeOwned};
|
||||
|
||||
use super::{Cache, EXPIRE_AT, TimedObject};
|
||||
|
||||
pub const EPOCH_YEAR: u32 = 2025;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct NoCache {
|
||||
pub client: Option<u32>,
|
||||
}
|
||||
|
||||
impl Cache for NoCache {
|
||||
type Item = String;
|
||||
type Client = Option<u32>;
|
||||
|
||||
async fn new() -> Self {
|
||||
Self { client: None }
|
||||
}
|
||||
|
||||
async fn get_con(&self) -> Self::Client {
|
||||
None
|
||||
}
|
||||
|
||||
async fn get(&self, id: Self::Item) -> Option<String> {
|
||||
None
|
||||
}
|
||||
|
||||
async fn set(&self, id: Self::Item, content: Self::Item) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
async fn update(&self, id: Self::Item, content: Self::Item) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
async fn remove(&self, id: Self::Item) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
async fn remove_starting_with(&self, id: Self::Item) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
async fn incr(&self, id: Self::Item) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
async fn decr(&self, id: Self::Item) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
async fn get_timed<T: Serialize + DeserializeOwned>(
|
||||
&self,
|
||||
id: Self::Item,
|
||||
) -> Option<TimedObject<T>> {
|
||||
None
|
||||
}
|
||||
|
||||
async fn set_timed<T: Serialize + DeserializeOwned>(&self, id: Self::Item, content: T) -> bool {
|
||||
None
|
||||
}
|
||||
}
|
126
crates/core/src/cache/redis.rs
vendored
126
crates/core/src/cache/redis.rs
vendored
|
@ -1,126 +0,0 @@
|
|||
use redis::Commands;
|
||||
use serde::{Serialize, de::DeserializeOwned};
|
||||
|
||||
use super::{Cache, EXPIRE_AT, TimedObject};
|
||||
|
||||
pub const EPOCH_YEAR: u32 = 2025;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RedisCache {
|
||||
pub client: redis::Client,
|
||||
}
|
||||
|
||||
impl Cache for RedisCache {
|
||||
type Item = String;
|
||||
type Client = redis::Connection;
|
||||
|
||||
async fn new() -> Self {
|
||||
Self {
|
||||
client: redis::Client::open("redis://127.0.0.1:6379")
|
||||
.expect("ERROR_TETRATTO_REDIS_CON"),
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_con(&self) -> Self::Client {
|
||||
self.client
|
||||
.get_connection()
|
||||
.expect("ERROR_TETRATTO_PSQL_CON_ACQUIRE")
|
||||
}
|
||||
|
||||
async fn get(&self, id: Self::Item) -> Option<String> {
|
||||
self.get_con().await.get(id).ok()
|
||||
}
|
||||
|
||||
async fn set(&self, id: Self::Item, content: Self::Item) -> bool {
|
||||
let mut c = self.get_con().await;
|
||||
let res: Result<String, redis::RedisError> = c.set_ex(id, content, 604800);
|
||||
|
||||
res.is_ok()
|
||||
}
|
||||
|
||||
async fn update(&self, id: Self::Item, content: Self::Item) -> bool {
|
||||
self.set(id, content).await
|
||||
}
|
||||
|
||||
async fn remove(&self, id: Self::Item) -> bool {
|
||||
let mut c = self.get_con().await;
|
||||
let res: Result<String, redis::RedisError> = c.del(id);
|
||||
|
||||
res.is_ok()
|
||||
}
|
||||
|
||||
async fn remove_starting_with(&self, id: Self::Item) -> bool {
|
||||
let mut c = self.get_con().await;
|
||||
|
||||
// get keys
|
||||
let mut cmd = redis::cmd("DEL");
|
||||
let keys: Result<Vec<String>, redis::RedisError> = c.keys(id);
|
||||
|
||||
for key in keys.unwrap() {
|
||||
cmd.arg(key);
|
||||
}
|
||||
|
||||
// remove
|
||||
let res: Result<String, redis::RedisError> = cmd.query(&mut c);
|
||||
|
||||
res.is_ok()
|
||||
}
|
||||
|
||||
async fn incr(&self, id: Self::Item) -> bool {
|
||||
let mut c = self.get_con().await;
|
||||
let res: Result<String, redis::RedisError> = c.incr(id, 1);
|
||||
|
||||
res.is_ok()
|
||||
}
|
||||
|
||||
async fn decr(&self, id: Self::Item) -> bool {
|
||||
let mut c = self.get_con().await;
|
||||
let res: Result<String, redis::RedisError> = c.decr(id, 1);
|
||||
|
||||
res.is_ok()
|
||||
}
|
||||
|
||||
async fn get_timed<T: Serialize + DeserializeOwned>(
|
||||
&self,
|
||||
id: Self::Item,
|
||||
) -> Option<TimedObject<T>> {
|
||||
let mut c = self.get_con().await;
|
||||
let res: Result<String, redis::RedisError> = c.get(&id);
|
||||
|
||||
match res {
|
||||
Ok(d) => match serde_json::from_str::<TimedObject<T>>(&d) {
|
||||
Ok(d) => {
|
||||
// check time
|
||||
let now = tetratto_shared::epoch_timestamp(EPOCH_YEAR);
|
||||
|
||||
if now - d.0 >= EXPIRE_AT {
|
||||
// expired key, remove and return None
|
||||
self.remove(id).await;
|
||||
return None;
|
||||
}
|
||||
|
||||
// return
|
||||
Some(d)
|
||||
}
|
||||
Err(_) => None,
|
||||
},
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
async fn set_timed<T: Serialize + DeserializeOwned>(&self, id: Self::Item, content: T) -> bool {
|
||||
let mut c = self.get_con().await;
|
||||
let res: Result<String, redis::RedisError> = c.set(
|
||||
id,
|
||||
match serde_json::to_string::<TimedObject<T>>(&(
|
||||
tetratto_shared::epoch_timestamp(EPOCH_YEAR),
|
||||
content,
|
||||
)) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return false,
|
||||
},
|
||||
);
|
||||
|
||||
res.is_ok()
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
use oiseau::config::{Configuration, DatabaseConfig};
|
||||
use pathbufd::PathBufD;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
|
@ -83,29 +84,9 @@ impl Default for DirsConfig {
|
|||
}
|
||||
}
|
||||
|
||||
/// Database configuration.
|
||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct DatabaseConfig {
|
||||
pub name: String,
|
||||
#[cfg(feature = "postgres")]
|
||||
pub url: String,
|
||||
#[cfg(feature = "postgres")]
|
||||
pub user: String,
|
||||
#[cfg(feature = "postgres")]
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
impl Default for DatabaseConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
name: "atto.db".to_string(),
|
||||
#[cfg(feature = "postgres")]
|
||||
url: "localhost:5432".to_string(),
|
||||
#[cfg(feature = "postgres")]
|
||||
user: "postgres".to_string(),
|
||||
#[cfg(feature = "postgres")]
|
||||
password: "postgres".to_string(),
|
||||
}
|
||||
impl Configuration for Config {
|
||||
fn db_config(&self) -> DatabaseConfig {
|
||||
self.database.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::{Error, Result, auth::User, moderation::AuditLogEntry, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, params, query_row, query_rows};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get an [`AuditLogEntry`] from an SQL row.
|
||||
pub(crate) fn get_audit_log_entry_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> AuditLogEntry {
|
||||
AuditLogEntry {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -35,7 +36,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<AuditLogEntry>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -59,7 +60,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `data` - a mock [`AuditLogEntry`] object to insert
|
||||
pub async fn create_audit_log_entry(&self, data: AuditLogEntry) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -88,7 +89,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -103,7 +104,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.audit_log:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.audit_log:{}", id)).await;
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use super::common::NAME_REGEX;
|
||||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::auth::UserConnections;
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::oauth::AuthGrant;
|
||||
|
@ -9,23 +8,26 @@ use crate::model::{
|
|||
auth::{Token, User, UserSettings},
|
||||
permissions::FinePermission,
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, params};
|
||||
use pathbufd::PathBufD;
|
||||
use std::fs::{exists, remove_file};
|
||||
use tetratto_shared::hash::{hash_salted, salt};
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
#[cfg(feature = "postgres")]
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
|
||||
use oiseau::{execute, get, query_row, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`User`] from an SQL row.
|
||||
pub(crate) fn get_user_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> User {
|
||||
User {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -61,7 +63,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `id` - the ID of the user
|
||||
pub async fn get_user_by_id_with_void(&self, id: usize) -> Result<User> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -86,7 +88,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `token` - the token of the user
|
||||
pub async fn get_user_by_token(&self, token: &str) -> Result<User> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -112,7 +114,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `token` - the token of the user
|
||||
pub async fn get_user_by_grant_token(&self, token: &str) -> Result<(AuthGrant, User)> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -144,7 +146,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `data` - a mock [`User`] object to insert
|
||||
pub async fn create_user(&self, mut data: User) -> Result<()> {
|
||||
if !self.0.security.registration_enabled {
|
||||
if !self.0.0.security.registration_enabled {
|
||||
return Err(Error::RegistrationDisabled);
|
||||
}
|
||||
|
||||
|
@ -161,7 +163,7 @@ impl DataManager {
|
|||
return Err(Error::DataTooShort("password".to_string()));
|
||||
}
|
||||
|
||||
if self.0.banned_usernames.contains(&data.username) {
|
||||
if self.0.0.banned_usernames.contains(&data.username) {
|
||||
return Err(Error::MiscError("This username cannot be used".to_string()));
|
||||
}
|
||||
|
||||
|
@ -182,7 +184,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -235,7 +237,7 @@ impl DataManager {
|
|||
return Err(Error::IncorrectPassword);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -389,7 +391,7 @@ impl DataManager {
|
|||
|
||||
// remove images
|
||||
let avatar = PathBufD::current().extend(&[
|
||||
self.0.dirs.media.as_str(),
|
||||
self.0.0.dirs.media.as_str(),
|
||||
"avatars",
|
||||
&format!(
|
||||
"{}.{}",
|
||||
|
@ -399,7 +401,7 @@ impl DataManager {
|
|||
]);
|
||||
|
||||
let banner = PathBufD::current().extend(&[
|
||||
self.0.dirs.media.as_str(),
|
||||
self.0.0.dirs.media.as_str(),
|
||||
"banners",
|
||||
&format!(
|
||||
"{}.{}",
|
||||
|
@ -437,7 +439,7 @@ impl DataManager {
|
|||
|
||||
let other_user = self.get_user_by_id(id).await?;
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -482,7 +484,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -511,7 +513,7 @@ impl DataManager {
|
|||
return Err(Error::DataTooLong("username".to_string()));
|
||||
}
|
||||
|
||||
if self.0.banned_usernames.contains(&to) {
|
||||
if self.0.0.banned_usernames.contains(&to) {
|
||||
return Err(Error::MiscError("This username cannot be used".to_string()));
|
||||
}
|
||||
|
||||
|
@ -527,7 +529,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -575,7 +577,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -608,7 +610,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
pub async fn seen_user(&self, user: &User) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -632,6 +634,7 @@ impl DataManager {
|
|||
pub fn check_totp(&self, ua: &User, code: &str) -> bool {
|
||||
let totp = ua.totp(Some(
|
||||
self.0
|
||||
.0
|
||||
.host
|
||||
.replace("http://", "")
|
||||
.replace("https://", "")
|
||||
|
@ -673,7 +676,7 @@ impl DataManager {
|
|||
let user = self.get_user_by_id(id).await?;
|
||||
|
||||
// update
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -734,6 +737,7 @@ impl DataManager {
|
|||
// get totp
|
||||
let totp = other_user.totp(Some(
|
||||
self.0
|
||||
.0
|
||||
.host
|
||||
.replace("http://", "")
|
||||
.replace("https://", "")
|
||||
|
@ -757,8 +761,11 @@ impl DataManager {
|
|||
}
|
||||
|
||||
pub async fn cache_clear_user(&self, user: &User) {
|
||||
self.2.remove(format!("atto.user:{}", user.id)).await;
|
||||
self.2.remove(format!("atto.user:{}", user.username)).await;
|
||||
self.0.1.remove(format!("atto.user:{}", user.id)).await;
|
||||
self.0
|
||||
.1
|
||||
.remove(format!("atto.user:{}", user.username))
|
||||
.await;
|
||||
}
|
||||
|
||||
auto_method!(update_user_tokens(Vec<Token>)@get_user_by_id -> "UPDATE users SET tokens = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_user);
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::{
|
||||
Error, Result, auth::User, permissions::FinePermission,
|
||||
communities_permissions::CommunityPermission, channels::Channel,
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`Channel`] from an SQL row.
|
||||
pub(crate) fn get_channel_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Channel {
|
||||
Channel {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -58,7 +59,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `community` - the ID of the community to fetch channels for
|
||||
pub async fn get_channels_by_community(&self, community: usize) -> Result<Vec<Channel>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -82,7 +83,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `user` - the ID of the user to fetch channels for
|
||||
pub async fn get_channels_by_user(&self, user: usize) -> Result<Vec<Channel>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -111,7 +112,7 @@ impl DataManager {
|
|||
owner: usize,
|
||||
member: usize,
|
||||
) -> Result<Channel> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -163,7 +164,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -206,7 +207,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -229,7 +230,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
self.2.remove(format!("atto.channel:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.channel:{}", id)).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -262,7 +263,7 @@ impl DataManager {
|
|||
// ...
|
||||
y.members.push(member.id);
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -277,7 +278,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.channel:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.channel:{}", id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -303,7 +304,7 @@ impl DataManager {
|
|||
None => return Err(Error::GeneralNotFound("member".to_string())),
|
||||
});
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -318,7 +319,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.channel:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.channel:{}", id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,16 +1,12 @@
|
|||
use crate::{
|
||||
database::drivers::common,
|
||||
execute,
|
||||
model::{Error, Result},
|
||||
cache::Cache,
|
||||
};
|
||||
use super::DataManager;
|
||||
use crate::model::{Error, Result};
|
||||
use super::{DataManager, drivers::common};
|
||||
use oiseau::{cache::Cache, execute};
|
||||
|
||||
pub const NAME_REGEX: &str = r"[^\w_\-\.,!]+";
|
||||
|
||||
impl DataManager {
|
||||
pub async fn init(&self) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -39,10 +35,12 @@ impl DataManager {
|
|||
execute!(&conn, common::CREATE_TABLE_POLLS).unwrap();
|
||||
execute!(&conn, common::CREATE_TABLE_POLLVOTES).unwrap();
|
||||
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set("atto.active_connections:users".to_string(), "0".to_string())
|
||||
.await;
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set("atto.active_connections:chats".to_string(), "0".to_string())
|
||||
.await;
|
||||
|
||||
|
@ -54,7 +52,7 @@ impl DataManager {
|
|||
macro_rules! auto_method {
|
||||
($name:ident()@$select_fn:ident -> $query:literal --name=$name_:literal --returns=$returns_:tt) => {
|
||||
pub async fn $name(&self, id: usize) -> Result<$returns_> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -73,18 +71,18 @@ macro_rules! auto_method {
|
|||
|
||||
($name:ident()@$select_fn:ident -> $query:literal --name=$name_:literal --returns=$returns_:tt --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||
pub async fn $name(&self, id: usize) -> Result<$returns_> {
|
||||
if let Some(cached) = self.2.get(format!($cache_key_tmpl, id)).await {
|
||||
if let Some(cached) = self.0.1.get(format!($cache_key_tmpl, id)).await {
|
||||
if let Ok(c) = serde_json::from_str(&cached) {
|
||||
return Ok(c);
|
||||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
||||
let res = query_row!(&conn, $query, &[&(id as i64)], |x| {
|
||||
let res = oiseau::query_row!(&conn, $query, &[&(id as i64)], |x| {
|
||||
Ok(Self::$select_fn(x))
|
||||
});
|
||||
|
||||
|
@ -93,7 +91,8 @@ macro_rules! auto_method {
|
|||
}
|
||||
|
||||
let x = res.unwrap();
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set(
|
||||
format!($cache_key_tmpl, id),
|
||||
serde_json::to_string(&x).unwrap(),
|
||||
|
@ -106,7 +105,7 @@ macro_rules! auto_method {
|
|||
|
||||
($name:ident($selector_t:ty)@$select_fn:ident -> $query:literal --name=$name_:literal --returns=$returns_:tt) => {
|
||||
pub async fn $name(&self, selector: $selector_t) -> Result<$returns_> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -125,11 +124,11 @@ macro_rules! auto_method {
|
|||
pub async fn $name(&self, selector: $selector_t) -> Result<$returns_> {
|
||||
let selector = selector.to_string().to_lowercase();
|
||||
|
||||
if let Some(cached) = self.2.get(format!($cache_key_tmpl, selector)).await {
|
||||
if let Some(cached) = self.0.1.get(format!($cache_key_tmpl, selector)).await {
|
||||
return Ok(serde_json::from_str(&cached).unwrap());
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -143,7 +142,8 @@ macro_rules! auto_method {
|
|||
}
|
||||
|
||||
let x = res.unwrap();
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set(
|
||||
format!($cache_key_tmpl, selector),
|
||||
serde_json::to_string(&x).unwrap(),
|
||||
|
@ -157,19 +157,20 @@ macro_rules! auto_method {
|
|||
($name:ident($selector_t:ty as i64)@$select_fn:ident -> $query:literal --name=$name_:literal --returns=$returns_:tt --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||
pub async fn $name(&self, selector: $selector_t) -> Result<$returns_> {
|
||||
if let Some(cached) = self
|
||||
.2
|
||||
.0
|
||||
.1
|
||||
.get(format!($cache_key_tmpl, selector.to_string()))
|
||||
.await
|
||||
{
|
||||
return Ok(serde_json::from_str(&cached).unwrap());
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
||||
let res = query_row!(&conn, $query, &[&(selector as i64)], |x| {
|
||||
let res = oiseau::query_row!(&conn, $query, &[&(selector as i64)], |x| {
|
||||
Ok(Self::$select_fn(x))
|
||||
});
|
||||
|
||||
|
@ -178,7 +179,8 @@ macro_rules! auto_method {
|
|||
}
|
||||
|
||||
let x = res.unwrap();
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set(
|
||||
format!($cache_key_tmpl, selector),
|
||||
serde_json::to_string(&x).unwrap(),
|
||||
|
@ -204,7 +206,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -234,7 +236,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -245,7 +247,7 @@ macro_rules! auto_method {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!($cache_key_tmpl, id)).await;
|
||||
self.0.1.remove(format!($cache_key_tmpl, id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -267,7 +269,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -298,7 +300,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -309,7 +311,7 @@ macro_rules! auto_method {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!($cache_key_tmpl, id)).await;
|
||||
self.0.1.remove(format!($cache_key_tmpl, id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -331,7 +333,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -366,7 +368,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -381,7 +383,7 @@ macro_rules! auto_method {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!($cache_key_tmpl, id)).await;
|
||||
self.0.1.remove(format!($cache_key_tmpl, id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -389,7 +391,7 @@ macro_rules! auto_method {
|
|||
|
||||
($name:ident($x:ty) -> $query:literal) => {
|
||||
pub async fn $name(&self, id: usize, x: $x) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -406,7 +408,7 @@ macro_rules! auto_method {
|
|||
|
||||
($name:ident($x:ty) -> $query:literal --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||
pub async fn $name(&self, id: usize, x: $x) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -417,7 +419,7 @@ macro_rules! auto_method {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!($cache_key_tmpl, id)).await;
|
||||
self.0.1.remove(format!($cache_key_tmpl, id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -425,7 +427,7 @@ macro_rules! auto_method {
|
|||
|
||||
($name:ident($x:ty) -> $query:literal --serde) => {
|
||||
pub async fn $name(&self, id: usize, x: $x) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -446,7 +448,7 @@ macro_rules! auto_method {
|
|||
|
||||
($name:ident($x:ty) -> $query:literal --serde --cache-key-tmpl=$cache_key_tmpl:literal) => {
|
||||
pub async fn $name(&self, id: usize, x: $x) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -461,7 +463,7 @@ macro_rules! auto_method {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!($cache_key_tmpl, id)).await;
|
||||
self.0.1.remove(format!($cache_key_tmpl, id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -469,7 +471,7 @@ macro_rules! auto_method {
|
|||
|
||||
($name:ident() -> $query:literal --cache-key-tmpl=$cache_key_tmpl:literal --incr) => {
|
||||
pub async fn $name(&self, id: usize) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -480,7 +482,7 @@ macro_rules! auto_method {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!($cache_key_tmpl, id)).await;
|
||||
self.0.1.remove(format!($cache_key_tmpl, id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -488,7 +490,7 @@ macro_rules! auto_method {
|
|||
|
||||
($name:ident() -> $query:literal --cache-key-tmpl=$cache_key_tmpl:literal --decr) => {
|
||||
pub async fn $name(&self, id: usize) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -499,7 +501,7 @@ macro_rules! auto_method {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!($cache_key_tmpl, id)).await;
|
||||
self.0.1.remove(format!($cache_key_tmpl, id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -521,7 +523,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -554,7 +556,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -575,7 +577,7 @@ macro_rules! auto_method {
|
|||
pub async fn $name(&self, id: usize, x: $x) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -596,7 +598,7 @@ macro_rules! auto_method {
|
|||
pub async fn $name(&self, id: usize, x: $x) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -633,7 +635,7 @@ macro_rules! auto_method {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -658,7 +660,7 @@ macro_rules! auto_method {
|
|||
pub async fn $name(&self, id: usize) -> Result<()> {
|
||||
let y = self.$select_fn(id).await?;
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -683,7 +685,7 @@ macro_rules! auto_method {
|
|||
return Ok(());
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use super::common::NAME_REGEX;
|
||||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::communities::{CommunityContext, CommunityJoinAccess, CommunityMembership};
|
||||
use crate::model::communities_permissions::CommunityPermission;
|
||||
use crate::model::{
|
||||
|
@ -10,21 +10,23 @@ use crate::model::{
|
|||
communities::{CommunityReadAccess, CommunityWriteAccess},
|
||||
permissions::FinePermission,
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use pathbufd::PathBufD;
|
||||
use std::fs::{exists, remove_file};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`Community`] from an SQL row.
|
||||
pub(crate) fn get_community_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Community {
|
||||
Community {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -48,11 +50,11 @@ impl DataManager {
|
|||
return Ok(Community::void());
|
||||
}
|
||||
|
||||
if let Some(cached) = self.2.get(format!("atto.community:{}", id)).await {
|
||||
if let Some(cached) = self.0.1.get(format!("atto.community:{}", id)).await {
|
||||
return Ok(serde_json::from_str(&cached).unwrap());
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -70,7 +72,8 @@ impl DataManager {
|
|||
}
|
||||
|
||||
let x = res.unwrap();
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set(
|
||||
format!("atto.community:{}", id),
|
||||
serde_json::to_string(&x).unwrap(),
|
||||
|
@ -85,11 +88,11 @@ impl DataManager {
|
|||
return Ok(Community::void());
|
||||
}
|
||||
|
||||
if let Some(cached) = self.2.get(format!("atto.community:{}", id)).await {
|
||||
if let Some(cached) = self.0.1.get(format!("atto.community:{}", id)).await {
|
||||
return Ok(serde_json::from_str(&cached).unwrap());
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -107,7 +110,8 @@ impl DataManager {
|
|||
}
|
||||
|
||||
let x = res.unwrap();
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set(
|
||||
format!("atto.community:{}", id),
|
||||
serde_json::to_string(&x).unwrap(),
|
||||
|
@ -122,7 +126,7 @@ impl DataManager {
|
|||
|
||||
/// Get the top 12 most popular (most likes) communities.
|
||||
pub async fn get_popular_communities(&self) -> Result<Vec<Community>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -154,7 +158,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Community>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -179,7 +183,7 @@ impl DataManager {
|
|||
|
||||
/// Get all communities by their owner.
|
||||
pub async fn get_communities_by_owner(&self, id: usize) -> Result<Vec<Community>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -210,7 +214,7 @@ impl DataManager {
|
|||
return Err(Error::DataTooLong("title".to_string()));
|
||||
}
|
||||
|
||||
if self.0.banned_usernames.contains(&data.title) {
|
||||
if self.0.0.banned_usernames.contains(&data.title) {
|
||||
return Err(Error::MiscError("This title cannot be used".to_string()));
|
||||
}
|
||||
|
||||
|
@ -265,7 +269,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -306,10 +310,12 @@ impl DataManager {
|
|||
}
|
||||
|
||||
pub async fn cache_clear_community(&self, community: &Community) {
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.remove(format!("atto.community:{}", community.id))
|
||||
.await;
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.remove(format!("atto.community:{}", community.title))
|
||||
.await;
|
||||
}
|
||||
|
@ -329,7 +335,7 @@ impl DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -364,13 +370,13 @@ impl DataManager {
|
|||
|
||||
// remove images
|
||||
let avatar = PathBufD::current().extend(&[
|
||||
self.0.dirs.media.as_str(),
|
||||
self.0.0.dirs.media.as_str(),
|
||||
"community_avatars",
|
||||
&format!("{}.avif", &y.id),
|
||||
]);
|
||||
|
||||
let banner = PathBufD::current().extend(&[
|
||||
self.0.dirs.media.as_str(),
|
||||
self.0.0.dirs.media.as_str(),
|
||||
"community_banners",
|
||||
&format!("{}.avif", &y.id),
|
||||
]);
|
||||
|
@ -395,7 +401,7 @@ impl DataManager {
|
|||
return Err(Error::DataTooLong("title".to_string()));
|
||||
}
|
||||
|
||||
if self.0.banned_usernames.contains(&title.to_string()) {
|
||||
if self.0.0.banned_usernames.contains(&title.to_string()) {
|
||||
return Err(Error::MiscError("This title cannot be used".to_string()));
|
||||
}
|
||||
|
||||
|
@ -432,7 +438,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -480,7 +486,7 @@ impl DataManager {
|
|||
.await?;
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::{Error, Result, auth::User, communities::PostDraft, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`PostDraft`] from an SQL row.
|
||||
pub(crate) fn get_draft_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> PostDraft {
|
||||
PostDraft {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -38,7 +39,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<PostDraft>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -63,7 +64,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `id` - the ID of the user the requested drafts belong to
|
||||
pub async fn get_drafts_by_user_all(&self, id: usize) -> Result<Vec<PostDraft>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -111,7 +112,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -148,7 +149,7 @@ impl DataManager {
|
|||
.await?
|
||||
}
|
||||
}
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -159,7 +160,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.draft:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.draft:{}", id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -180,7 +181,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
pub mod common;
|
||||
|
||||
use std::collections::HashMap;
|
||||
use tetratto_l10n::{read_langs, LangFile};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
pub mod sqlite;
|
||||
use oiseau::sqlite::{DataManager as OiseauManager, Result};
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
pub mod postgres;
|
||||
use oiseau::postgres::{DataManager as OiseauManager, Result};
|
||||
|
||||
use crate::config::Config;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DataManager(pub OiseauManager<Config>, pub HashMap<String, LangFile>);
|
||||
|
||||
impl DataManager {
|
||||
/// Create a new [`DataManager`].
|
||||
pub async fn new(config: Config) -> Result<Self> {
|
||||
Ok(Self(OiseauManager::new(config).await?, read_langs()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,157 +0,0 @@
|
|||
#[cfg(not(feature = "redis"))]
|
||||
use crate::cache::no_cache::NoCache;
|
||||
#[cfg(feature = "redis")]
|
||||
use crate::cache::redis::RedisCache;
|
||||
|
||||
use crate::cache::Cache;
|
||||
|
||||
use crate::config::Config;
|
||||
use bb8_postgres::{
|
||||
PostgresConnectionManager,
|
||||
bb8::{Pool, PooledConnection},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use tetratto_l10n::{LangFile, read_langs};
|
||||
use tokio_postgres::{Config as PgConfig, NoTls, Row, types::ToSql};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, tokio_postgres::Error>;
|
||||
pub type Connection<'a> = PooledConnection<'a, PostgresConnectionManager<NoTls>>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DataManager(
|
||||
pub Config,
|
||||
pub HashMap<String, LangFile>,
|
||||
#[cfg(feature = "redis")] pub RedisCache,
|
||||
#[cfg(not(feature = "redis"))] pub NoCache,
|
||||
pub Pool<PostgresConnectionManager<NoTls>>,
|
||||
);
|
||||
|
||||
impl DataManager {
|
||||
/// Obtain a connection to the staging database.
|
||||
pub(crate) async fn connect(&self) -> Result<Connection> {
|
||||
Ok(self.3.get().await.expect("ERROR_TETRATTO_PSQL_CON"))
|
||||
}
|
||||
|
||||
/// Create a new [`DataManager`] (and init database).
|
||||
pub async fn new(config: Config) -> Result<Self> {
|
||||
let con_url = &format!(
|
||||
"postgresql://{}:{}@{}/{}?target_session_attrs=read-write",
|
||||
config.database.user,
|
||||
config.database.password,
|
||||
config.database.url,
|
||||
config.database.name
|
||||
);
|
||||
|
||||
println!("attempting connection on: {con_url}");
|
||||
let manager = PostgresConnectionManager::new(PgConfig::from_str(con_url).unwrap(), NoTls);
|
||||
|
||||
let pool = Pool::builder().max_size(15).build(manager).await.unwrap();
|
||||
Ok(Self(
|
||||
config.clone(),
|
||||
read_langs(),
|
||||
#[cfg(feature = "redis")]
|
||||
RedisCache::new().await,
|
||||
#[cfg(not(feature = "redis"))]
|
||||
NoCache::new().await,
|
||||
pool,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
#[macro_export]
|
||||
macro_rules! get {
|
||||
($row:ident->$idx:literal($t:ty)) => {
|
||||
$row.get::<usize, Option<$t>>($idx).unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
pub async fn query_row_helper<T, F>(
|
||||
conn: &Connection<'_>,
|
||||
sql: &str,
|
||||
params: &[&(dyn ToSql + Sync)],
|
||||
f: F,
|
||||
) -> Result<T>
|
||||
where
|
||||
F: FnOnce(&Row) -> Result<T>,
|
||||
{
|
||||
let query = conn.prepare(sql).await.unwrap();
|
||||
let res = conn.query_one(&query, params).await;
|
||||
|
||||
if let Ok(row) = res {
|
||||
Ok(f(&row).unwrap())
|
||||
} else {
|
||||
Err(res.unwrap_err())
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! query_row {
|
||||
($conn:expr, $sql:expr, $params:expr, $f:expr) => {
|
||||
crate::database::query_row_helper($conn, $sql, $params, $f).await
|
||||
};
|
||||
}
|
||||
|
||||
pub async fn query_rows_helper<T, F>(
|
||||
conn: &Connection<'_>,
|
||||
sql: &str,
|
||||
params: &[&(dyn ToSql + Sync)],
|
||||
mut f: F,
|
||||
) -> Result<Vec<T>>
|
||||
where
|
||||
F: FnMut(&Row) -> T,
|
||||
{
|
||||
let query = conn.prepare(sql).await.unwrap();
|
||||
let res = conn.query(&query, params).await;
|
||||
|
||||
if let Ok(rows) = res {
|
||||
let mut out = Vec::new();
|
||||
|
||||
for row in rows {
|
||||
out.push(f(&row));
|
||||
}
|
||||
|
||||
return Ok(out);
|
||||
} else {
|
||||
Err(res.unwrap_err())
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! query_rows {
|
||||
($conn:expr, $sql:expr, $params:expr, $f:expr) => {
|
||||
crate::database::query_rows_helper($conn, $sql, $params, $f).await
|
||||
};
|
||||
}
|
||||
|
||||
pub async fn execute_helper(
|
||||
conn: &Connection<'_>,
|
||||
sql: &str,
|
||||
params: &[&(dyn ToSql + Sync)],
|
||||
) -> Result<()> {
|
||||
let query = conn.prepare(sql).await.unwrap();
|
||||
conn.execute(&query, params).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! execute {
|
||||
($conn:expr, $sql:expr, $params:expr) => {
|
||||
crate::database::execute_helper($conn, $sql, $params).await
|
||||
};
|
||||
|
||||
($conn:expr, $sql:expr) => {
|
||||
crate::database::execute_helper($conn, $sql, &[]).await
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! params {
|
||||
() => {
|
||||
&[]
|
||||
};
|
||||
($($x:expr),+ $(,)?) => {
|
||||
&[$(&$x),+]
|
||||
};
|
||||
}
|
|
@ -1,98 +0,0 @@
|
|||
#[cfg(not(feature = "redis"))]
|
||||
use crate::cache::no_cache::NoCache;
|
||||
#[cfg(feature = "redis")]
|
||||
use crate::cache::redis::RedisCache;
|
||||
|
||||
use crate::cache::Cache;
|
||||
|
||||
use crate::config::Config;
|
||||
use rusqlite::{Connection, Result};
|
||||
use std::collections::HashMap;
|
||||
use tetratto_l10n::{LangFile, read_langs};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct DataManager(
|
||||
pub Config,
|
||||
pub HashMap<String, LangFile>,
|
||||
#[cfg(feature = "redis")] pub RedisCache,
|
||||
#[cfg(not(feature = "redis"))] pub NoCache,
|
||||
);
|
||||
|
||||
impl DataManager {
|
||||
/// Obtain a connection to the staging database.
|
||||
pub(crate) async fn connect(&self) -> Result<Connection> {
|
||||
Connection::open(&self.0.database.name)
|
||||
}
|
||||
|
||||
/// Create a new [`DataManager`] (and init database).
|
||||
pub async fn new(config: Config) -> Result<Self> {
|
||||
let this = Self(
|
||||
config.clone(),
|
||||
read_langs(),
|
||||
#[cfg(feature = "redis")]
|
||||
RedisCache::new().await,
|
||||
#[cfg(not(feature = "redis"))]
|
||||
NoCache::new().await,
|
||||
);
|
||||
|
||||
let conn = this.connect().await?;
|
||||
conn.pragma_update(None, "journal_mode", "WAL").unwrap();
|
||||
|
||||
Ok(this)
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! get {
|
||||
($row:ident->$idx:literal($t:ty)) => {
|
||||
$row.get::<usize, $t>($idx).unwrap()
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! query_row {
|
||||
($conn:expr, $sql:expr, $params:expr, $f:expr) => {{
|
||||
let mut query = $conn.prepare($sql).unwrap();
|
||||
query.query_row($params, $f)
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! query_rows {
|
||||
($conn:expr, $sql:expr, $params:expr, $f:expr) => {{
|
||||
let mut query = $conn.prepare($sql).unwrap();
|
||||
|
||||
if let Ok(mut rows) = query.query($params) {
|
||||
let mut out = Vec::new();
|
||||
|
||||
while let Some(row) = rows.next().unwrap() {
|
||||
out.push($f(&row));
|
||||
}
|
||||
|
||||
Ok(out)
|
||||
} else {
|
||||
Err(Error::Unknown)
|
||||
}
|
||||
}};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! execute {
|
||||
($conn:expr, $sql:expr, $params:expr) => {
|
||||
$conn.prepare($sql).unwrap().execute($params)
|
||||
};
|
||||
|
||||
($conn:expr, $sql:expr) => {
|
||||
$conn.prepare($sql).unwrap().execute(())
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! params {
|
||||
() => {
|
||||
rusqlite::params![]
|
||||
};
|
||||
($($params:expr),+ $(,)?) => {
|
||||
rusqlite::params![$($params),+]
|
||||
};
|
||||
}
|
|
@ -1,23 +1,25 @@
|
|||
use std::collections::HashMap;
|
||||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::{
|
||||
Error, Result, auth::User, permissions::FinePermission,
|
||||
communities_permissions::CommunityPermission, uploads::CustomEmoji,
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`CustomEmoji`] from an SQL row.
|
||||
pub(crate) fn get_emoji_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> CustomEmoji {
|
||||
CustomEmoji {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -37,7 +39,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `community` - the ID of the community to fetch emojis for
|
||||
pub async fn get_emojis_by_community(&self, community: usize) -> Result<Vec<CustomEmoji>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -103,7 +105,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -148,7 +150,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -189,7 +191,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -204,7 +206,7 @@ impl DataManager {
|
|||
self.delete_upload(emoji.upload_id).await?;
|
||||
|
||||
// ...
|
||||
self.2.remove(format!("atto.emoji:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.emoji:{}", id)).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::addr::RemoteAddr;
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::{Error, Result, auth::IpBan, auth::User, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`IpBan`] from an SQL row.
|
||||
pub(crate) fn get_ipban_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> IpBan {
|
||||
IpBan {
|
||||
ip: get!(x->0(String)),
|
||||
|
@ -32,7 +33,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `prefix`
|
||||
pub async fn get_ipban_by_addr(&self, addr: RemoteAddr) -> Result<IpBan> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -57,7 +58,7 @@ impl DataManager {
|
|||
/// * `batch` - the limit of items in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_ipbans(&self, batch: usize, page: usize) -> Result<Vec<IpBan>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -88,7 +89,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -125,7 +126,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -136,7 +137,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.ipban:{}", ip)).await;
|
||||
self.0.1.remove(format!("atto.ipban:{}", ip)).await;
|
||||
|
||||
// create audit log entry
|
||||
self.create_audit_log_entry(AuditLogEntry::new(
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::{Error, Result, auth::User, auth::IpBlock, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`UserBlock`] from an SQL row.
|
||||
pub(crate) fn get_ipblock_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> IpBlock {
|
||||
IpBlock {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -31,7 +32,7 @@ impl DataManager {
|
|||
initiator: usize,
|
||||
receiver: &str,
|
||||
) -> Result<IpBlock> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -56,7 +57,7 @@ impl DataManager {
|
|||
receiver: &str,
|
||||
initiator: usize,
|
||||
) -> Result<IpBlock> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -80,7 +81,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `data` - a mock [`UserBlock`] object to insert
|
||||
pub async fn create_ipblock(&self, data: IpBlock) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -114,7 +115,7 @@ impl DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -125,7 +126,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.ipblock:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.ipblock:{}", id)).await;
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::communities::Community;
|
||||
use crate::model::requests::{ActionRequest, ActionType};
|
||||
use crate::model::{
|
||||
|
@ -9,19 +8,21 @@ use crate::model::{
|
|||
communities_permissions::CommunityPermission,
|
||||
permissions::FinePermission,
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`JournalEntry`] from an SQL row.
|
||||
pub(crate) fn get_membership_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> CommunityMembership {
|
||||
CommunityMembership {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -68,7 +69,7 @@ impl DataManager {
|
|||
owner: usize,
|
||||
community: usize,
|
||||
) -> Result<CommunityMembership> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -98,7 +99,7 @@ impl DataManager {
|
|||
owner: usize,
|
||||
community: usize,
|
||||
) -> Result<CommunityMembership> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -119,7 +120,7 @@ impl DataManager {
|
|||
|
||||
/// Get all community memberships by `owner`.
|
||||
pub async fn get_memberships_by_owner(&self, owner: usize) -> Result<Vec<CommunityMembership>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -147,7 +148,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<CommunityMembership>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -214,7 +215,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -270,7 +271,7 @@ impl DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -285,7 +286,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.membership:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.membership:{}", id)).await;
|
||||
|
||||
self.decr_community_member_count(y.community).await.unwrap();
|
||||
|
||||
|
@ -296,7 +297,7 @@ impl DataManager {
|
|||
pub async fn delete_membership_force(&self, id: usize) -> Result<()> {
|
||||
let y = self.get_membership_by_id(id).await?;
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -311,7 +312,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.membership:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.membership:{}", id)).await;
|
||||
|
||||
self.decr_community_member_count(y.community).await.unwrap();
|
||||
|
||||
|
@ -324,7 +325,7 @@ impl DataManager {
|
|||
id: usize,
|
||||
new_role: CommunityPermission,
|
||||
) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -339,7 +340,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.membership:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.membership:{}", id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::auth::Notification;
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::socket::{SocketMessage, SocketMethod};
|
||||
|
@ -8,29 +7,32 @@ use crate::model::{
|
|||
Error, Result, auth::User, permissions::FinePermission,
|
||||
communities_permissions::CommunityPermission, channels::Message,
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use serde::Serialize;
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "redis")]
|
||||
use oiseau::cache::redis::Commands;
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use oiseau::PostgresRow;
|
||||
#[cfg(feature = "postgres")]
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct DeleteMessageEvent {
|
||||
pub id: String,
|
||||
}
|
||||
|
||||
#[cfg(feature = "redis")]
|
||||
use redis::Commands;
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`Message`] from an SQL row.
|
||||
pub(crate) fn get_message_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Message {
|
||||
Message {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -93,7 +95,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Message>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -220,7 +222,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -244,7 +246,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// post event
|
||||
let mut con = self.2.get_con().await;
|
||||
let mut con = self.0.1.get_con().await;
|
||||
|
||||
if let Err(e) = con.publish::<String, String, ()>(
|
||||
if channel.community != 0 {
|
||||
|
@ -291,7 +293,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -302,10 +304,10 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.message:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.message:{}", id)).await;
|
||||
|
||||
// post event
|
||||
let mut con = self.2.get_con().await;
|
||||
let mut con = self.0.1.get_con().await;
|
||||
|
||||
if let Err(e) = con.publish::<String, String, ()>(
|
||||
if channel.community != 0 {
|
||||
|
@ -344,7 +346,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
|
|
@ -28,8 +28,4 @@ mod channels;
|
|||
#[cfg(feature = "redis")]
|
||||
mod messages;
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
pub use drivers::sqlite::*;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
pub use drivers::postgres::*;
|
||||
pub use drivers::DataManager;
|
||||
|
|
|
@ -1,23 +1,24 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::socket::{CrudMessageType, PacketType, SocketMessage, SocketMethod};
|
||||
use crate::model::{Error, Result, auth::Notification, auth::User, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "redis")]
|
||||
use redis::Commands;
|
||||
use oiseau::cache::redis::Commands;
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`Notification`] from an SQL row.
|
||||
pub(crate) fn get_notification_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Notification {
|
||||
Notification {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -34,7 +35,7 @@ impl DataManager {
|
|||
|
||||
/// Get all notifications by `owner`.
|
||||
pub async fn get_notifications_by_owner(&self, owner: usize) -> Result<Vec<Notification>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -60,7 +61,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Notification>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -81,7 +82,7 @@ impl DataManager {
|
|||
|
||||
/// Get all notifications by `tag`.
|
||||
pub async fn get_notifications_by_tag(&self, tag: &str) -> Result<Vec<Notification>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -105,7 +106,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `data` - a mock [`Notification`] object to insert
|
||||
pub async fn create_notification(&self, data: Notification) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -134,7 +135,7 @@ impl DataManager {
|
|||
};
|
||||
|
||||
// post event
|
||||
let mut con = self.2.get_con().await;
|
||||
let mut con = self.0.1.get_con().await;
|
||||
|
||||
if let Err(e) = con.publish::<String, String, ()>(
|
||||
format!("{}/notifs", data.owner),
|
||||
|
@ -160,7 +161,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -175,7 +176,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.notification:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.notification:{}", id)).await;
|
||||
|
||||
// decr notification count
|
||||
if !notification.read {
|
||||
|
@ -185,7 +186,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// post event
|
||||
let mut con = self.2.get_con().await;
|
||||
let mut con = self.0.1.get_con().await;
|
||||
|
||||
if let Err(e) = con.publish::<String, String, ()>(
|
||||
format!("{}/notifs", notification.owner),
|
||||
|
@ -249,7 +250,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -264,7 +265,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.notification:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.notification:{}", id)).await;
|
||||
|
||||
if (y.read) && (!new_read) {
|
||||
self.incr_user_notifications(user.id).await?;
|
||||
|
@ -287,13 +288,14 @@ impl DataManager {
|
|||
|
||||
changed_count += 1;
|
||||
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.remove(format!("atto.notification:{}", notification.id))
|
||||
.await;
|
||||
}
|
||||
|
||||
// execute
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::communities::Poll;
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::{Error, Result, auth::User, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, params, query_row, query_rows};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`Poll`] from an SQL row.
|
||||
pub(crate) fn get_poll_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Poll {
|
||||
Poll {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -40,7 +41,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `owner` - the ID of the owner of the polls
|
||||
pub async fn get_polls_by_owner_all(&self, owner: usize) -> Result<Vec<Poll>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -86,7 +87,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -131,7 +132,7 @@ impl DataManager {
|
|||
.await?
|
||||
}
|
||||
}
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -142,7 +143,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.poll:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.poll:{}", id)).await;
|
||||
|
||||
// remove votes
|
||||
let res = execute!(
|
||||
|
@ -160,7 +161,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
pub async fn cache_clear_poll(&self, poll: &Poll) {
|
||||
self.2.remove(format!("atto.poll:{}", poll.id)).await;
|
||||
self.0.1.remove(format!("atto.poll:{}", poll.id)).await;
|
||||
}
|
||||
|
||||
auto_method!(incr_votes_a_count()@get_poll_by_id -> "UPDATE polls SET votes_a = votes_a + 1 WHERE id = $1" --cache-key-tmpl=cache_clear_poll --incr);
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
use crate::model::communities::{PollOption, PollVote};
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::{Error, Result, auth::User, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`PollVote`] from an SQL row.
|
||||
pub(crate) fn get_pollvote_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> PollVote {
|
||||
PollVote {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -31,14 +32,15 @@ impl DataManager {
|
|||
|
||||
pub async fn get_pollvote_by_owner_poll(&self, id: usize, poll_id: usize) -> Result<PollVote> {
|
||||
if let Some(cached) = self
|
||||
.2
|
||||
.0
|
||||
.1
|
||||
.get(format!("atto.pollvote:{}:{}", id, poll_id))
|
||||
.await
|
||||
{
|
||||
return Ok(serde_json::from_str(&cached).unwrap());
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -55,7 +57,8 @@ impl DataManager {
|
|||
}
|
||||
|
||||
let x = res.unwrap();
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set(
|
||||
format!("atto.pollvote:{}:{}", id, poll_id),
|
||||
serde_json::to_string(&x).unwrap(),
|
||||
|
@ -81,7 +84,7 @@ impl DataManager {
|
|||
};
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -137,7 +140,7 @@ impl DataManager {
|
|||
.await?
|
||||
}
|
||||
}
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -152,7 +155,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.pollvote:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.pollvote:{}", id)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use std::collections::HashMap;
|
||||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::config::StringBan;
|
||||
use crate::model::auth::Notification;
|
||||
use crate::model::communities::{Poll, Question};
|
||||
|
@ -13,14 +12,16 @@ use crate::model::{
|
|||
communities::{Community, CommunityWriteAccess, Post, PostContext},
|
||||
permissions::FinePermission,
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
macro_rules! private_post_replying {
|
||||
($post:ident, $replying_posts:ident, $ua1:ident, $data:ident) => {
|
||||
|
@ -89,8 +90,8 @@ macro_rules! private_post_replying {
|
|||
impl DataManager {
|
||||
/// Get a [`Post`] from an SQL row.
|
||||
pub(crate) fn get_post_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Post {
|
||||
Post {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -127,7 +128,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -474,7 +475,7 @@ impl DataManager {
|
|||
page: usize,
|
||||
user: &Option<User>,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -521,7 +522,7 @@ impl DataManager {
|
|||
page: usize,
|
||||
user: &Option<User>,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -568,7 +569,7 @@ impl DataManager {
|
|||
page: usize,
|
||||
user: &Option<User>,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -618,7 +619,7 @@ impl DataManager {
|
|||
text_query: &str,
|
||||
user: &Option<&User>,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -669,7 +670,7 @@ impl DataManager {
|
|||
page: usize,
|
||||
text_query: &str,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -704,7 +705,7 @@ impl DataManager {
|
|||
page: usize,
|
||||
user: &Option<User>,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -755,7 +756,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -779,7 +780,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `id` - the ID of the community the requested posts belong to
|
||||
pub async fn get_pinned_posts_by_community(&self, id: usize) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -803,7 +804,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `id` - the ID of the user the requested posts belong to
|
||||
pub async fn get_pinned_posts_by_user(&self, id: usize) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -834,7 +835,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -863,7 +864,7 @@ impl DataManager {
|
|||
/// * `owner` - the ID of the post owner
|
||||
/// * `question` - the ID of the post question
|
||||
pub async fn get_post_by_owner_question(&self, owner: usize, question: usize) -> Result<Post> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -897,7 +898,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -935,7 +936,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -970,7 +971,7 @@ impl DataManager {
|
|||
page: usize,
|
||||
cutoff: usize,
|
||||
) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1000,7 +1001,7 @@ impl DataManager {
|
|||
/// * `batch` - the limit of posts in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_latest_posts(&self, batch: usize, page: usize) -> Result<Vec<Post>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1045,7 +1046,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1093,7 +1094,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1143,7 +1144,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1193,7 +1194,7 @@ impl DataManager {
|
|||
/// * `data` - a mock [`Post`] object to insert
|
||||
pub async fn create_post(&self, mut data: Post) -> Result<usize> {
|
||||
// check characters
|
||||
for ban in &self.0.banned_data {
|
||||
for ban in &self.0.0.banned_data {
|
||||
match ban {
|
||||
StringBan::String(x) => {
|
||||
if data.content.contains(x) {
|
||||
|
@ -1418,7 +1419,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1506,7 +1507,7 @@ impl DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1517,7 +1518,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.post:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.post:{}", id)).await;
|
||||
|
||||
// decr parent comment count
|
||||
if let Some(replying_to) = y.replying_to {
|
||||
|
@ -1577,7 +1578,7 @@ impl DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1592,7 +1593,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.post:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.post:{}", id)).await;
|
||||
|
||||
if is_deleted {
|
||||
// decr parent comment count
|
||||
|
@ -1706,7 +1707,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -1721,7 +1722,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.post:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.post:{}", id)).await;
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
|
@ -1743,7 +1744,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
use crate::model::communities_permissions::CommunityPermission;
|
||||
use crate::model::{
|
||||
Error, Result,
|
||||
|
@ -10,20 +9,21 @@ use crate::model::{
|
|||
auth::User,
|
||||
permissions::FinePermission,
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
use tetratto_shared::unix_epoch_timestamp;
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`Question`] from an SQL row.
|
||||
pub(crate) fn get_question_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Question {
|
||||
Question {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -78,7 +78,7 @@ impl DataManager {
|
|||
|
||||
/// Get all questions by `owner`.
|
||||
pub async fn get_questions_by_owner(&self, owner: usize) -> Result<Vec<Question>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -104,7 +104,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Question>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -125,7 +125,7 @@ impl DataManager {
|
|||
|
||||
/// Get all questions by `receiver`.
|
||||
pub async fn get_questions_by_receiver(&self, receiver: usize) -> Result<Vec<Question>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -151,7 +151,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Question>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -195,7 +195,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -238,7 +238,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -270,7 +270,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Question>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -301,7 +301,7 @@ impl DataManager {
|
|||
page: usize,
|
||||
cutoff: usize,
|
||||
) -> Result<Vec<Question>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -383,7 +383,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -447,7 +447,7 @@ impl DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -462,7 +462,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.question:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.question:{}", id)).await;
|
||||
|
||||
// delete request (if it exists and question isn't global)
|
||||
if !y.is_global
|
||||
|
|
|
@ -1,24 +1,25 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::{
|
||||
Error, Result,
|
||||
auth::{Notification, User},
|
||||
permissions::FinePermission,
|
||||
reactions::{AssetType, Reaction},
|
||||
};
|
||||
use crate::{auto_method, execute, get, params, query_row, query_rows};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`Reaction`] from an SQL row.
|
||||
pub(crate) fn get_reaction_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Reaction {
|
||||
Reaction {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -61,7 +62,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Reaction>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -87,7 +88,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<Reaction>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -112,7 +113,7 @@ impl DataManager {
|
|||
owner: usize,
|
||||
asset: usize,
|
||||
) -> Result<Reaction> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -136,7 +137,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `data` - a mock [`Reaction`] object to insert
|
||||
pub async fn create_reaction(&self, data: Reaction, user: &User) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -278,7 +279,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -293,7 +294,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.reaction:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.reaction:{}", id)).await;
|
||||
|
||||
// decr corresponding
|
||||
match reaction.asset_type {
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::{Error, Result, auth::User, moderation::Report, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`Report`] from an SQL row.
|
||||
pub(crate) fn get_report_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> Report {
|
||||
Report {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -34,7 +35,7 @@ impl DataManager {
|
|||
/// * `batch` - the limit of items in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_reports(&self, batch: usize, page: usize) -> Result<Vec<Report>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -58,7 +59,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `data` - a mock [`Report`] object to insert
|
||||
pub async fn create_report(&self, data: Report) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -93,7 +94,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -104,7 +105,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.report:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.report:{}", id)).await;
|
||||
|
||||
// create audit log entry
|
||||
self.create_audit_log_entry(AuditLogEntry::new(
|
||||
|
|
|
@ -1,20 +1,21 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::requests::ActionType;
|
||||
use crate::model::{Error, Result, requests::ActionRequest, auth::User, permissions::FinePermission};
|
||||
use crate::{execute, get, query_row, query_rows, params};
|
||||
use crate::DataManager;
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get an [`ActionRequest`] from an SQL row.
|
||||
pub(crate) fn get_request_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> ActionRequest {
|
||||
ActionRequest {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -31,14 +32,15 @@ impl DataManager {
|
|||
linked_asset: usize,
|
||||
) -> Result<ActionRequest> {
|
||||
if let Some(cached) = self
|
||||
.2
|
||||
.0
|
||||
.1
|
||||
.get(format!("atto.request:{}:{}", id, linked_asset))
|
||||
.await
|
||||
{
|
||||
return Ok(serde_json::from_str(&cached).unwrap());
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -55,7 +57,8 @@ impl DataManager {
|
|||
}
|
||||
|
||||
let x = res.unwrap();
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.set(
|
||||
format!("atto.request:{}:{}", id, linked_asset),
|
||||
serde_json::to_string(&x).unwrap(),
|
||||
|
@ -67,7 +70,7 @@ impl DataManager {
|
|||
|
||||
/// Get all action requests by `owner`.
|
||||
pub async fn get_requests_by_owner(&self, owner: usize) -> Result<Vec<ActionRequest>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -93,7 +96,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<ActionRequest>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -117,7 +120,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `data` - a mock [`ActionRequest`] object to insert
|
||||
pub async fn create_request(&self, data: ActionRequest) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -163,7 +166,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -178,9 +181,10 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.request:{}", y.id)).await;
|
||||
self.0.1.remove(format!("atto.request:{}", y.id)).await;
|
||||
|
||||
self.2
|
||||
self.0
|
||||
.1
|
||||
.remove(format!("atto.request:{}:{}", id, linked_asset))
|
||||
.await;
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::communities::{Community, Poll, Post, Question};
|
||||
use crate::model::stacks::{StackMode, StackSort};
|
||||
use crate::model::{
|
||||
|
@ -8,19 +7,21 @@ use crate::model::{
|
|||
permissions::FinePermission,
|
||||
stacks::{StackPrivacy, UserStack},
|
||||
};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`UserStack`] from an SQL row.
|
||||
pub(crate) fn get_stack_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> UserStack {
|
||||
UserStack {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -99,7 +100,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `id` - the ID of the user to fetch stacks for
|
||||
pub async fn get_stacks_by_owner(&self, id: usize) -> Result<Vec<UserStack>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -146,7 +147,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -182,7 +183,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -193,7 +194,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.stack:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.stack:{}", id)).await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::auth::User;
|
||||
use crate::model::permissions::FinePermission;
|
||||
use crate::model::{Error, Result, uploads::MediaUpload};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`MediaUpload`] from an SQL row.
|
||||
pub(crate) fn get_upload_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> MediaUpload {
|
||||
MediaUpload {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -33,7 +34,7 @@ impl DataManager {
|
|||
/// * `batch` - the limit of items in each page
|
||||
/// * `page` - the page number
|
||||
pub async fn get_uploads(&self, batch: usize, page: usize) -> Result<Vec<MediaUpload>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -64,7 +65,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<MediaUpload>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -88,7 +89,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `owner` - the ID of the owner of the upload
|
||||
pub async fn get_uploads_by_owner_all(&self, owner: usize) -> Result<Vec<MediaUpload>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -112,7 +113,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `data` - a mock [`MediaUpload`] object to insert
|
||||
pub async fn create_upload(&self, data: MediaUpload) -> Result<MediaUpload> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -147,10 +148,10 @@ impl DataManager {
|
|||
//
|
||||
// the actual file takes up much more space than the database entry.
|
||||
let upload = self.get_upload_by_id(id).await?;
|
||||
upload.remove(&self.0)?;
|
||||
upload.remove(&self.0.0)?;
|
||||
|
||||
// delete from database
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -161,7 +162,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.upload:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.upload:{}", id)).await;
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
|
@ -176,10 +177,10 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// delete file
|
||||
upload.remove(&self.0)?;
|
||||
upload.remove(&self.0.0)?;
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -190,7 +191,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.upload:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.upload:{}", id)).await;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::auth::{Notification, UserWarning};
|
||||
use crate::model::moderation::AuditLogEntry;
|
||||
use crate::model::{Error, Result, auth::User, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`UserWarning`] from an SQL row.
|
||||
pub(crate) fn get_user_warning_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> UserWarning {
|
||||
UserWarning {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -40,7 +41,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<UserWarning>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -71,7 +72,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -120,7 +121,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -135,7 +136,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.user_warning:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.user_warning:{}", id)).await;
|
||||
|
||||
// create audit log entry
|
||||
self.create_audit_log_entry(AuditLogEntry::new(
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::{Error, Result, auth::User, auth::UserBlock, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, params, query_row, query_rows};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`UserBlock`] from an SQL row.
|
||||
pub(crate) fn get_userblock_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> UserBlock {
|
||||
UserBlock {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -48,7 +49,7 @@ impl DataManager {
|
|||
initiator: usize,
|
||||
receiver: usize,
|
||||
) -> Result<UserBlock> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -73,7 +74,7 @@ impl DataManager {
|
|||
receiver: usize,
|
||||
initiator: usize,
|
||||
) -> Result<UserBlock> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -94,7 +95,7 @@ impl DataManager {
|
|||
|
||||
/// Get the receiver of all user blocks for the given `initiator`.
|
||||
pub async fn get_userblocks_receivers(&self, initiator: usize) -> Vec<usize> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
|
@ -123,7 +124,7 @@ impl DataManager {
|
|||
|
||||
/// Get all user blocks created by the given `initiator`.
|
||||
pub async fn get_userblocks_by_initiator(&self, initiator: usize) -> Vec<UserBlock> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
|
@ -145,7 +146,7 @@ impl DataManager {
|
|||
|
||||
/// Get the owner of all user blocks for the given `receiver`.
|
||||
pub async fn get_userblocks_initiator_by_receivers(&self, receiver: usize) -> Vec<usize> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(_) => return Vec::new(),
|
||||
};
|
||||
|
@ -181,7 +182,7 @@ impl DataManager {
|
|||
let receiver = self.get_user_by_id(data.receiver).await?;
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -240,7 +241,7 @@ impl DataManager {
|
|||
}
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -255,14 +256,14 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.userblock:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.userblock:{}", id)).await;
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn delete_userblock_sudo(&self, id: usize) -> Result<()> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -277,7 +278,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.userblock:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.userblock:{}", id)).await;
|
||||
|
||||
// return
|
||||
Ok(())
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
use super::*;
|
||||
use crate::cache::Cache;
|
||||
use oiseau::cache::Cache;
|
||||
use crate::model::auth::FollowResult;
|
||||
use crate::model::requests::{ActionRequest, ActionType};
|
||||
use crate::model::{Error, Result, auth::User, auth::UserFollow, permissions::FinePermission};
|
||||
use crate::{auto_method, execute, get, query_row, query_rows, params};
|
||||
use crate::{auto_method, DataManager};
|
||||
|
||||
#[cfg(feature = "sqlite")]
|
||||
use rusqlite::Row;
|
||||
use oiseau::SqliteRow;
|
||||
|
||||
#[cfg(feature = "postgres")]
|
||||
use tokio_postgres::Row;
|
||||
use oiseau::PostgresRow;
|
||||
|
||||
use oiseau::{execute, get, query_row, query_rows, params};
|
||||
|
||||
impl DataManager {
|
||||
/// Get a [`UserFollow`] from an SQL row.
|
||||
pub(crate) fn get_userfollow_from_row(
|
||||
#[cfg(feature = "sqlite")] x: &Row<'_>,
|
||||
#[cfg(feature = "postgres")] x: &Row,
|
||||
#[cfg(feature = "sqlite")] x: &SqliteRow<'_>,
|
||||
#[cfg(feature = "postgres")] x: &PostgresRow,
|
||||
) -> UserFollow {
|
||||
UserFollow {
|
||||
id: get!(x->0(i64)) as usize,
|
||||
|
@ -33,7 +34,7 @@ impl DataManager {
|
|||
initiator: usize,
|
||||
receiver: usize,
|
||||
) -> Result<UserFollow> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -58,7 +59,7 @@ impl DataManager {
|
|||
receiver: usize,
|
||||
initiator: usize,
|
||||
) -> Result<UserFollow> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -89,7 +90,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<UserFollow>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -113,7 +114,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `id` - the ID of the user
|
||||
pub async fn get_userfollows_by_initiator_all(&self, id: usize) -> Result<Vec<UserFollow>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -144,7 +145,7 @@ impl DataManager {
|
|||
batch: usize,
|
||||
page: usize,
|
||||
) -> Result<Vec<UserFollow>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -168,7 +169,7 @@ impl DataManager {
|
|||
/// # Arguments
|
||||
/// * `id` - the ID of the user
|
||||
pub async fn get_userfollows_by_receiver_all(&self, id: usize) -> Result<Vec<UserFollow>> {
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -253,7 +254,7 @@ impl DataManager {
|
|||
}
|
||||
|
||||
// ...
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -300,7 +301,7 @@ impl DataManager {
|
|||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
let conn = match self.connect().await {
|
||||
let conn = match self.0.connect().await {
|
||||
Ok(c) => c,
|
||||
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
|
||||
};
|
||||
|
@ -315,7 +316,7 @@ impl DataManager {
|
|||
return Err(Error::DatabaseError(e.to_string()));
|
||||
}
|
||||
|
||||
self.2.remove(format!("atto.userfollow:{}", id)).await;
|
||||
self.0.1.remove(format!("atto.userfollow:{}", id)).await;
|
||||
|
||||
// decr counts (if we aren't deleting the user OR the user id isn't the deleted user id)
|
||||
if !is_deleting_user | (follow.initiator != user.id) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
pub mod cache;
|
||||
pub mod config;
|
||||
pub mod database;
|
||||
pub mod model;
|
||||
|
||||
pub use database::DataManager;
|
||||
pub use oiseau::cache;
|
||||
|
||||
/// Tells us if pubsub capabilities are provided (via Redis).
|
||||
///
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue