Merge branch 'blog-txns' into 'master'

Add transactional versions of BlogManager methods and a bug fix

See merge request briar/briar!1802
This commit is contained in:
akwizgran
2023-07-13 20:30:21 +00:00
3 changed files with 61 additions and 39 deletions

View File

@@ -74,6 +74,13 @@ public interface BlogManager {
@Nullable String comment, BlogPostHeader parentHeader) @Nullable String comment, BlogPostHeader parentHeader)
throws DbException; throws DbException;
/**
* Adds a comment to an existing blog post or reblogs it.
*/
void addLocalComment(Transaction txn, LocalAuthor author,
GroupId groupId, @Nullable String comment,
BlogPostHeader parentHeader) throws DbException;
/** /**
* Returns the blog with the given ID. * Returns the blog with the given ID.
*/ */
@@ -99,6 +106,11 @@ public interface BlogManager {
*/ */
Collection<Blog> getBlogs() throws DbException; Collection<Blog> getBlogs() throws DbException;
/**
* Returns all blogs to which the user subscribes.
*/
Collection<Blog> getBlogs(Transaction txn) throws DbException;
/** /**
* Returns the group IDs of all blogs to which the user subscribes. * Returns the group IDs of all blogs to which the user subscribes.
*/ */
@@ -136,6 +148,11 @@ public interface BlogManager {
*/ */
void setReadFlag(MessageId m, boolean read) throws DbException; void setReadFlag(MessageId m, boolean read) throws DbException;
/**
* Marks a blog post as read or unread.
*/
void setReadFlag(Transaction txn, MessageId m, boolean read) throws DbException;
/** /**
* Registers a hook to be called whenever a blog is removed. * Registers a hook to be called whenever a blog is removed.
*/ */

View File

@@ -257,12 +257,19 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
public void addLocalComment(LocalAuthor author, GroupId groupId, public void addLocalComment(LocalAuthor author, GroupId groupId,
@Nullable String comment, BlogPostHeader parentHeader) @Nullable String comment, BlogPostHeader parentHeader)
throws DbException { throws DbException {
db.transaction(false, txn -> {
addLocalComment(txn, author, groupId, comment, parentHeader);
});
}
@Override
public void addLocalComment(Transaction txn, LocalAuthor author,
GroupId groupId, @Nullable String comment,
BlogPostHeader parentHeader) throws DbException {
MessageType type = parentHeader.getType(); MessageType type = parentHeader.getType();
if (type != POST && type != COMMENT) if (type != POST && type != COMMENT)
throw new IllegalArgumentException("Comment on unknown type!"); throw new IllegalArgumentException("Comment on unknown type!");
Transaction txn = db.startTransaction(false);
try { try {
// Wrap post that we are commenting on // Wrap post that we are commenting on
MessageId parentOriginalId = MessageId parentOriginalId =
@@ -281,6 +288,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
meta.put(KEY_ORIGINAL_PARENT_MSG_ID, parentOriginalId); meta.put(KEY_ORIGINAL_PARENT_MSG_ID, parentOriginalId);
meta.put(KEY_PARENT_MSG_ID, parentCurrentId); meta.put(KEY_PARENT_MSG_ID, parentCurrentId);
meta.put(KEY_AUTHOR, clientHelper.toList(author)); meta.put(KEY_AUTHOR, clientHelper.toList(author));
meta.put(KEY_READ, true);
// Send comment // Send comment
clientHelper.addLocalMessage(txn, message, meta, true, false); clientHelper.addLocalMessage(txn, message, meta, true, false);
@@ -290,13 +298,10 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
message.getId(), meta); message.getId(), meta);
BlogPostAddedEvent event = new BlogPostAddedEvent(groupId, h, true); BlogPostAddedEvent event = new BlogPostAddedEvent(groupId, h, true);
txn.attach(event); txn.attach(event);
db.commitTransaction(txn);
} catch (FormatException e) { } catch (FormatException e) {
throw new DbException(e); throw new DbException(e);
} catch (GeneralSecurityException e) { } catch (GeneralSecurityException e) {
throw new IllegalArgumentException("Invalid key of author", e); throw new IllegalArgumentException("Invalid key of author", e);
} finally {
db.endTransaction(txn);
} }
} }
@@ -429,18 +434,17 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
@Override @Override
public Collection<Blog> getBlogs() throws DbException { public Collection<Blog> getBlogs() throws DbException {
return db.transactionWithResult(true, this::getBlogs);
}
@Override
public Collection<Blog> getBlogs(Transaction txn) throws DbException {
try { try {
List<Blog> blogs = new ArrayList<>(); List<Blog> blogs = new ArrayList<>();
Collection<Group> groups; Collection<Group> groups =
Transaction txn = db.startTransaction(true); db.getGroups(txn, CLIENT_ID, MAJOR_VERSION);
try { for (Group g : groups) {
groups = db.getGroups(txn, CLIENT_ID, MAJOR_VERSION); blogs.add(blogFactory.parseBlog(g));
for (Group g : groups) {
blogs.add(blogFactory.parseBlog(g));
}
db.commitTransaction(txn);
} finally {
db.endTransaction(txn);
} }
return blogs; return blogs;
} catch (FormatException e) { } catch (FormatException e) {
@@ -555,10 +559,18 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
@Override @Override
public void setReadFlag(MessageId m, boolean read) throws DbException { public void setReadFlag(MessageId m, boolean read) throws DbException {
db.transaction(true, txn -> {
setReadFlag(txn, m, read);
});
}
@Override
public void setReadFlag(Transaction txn, MessageId m, boolean read)
throws DbException {
try { try {
BdfDictionary meta = new BdfDictionary(); BdfDictionary meta = new BdfDictionary();
meta.put(KEY_READ, read); meta.put(KEY_READ, read);
clientHelper.mergeMessageMetadata(m, meta); clientHelper.mergeMessageMetadata(txn, m, meta);
} catch (FormatException e) { } catch (FormatException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }

View File

@@ -20,6 +20,7 @@ import org.briarproject.bramble.api.sync.Group;
import org.briarproject.bramble.api.sync.Message; import org.briarproject.bramble.api.sync.Message;
import org.briarproject.bramble.api.sync.MessageId; import org.briarproject.bramble.api.sync.MessageId;
import org.briarproject.bramble.test.BrambleMockTestCase; import org.briarproject.bramble.test.BrambleMockTestCase;
import org.briarproject.bramble.test.DbExpectations;
import org.briarproject.briar.api.blog.Blog; import org.briarproject.briar.api.blog.Blog;
import org.briarproject.briar.api.blog.BlogCommentHeader; import org.briarproject.briar.api.blog.BlogCommentHeader;
import org.briarproject.briar.api.blog.BlogFactory; import org.briarproject.briar.api.blog.BlogFactory;
@@ -396,12 +397,12 @@ public class BlogManagerImplTest extends BrambleMockTestCase {
new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId), new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId),
new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, messageId), new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, messageId),
new BdfEntry(KEY_PARENT_MSG_ID, messageId), new BdfEntry(KEY_PARENT_MSG_ID, messageId),
new BdfEntry(KEY_AUTHOR, authorList1) new BdfEntry(KEY_AUTHOR, authorList1),
new BdfEntry(KEY_READ, true)
); );
context.checking(new Expectations() {{ context.checking(new DbExpectations() {{
oneOf(db).startTransaction(false); oneOf(db).transaction(with(false), withDbRunnable(txn));
will(returnValue(txn));
// Create the comment // Create the comment
oneOf(blogPostFactory).createBlogComment(blog1.getId(), oneOf(blogPostFactory).createBlogComment(blog1.getId(),
localAuthor1, comment, messageId, messageId); localAuthor1, comment, messageId, messageId);
@@ -422,8 +423,6 @@ public class BlogManagerImplTest extends BrambleMockTestCase {
will(returnValue(localAuthor1)); will(returnValue(localAuthor1));
oneOf(authorManager).getAuthorInfo(txn, localAuthor1.getId()); oneOf(authorManager).getAuthorInfo(txn, localAuthor1.getId());
will(returnValue(ourselvesInfo)); will(returnValue(ourselvesInfo));
oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn);
}}); }});
BlogPostHeader postHeader = new BlogPostHeader(POST, blog1.getId(), BlogPostHeader postHeader = new BlogPostHeader(POST, blog1.getId(),
@@ -492,12 +491,12 @@ public class BlogManagerImplTest extends BrambleMockTestCase {
new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId), new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId),
new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, messageId), new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, messageId),
new BdfEntry(KEY_PARENT_MSG_ID, wrappedPostId), new BdfEntry(KEY_PARENT_MSG_ID, wrappedPostId),
new BdfEntry(KEY_AUTHOR, authorList2) new BdfEntry(KEY_AUTHOR, authorList2),
new BdfEntry(KEY_READ, true)
); );
context.checking(new Expectations() {{ context.checking(new DbExpectations() {{
oneOf(db).startTransaction(false); oneOf(db).transaction(with(false), withDbRunnable(txn));
will(returnValue(txn));
// Wrap the original post for blog 2 // Wrap the original post for blog 2
oneOf(clientHelper).getMessageAsList(txn, messageId); oneOf(clientHelper).getMessageAsList(txn, messageId);
will(returnValue(originalPostBody)); will(returnValue(originalPostBody));
@@ -533,8 +532,6 @@ public class BlogManagerImplTest extends BrambleMockTestCase {
will(returnValue(localAuthor1)); will(returnValue(localAuthor1));
oneOf(authorManager).getAuthorInfo(txn, localAuthor1.getId()); oneOf(authorManager).getAuthorInfo(txn, localAuthor1.getId());
will(returnValue(verifiedInfo)); will(returnValue(verifiedInfo));
oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn);
}}); }});
BlogPostHeader originalPostHeader = new BlogPostHeader(POST, BlogPostHeader originalPostHeader = new BlogPostHeader(POST,
@@ -603,12 +600,12 @@ public class BlogManagerImplTest extends BrambleMockTestCase {
new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId), new BdfEntry(KEY_ORIGINAL_MSG_ID, commentId),
new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, rssMessageId), new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, rssMessageId),
new BdfEntry(KEY_PARENT_MSG_ID, wrappedPostId), new BdfEntry(KEY_PARENT_MSG_ID, wrappedPostId),
new BdfEntry(KEY_AUTHOR, authorList1) new BdfEntry(KEY_AUTHOR, authorList1),
new BdfEntry(KEY_READ, true)
); );
context.checking(new Expectations() {{ context.checking(new DbExpectations() {{
oneOf(db).startTransaction(false); oneOf(db).transaction(with(false), withDbRunnable(txn));
will(returnValue(txn));
// Wrap the original post for blog 1 // Wrap the original post for blog 1
oneOf(clientHelper).getMessageAsList(txn, rssMessageId); oneOf(clientHelper).getMessageAsList(txn, rssMessageId);
will(returnValue(originalPostBody)); will(returnValue(originalPostBody));
@@ -642,8 +639,6 @@ public class BlogManagerImplTest extends BrambleMockTestCase {
will(returnValue(wrappedPostMeta)); will(returnValue(wrappedPostMeta));
oneOf(clientHelper).parseAndValidateAuthor(rssAuthorList); oneOf(clientHelper).parseAndValidateAuthor(rssAuthorList);
will(returnValue(rssLocalAuthor)); will(returnValue(rssLocalAuthor));
oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn);
}}); }});
BlogPostHeader originalPostHeader = new BlogPostHeader(POST, BlogPostHeader originalPostHeader = new BlogPostHeader(POST,
@@ -728,12 +723,12 @@ public class BlogManagerImplTest extends BrambleMockTestCase {
new BdfEntry(KEY_ORIGINAL_MSG_ID, localCommentId), new BdfEntry(KEY_ORIGINAL_MSG_ID, localCommentId),
new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, originalCommentId), new BdfEntry(KEY_ORIGINAL_PARENT_MSG_ID, originalCommentId),
new BdfEntry(KEY_PARENT_MSG_ID, wrappedCommentId), new BdfEntry(KEY_PARENT_MSG_ID, wrappedCommentId),
new BdfEntry(KEY_AUTHOR, authorList2) new BdfEntry(KEY_AUTHOR, authorList2),
new BdfEntry(KEY_READ, true)
); );
context.checking(new Expectations() {{ context.checking(new DbExpectations() {{
oneOf(db).startTransaction(false); oneOf(db).transaction(with(false), withDbRunnable(txn));
will(returnValue(txn));
// Rewrap the wrapped post for blog 2 // Rewrap the wrapped post for blog 2
oneOf(clientHelper).getMessageAsList(txn, wrappedPostId); oneOf(clientHelper).getMessageAsList(txn, wrappedPostId);
will(returnValue(wrappedPostBody)); will(returnValue(wrappedPostBody));
@@ -790,8 +785,6 @@ public class BlogManagerImplTest extends BrambleMockTestCase {
will(returnValue(rewrappedPostMeta)); will(returnValue(rewrappedPostMeta));
oneOf(clientHelper).parseAndValidateAuthor(rssAuthorList); oneOf(clientHelper).parseAndValidateAuthor(rssAuthorList);
will(returnValue(rssLocalAuthor)); will(returnValue(rssLocalAuthor));
oneOf(db).commitTransaction(txn);
oneOf(db).endTransaction(txn);
}}); }});
BlogPostHeader wrappedPostHeader = new BlogPostHeader(WRAPPED_POST, BlogPostHeader wrappedPostHeader = new BlogPostHeader(WRAPPED_POST,