fix(helpers): transactions
This commit is contained in:
parent
0c3ea546fd
commit
c183747729
4 changed files with 134 additions and 102 deletions
|
|
@ -2,6 +2,10 @@ use base64::engine::Engine;
|
|||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::{net::IpAddr, path::Path};
|
||||
|
||||
pub use sled::transaction::{
|
||||
ConflictableTransactionError, ConflictableTransactionResult, TransactionError,
|
||||
};
|
||||
pub use typed_sled::Tree;
|
||||
|
||||
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 log::error;
|
||||
use std::{net::IpAddr, str::FromStr};
|
||||
use typed_sled::transaction::Transactional;
|
||||
use unic_langid::LanguageIdentifier;
|
||||
|
||||
pub fn new_pending_comment(
|
||||
|
|
@ -11,16 +12,21 @@ pub fn new_pending_comment(
|
|||
dbs: &Dbs,
|
||||
) -> Result<CommentId, sled::Error> {
|
||||
let comment_id = CommentId::new();
|
||||
dbs.comment
|
||||
.insert(&comment_id, &(comment.clone(), CommentStatus::Pending))?;
|
||||
dbs.comment_pending.insert(
|
||||
&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id.clone(),
|
||||
),
|
||||
&(addr, false),
|
||||
)?;
|
||||
(&dbs.comment, &dbs.comment_pending)
|
||||
.transaction(|(db_comment, db_comment_pending)| {
|
||||
db_comment.insert(&comment_id, &(comment.clone(), CommentStatus::Pending))?;
|
||||
db_comment_pending.insert(
|
||||
&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id.clone(),
|
||||
),
|
||||
&(addr, false),
|
||||
)?;
|
||||
ConflictableTransactionResult::<_>::Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
Ok(comment_id)
|
||||
}
|
||||
|
||||
|
|
@ -40,18 +46,26 @@ pub fn edit_comment(
|
|||
// TODO should we update ip address in comment_pending?
|
||||
}
|
||||
CommentStatus::Approved => {
|
||||
dbs.comment_pending.insert(
|
||||
&(
|
||||
edited_comment.topic_hash.clone(),
|
||||
edited_comment.post_time,
|
||||
comment_id.clone(),
|
||||
),
|
||||
&(addr, true),
|
||||
)?;
|
||||
dbs.comment.insert(
|
||||
&comment_id,
|
||||
&(old_comment, CommentStatus::ApprovedEdited(edited_comment)),
|
||||
)?;
|
||||
(&dbs.comment, &dbs.comment_pending)
|
||||
.transaction(|(db_comment, db_comment_pending)| {
|
||||
db_comment_pending.insert(
|
||||
&(
|
||||
edited_comment.topic_hash.clone(),
|
||||
edited_comment.post_time,
|
||||
comment_id.clone(),
|
||||
),
|
||||
&(addr, true),
|
||||
)?;
|
||||
db_comment.insert(
|
||||
&comment_id,
|
||||
&(
|
||||
old_comment.clone(),
|
||||
CommentStatus::ApprovedEdited(edited_comment.clone()),
|
||||
),
|
||||
)?;
|
||||
ConflictableTransactionResult::<_>::Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
CommentStatus::ApprovedEdited(_old_edited_comment) => {
|
||||
dbs.comment.insert(
|
||||
|
|
@ -65,94 +79,108 @@ pub fn edit_comment(
|
|||
}
|
||||
|
||||
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_pending.remove(&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id.clone(),
|
||||
))?;
|
||||
dbs.comment_approved.insert(
|
||||
&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id.clone(),
|
||||
),
|
||||
&(),
|
||||
)?;
|
||||
dbs.comment
|
||||
.insert(&comment_id, &(comment, CommentStatus::Approved))?;
|
||||
}
|
||||
(&dbs.comment, &dbs.comment_approved, &dbs.comment_pending)
|
||||
.transaction(|(db_comment, db_comment_approved, db_comment_pending)| {
|
||||
if let Some((comment, CommentStatus::Pending)) = db_comment.get(&comment_id)? {
|
||||
db_comment_pending.remove(&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id.clone(),
|
||||
))?;
|
||||
db_comment_approved.insert(
|
||||
&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id.clone(),
|
||||
),
|
||||
&(),
|
||||
)?;
|
||||
db_comment.insert(&comment_id, &(comment, CommentStatus::Approved))?;
|
||||
}
|
||||
ConflictableTransactionResult::<_>::Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn approve_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, &(edited_comment, CommentStatus::Approved))?;
|
||||
return Ok(Some(comment));
|
||||
}
|
||||
Ok(None)
|
||||
Ok((&dbs.comment, &dbs.comment_pending)
|
||||
.transaction(|(db_comment, db_comment_pending)| {
|
||||
if let Some((comment, CommentStatus::ApprovedEdited(edited_comment))) =
|
||||
db_comment.get(&comment_id)?
|
||||
{
|
||||
db_comment_pending.remove(&(
|
||||
edited_comment.topic_hash.clone(),
|
||||
edited_comment.post_time,
|
||||
comment_id.clone(),
|
||||
))?;
|
||||
db_comment.insert(&comment_id, &(edited_comment, CommentStatus::Approved))?;
|
||||
return ConflictableTransactionResult::<_>::Ok(Some(comment));
|
||||
}
|
||||
ConflictableTransactionResult::<_>::Ok(None)
|
||||
})
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
pub fn remove_comment(
|
||||
comment_id: CommentId,
|
||||
dbs: &Dbs,
|
||||
) -> Result<Option<(Comment, CommentStatus)>, sled::Error> {
|
||||
if let Some((comment, edited_comment)) = dbs.comment.remove(&comment_id)? {
|
||||
match &edited_comment {
|
||||
CommentStatus::Pending => {
|
||||
dbs.comment_pending.remove(&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id,
|
||||
))?;
|
||||
Ok((&dbs.comment, &dbs.comment_approved, &dbs.comment_pending)
|
||||
.transaction(|(db_comment, db_comment_approved, db_comment_pending)| {
|
||||
if let Some((comment, edited_comment)) = db_comment.remove(&comment_id)? {
|
||||
match &edited_comment {
|
||||
CommentStatus::Pending => {
|
||||
db_comment_pending.remove(&(
|
||||
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 => {
|
||||
dbs.comment_approved.remove(&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id,
|
||||
))?;
|
||||
}
|
||||
CommentStatus::ApprovedEdited(edited_comment) => {
|
||||
dbs.comment_pending.remove(&(
|
||||
ConflictableTransactionResult::<_>::Ok(None)
|
||||
})
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
pub fn remove_edit(comment_id: CommentId, dbs: &Dbs) -> Result<Option<Comment>, sled::Error> {
|
||||
Ok((&dbs.comment, &dbs.comment_pending)
|
||||
.transaction(|(db_comment, db_comment_pending)| {
|
||||
if let Some((comment, CommentStatus::ApprovedEdited(edited_comment))) =
|
||||
db_comment.get(&comment_id)?
|
||||
{
|
||||
db_comment_pending.remove(&(
|
||||
edited_comment.topic_hash.clone(),
|
||||
edited_comment.post_time,
|
||||
comment_id.clone(),
|
||||
))?;
|
||||
dbs.comment_approved.remove(&(
|
||||
comment.topic_hash.clone(),
|
||||
comment.post_time,
|
||||
comment_id,
|
||||
))?;
|
||||
db_comment.insert(&comment_id, &(comment.clone(), CommentStatus::Approved))?;
|
||||
return ConflictableTransactionResult::<_>::Ok(Some(comment));
|
||||
}
|
||||
}
|
||||
return Ok(Some((comment, edited_comment)));
|
||||
}
|
||||
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)
|
||||
ConflictableTransactionResult::<_>::Ok(None)
|
||||
})
|
||||
.unwrap())
|
||||
}
|
||||
|
||||
pub fn iter_comments_by_topic<'a, V: typed_sled::KV>(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue