fix(helpers): transactions
This commit is contained in:
parent
0c3ea546fd
commit
c183747729
4 changed files with 134 additions and 102 deletions
12
Cargo.lock
generated
12
Cargo.lock
generated
|
@ -1721,9 +1721,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "once_cell"
|
name = "once_cell"
|
||||||
version = "1.16.0"
|
version = "1.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860"
|
checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opaque-debug"
|
name = "opaque-debug"
|
||||||
|
@ -2937,9 +2937,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.16.2"
|
version = "0.17.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd30deba9a1cd7153c22aecf93e86df639e7b81c622b0af8d9255e989991a7b7"
|
checksum = "a34cc558345efd7e88b9eda9626df2138b80bb46a7606f695e751c892bc7dac6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
@ -3003,9 +3003,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typed-sled"
|
name = "typed-sled"
|
||||||
version = "0.2.1"
|
version = "0.2.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32b903ab728fcd56542a5c538dfc3d196aeffcdb1dc37e34c49f61782adc5cfa"
|
checksum = "1060f05a4450ec5b758da60951b04f225a93a62079316630e76cf25c4034500d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bincode",
|
"bincode",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
|
|
|
@ -29,8 +29,8 @@ sled = "0.34.7"
|
||||||
tera = { version = "1.17.1", features = ["builtins", "date-locale"] }
|
tera = { version = "1.17.1", features = ["builtins", "date-locale"] }
|
||||||
tide = { version = "0.16.0", default-features = false, features = ["h1-server", "cookies", "logger"] }
|
tide = { version = "0.16.0", default-features = false, features = ["h1-server", "cookies", "logger"] }
|
||||||
tokio = { version = "1.23.0", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1.23.0", features = ["macros", "rt-multi-thread"] }
|
||||||
toml_edit = { version = "0.16.2", features = ["easy"] }
|
toml_edit = { version = "0.17.1", features = ["easy"] }
|
||||||
typed-sled = "0.2.1"
|
typed-sled = "0.2.3"
|
||||||
unic-langid = { version = "0.9.1", features = ["macros"] }
|
unic-langid = { version = "0.9.1", features = ["macros"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|
|
@ -2,6 +2,10 @@ use base64::engine::Engine;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
use std::{net::IpAddr, path::Path};
|
use std::{net::IpAddr, path::Path};
|
||||||
|
|
||||||
|
pub use sled::transaction::{
|
||||||
|
ConflictableTransactionError, ConflictableTransactionResult, TransactionError,
|
||||||
|
};
|
||||||
pub use typed_sled::Tree;
|
pub use typed_sled::Tree;
|
||||||
|
|
||||||
const DB_DIR: &str = "db";
|
const DB_DIR: &str = "db";
|
||||||
|
|
216
src/helpers.rs
216
src/helpers.rs
|
@ -3,6 +3,7 @@ use crate::{config::Config, db::*, locales::Locales, queries::*};
|
||||||
use fluent_bundle::FluentArgs;
|
use fluent_bundle::FluentArgs;
|
||||||
use log::error;
|
use log::error;
|
||||||
use std::{net::IpAddr, str::FromStr};
|
use std::{net::IpAddr, str::FromStr};
|
||||||
|
use typed_sled::transaction::Transactional;
|
||||||
use unic_langid::LanguageIdentifier;
|
use unic_langid::LanguageIdentifier;
|
||||||
|
|
||||||
pub fn new_pending_comment(
|
pub fn new_pending_comment(
|
||||||
|
@ -11,16 +12,21 @@ pub fn new_pending_comment(
|
||||||
dbs: &Dbs,
|
dbs: &Dbs,
|
||||||
) -> Result<CommentId, sled::Error> {
|
) -> Result<CommentId, sled::Error> {
|
||||||
let comment_id = CommentId::new();
|
let comment_id = CommentId::new();
|
||||||
dbs.comment
|
(&dbs.comment, &dbs.comment_pending)
|
||||||
.insert(&comment_id, &(comment.clone(), CommentStatus::Pending))?;
|
.transaction(|(db_comment, db_comment_pending)| {
|
||||||
dbs.comment_pending.insert(
|
db_comment.insert(&comment_id, &(comment.clone(), CommentStatus::Pending))?;
|
||||||
&(
|
db_comment_pending.insert(
|
||||||
comment.topic_hash.clone(),
|
&(
|
||||||
comment.post_time,
|
comment.topic_hash.clone(),
|
||||||
comment_id.clone(),
|
comment.post_time,
|
||||||
),
|
comment_id.clone(),
|
||||||
&(addr, false),
|
),
|
||||||
)?;
|
&(addr, false),
|
||||||
|
)?;
|
||||||
|
ConflictableTransactionResult::<_>::Ok(())
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
Ok(comment_id)
|
Ok(comment_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,18 +46,26 @@ pub fn edit_comment(
|
||||||
// TODO should we update ip address in comment_pending?
|
// TODO should we update ip address in comment_pending?
|
||||||
}
|
}
|
||||||
CommentStatus::Approved => {
|
CommentStatus::Approved => {
|
||||||
dbs.comment_pending.insert(
|
(&dbs.comment, &dbs.comment_pending)
|
||||||
&(
|
.transaction(|(db_comment, db_comment_pending)| {
|
||||||
edited_comment.topic_hash.clone(),
|
db_comment_pending.insert(
|
||||||
edited_comment.post_time,
|
&(
|
||||||
comment_id.clone(),
|
edited_comment.topic_hash.clone(),
|
||||||
),
|
edited_comment.post_time,
|
||||||
&(addr, true),
|
comment_id.clone(),
|
||||||
)?;
|
),
|
||||||
dbs.comment.insert(
|
&(addr, true),
|
||||||
&comment_id,
|
)?;
|
||||||
&(old_comment, CommentStatus::ApprovedEdited(edited_comment)),
|
db_comment.insert(
|
||||||
)?;
|
&comment_id,
|
||||||
|
&(
|
||||||
|
old_comment.clone(),
|
||||||
|
CommentStatus::ApprovedEdited(edited_comment.clone()),
|
||||||
|
),
|
||||||
|
)?;
|
||||||
|
ConflictableTransactionResult::<_>::Ok(())
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
CommentStatus::ApprovedEdited(_old_edited_comment) => {
|
CommentStatus::ApprovedEdited(_old_edited_comment) => {
|
||||||
dbs.comment.insert(
|
dbs.comment.insert(
|
||||||
|
@ -65,94 +79,108 @@ pub fn edit_comment(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn approve_comment(comment_id: CommentId, dbs: &Dbs) -> Result<(), sled::Error> {
|
pub fn approve_comment(comment_id: CommentId, dbs: &Dbs) -> Result<(), sled::Error> {
|
||||||
if let Some((comment, CommentStatus::Pending)) = dbs.comment.get(&comment_id)? {
|
(&dbs.comment, &dbs.comment_approved, &dbs.comment_pending)
|
||||||
dbs.comment_pending.remove(&(
|
.transaction(|(db_comment, db_comment_approved, db_comment_pending)| {
|
||||||
comment.topic_hash.clone(),
|
if let Some((comment, CommentStatus::Pending)) = db_comment.get(&comment_id)? {
|
||||||
comment.post_time,
|
db_comment_pending.remove(&(
|
||||||
comment_id.clone(),
|
comment.topic_hash.clone(),
|
||||||
))?;
|
comment.post_time,
|
||||||
dbs.comment_approved.insert(
|
comment_id.clone(),
|
||||||
&(
|
))?;
|
||||||
comment.topic_hash.clone(),
|
db_comment_approved.insert(
|
||||||
comment.post_time,
|
&(
|
||||||
comment_id.clone(),
|
comment.topic_hash.clone(),
|
||||||
),
|
comment.post_time,
|
||||||
&(),
|
comment_id.clone(),
|
||||||
)?;
|
),
|
||||||
dbs.comment
|
&(),
|
||||||
.insert(&comment_id, &(comment, CommentStatus::Approved))?;
|
)?;
|
||||||
}
|
db_comment.insert(&comment_id, &(comment, CommentStatus::Approved))?;
|
||||||
|
}
|
||||||
|
ConflictableTransactionResult::<_>::Ok(())
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn approve_edit(comment_id: CommentId, dbs: &Dbs) -> Result<Option<Comment>, sled::Error> {
|
pub fn approve_edit(comment_id: CommentId, dbs: &Dbs) -> Result<Option<Comment>, sled::Error> {
|
||||||
if let Some((comment, CommentStatus::ApprovedEdited(edited_comment))) =
|
Ok((&dbs.comment, &dbs.comment_pending)
|
||||||
dbs.comment.get(&comment_id)?
|
.transaction(|(db_comment, db_comment_pending)| {
|
||||||
{
|
if let Some((comment, CommentStatus::ApprovedEdited(edited_comment))) =
|
||||||
dbs.comment_pending.remove(&(
|
db_comment.get(&comment_id)?
|
||||||
edited_comment.topic_hash.clone(),
|
{
|
||||||
edited_comment.post_time,
|
db_comment_pending.remove(&(
|
||||||
comment_id.clone(),
|
edited_comment.topic_hash.clone(),
|
||||||
))?;
|
edited_comment.post_time,
|
||||||
dbs.comment
|
comment_id.clone(),
|
||||||
.insert(&comment_id, &(edited_comment, CommentStatus::Approved))?;
|
))?;
|
||||||
return Ok(Some(comment));
|
db_comment.insert(&comment_id, &(edited_comment, CommentStatus::Approved))?;
|
||||||
}
|
return ConflictableTransactionResult::<_>::Ok(Some(comment));
|
||||||
Ok(None)
|
}
|
||||||
|
ConflictableTransactionResult::<_>::Ok(None)
|
||||||
|
})
|
||||||
|
.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn remove_comment(
|
pub fn remove_comment(
|
||||||
comment_id: CommentId,
|
comment_id: CommentId,
|
||||||
dbs: &Dbs,
|
dbs: &Dbs,
|
||||||
) -> Result<Option<(Comment, CommentStatus)>, sled::Error> {
|
) -> Result<Option<(Comment, CommentStatus)>, sled::Error> {
|
||||||
if let Some((comment, edited_comment)) = dbs.comment.remove(&comment_id)? {
|
Ok((&dbs.comment, &dbs.comment_approved, &dbs.comment_pending)
|
||||||
match &edited_comment {
|
.transaction(|(db_comment, db_comment_approved, db_comment_pending)| {
|
||||||
CommentStatus::Pending => {
|
if let Some((comment, edited_comment)) = db_comment.remove(&comment_id)? {
|
||||||
dbs.comment_pending.remove(&(
|
match &edited_comment {
|
||||||
comment.topic_hash.clone(),
|
CommentStatus::Pending => {
|
||||||
comment.post_time,
|
db_comment_pending.remove(&(
|
||||||
comment_id,
|
comment.topic_hash.clone(),
|
||||||
))?;
|
comment.post_time,
|
||||||
|
comment_id.clone(),
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
CommentStatus::Approved => {
|
||||||
|
db_comment_approved.remove(&(
|
||||||
|
comment.topic_hash.clone(),
|
||||||
|
comment.post_time,
|
||||||
|
comment_id.clone(),
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
CommentStatus::ApprovedEdited(edited_comment) => {
|
||||||
|
db_comment_pending.remove(&(
|
||||||
|
edited_comment.topic_hash.clone(),
|
||||||
|
edited_comment.post_time,
|
||||||
|
comment_id.clone(),
|
||||||
|
))?;
|
||||||
|
db_comment_approved.remove(&(
|
||||||
|
comment.topic_hash.clone(),
|
||||||
|
comment.post_time,
|
||||||
|
comment_id.clone(),
|
||||||
|
))?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ConflictableTransactionResult::<_>::Ok(Some((comment, edited_comment)));
|
||||||
}
|
}
|
||||||
CommentStatus::Approved => {
|
ConflictableTransactionResult::<_>::Ok(None)
|
||||||
dbs.comment_approved.remove(&(
|
})
|
||||||
comment.topic_hash.clone(),
|
.unwrap())
|
||||||
comment.post_time,
|
}
|
||||||
comment_id,
|
|
||||||
))?;
|
pub fn remove_edit(comment_id: CommentId, dbs: &Dbs) -> Result<Option<Comment>, sled::Error> {
|
||||||
}
|
Ok((&dbs.comment, &dbs.comment_pending)
|
||||||
CommentStatus::ApprovedEdited(edited_comment) => {
|
.transaction(|(db_comment, db_comment_pending)| {
|
||||||
dbs.comment_pending.remove(&(
|
if let Some((comment, CommentStatus::ApprovedEdited(edited_comment))) =
|
||||||
|
db_comment.get(&comment_id)?
|
||||||
|
{
|
||||||
|
db_comment_pending.remove(&(
|
||||||
edited_comment.topic_hash.clone(),
|
edited_comment.topic_hash.clone(),
|
||||||
edited_comment.post_time,
|
edited_comment.post_time,
|
||||||
comment_id.clone(),
|
comment_id.clone(),
|
||||||
))?;
|
))?;
|
||||||
dbs.comment_approved.remove(&(
|
db_comment.insert(&comment_id, &(comment.clone(), CommentStatus::Approved))?;
|
||||||
comment.topic_hash.clone(),
|
return ConflictableTransactionResult::<_>::Ok(Some(comment));
|
||||||
comment.post_time,
|
|
||||||
comment_id,
|
|
||||||
))?;
|
|
||||||
}
|
}
|
||||||
}
|
ConflictableTransactionResult::<_>::Ok(None)
|
||||||
return Ok(Some((comment, edited_comment)));
|
})
|
||||||
}
|
.unwrap())
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn remove_edit(comment_id: CommentId, dbs: &Dbs) -> Result<Option<Comment>, sled::Error> {
|
|
||||||
if let Some((comment, CommentStatus::ApprovedEdited(edited_comment))) =
|
|
||||||
dbs.comment.get(&comment_id)?
|
|
||||||
{
|
|
||||||
dbs.comment_pending.remove(&(
|
|
||||||
edited_comment.topic_hash.clone(),
|
|
||||||
edited_comment.post_time,
|
|
||||||
comment_id.clone(),
|
|
||||||
))?;
|
|
||||||
dbs.comment
|
|
||||||
.insert(&comment_id, &(comment.clone(), CommentStatus::Approved))?;
|
|
||||||
return Ok(Some(comment));
|
|
||||||
}
|
|
||||||
Ok(None)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_comments_by_topic<'a, V: typed_sled::KV>(
|
pub fn iter_comments_by_topic<'a, V: typed_sled::KV>(
|
||||||
|
|
Loading…
Reference in a new issue