do not start inner transaction for transformation

throwing in an inner transaction will fail the entire transaction even if the
exception is caught in the outer transaction
This commit is contained in:
Daniel Gultsch 2023-03-21 22:01:34 +01:00
parent 4139c11771
commit 4fd96e740f
No known key found for this signature in database
GPG key ID: F43D18AD2A0982C2
3 changed files with 41 additions and 1 deletions

View file

@ -4,6 +4,7 @@ import static org.hamcrest.Matchers.*;
import androidx.test.core.app.ApplicationProvider; import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables; import com.google.common.collect.Iterables;
import im.conversations.android.database.model.Account; import im.conversations.android.database.model.Account;
import im.conversations.android.database.model.StanzaId; import im.conversations.android.database.model.StanzaId;
@ -143,6 +144,44 @@ public class ArchivePagingTest extends BaseTransformationTest {
MatcherAssert.assertThat(rangesSecondAttempt, contains(new Range(Range.Order.NORMAL, "6"))); MatcherAssert.assertThat(rangesSecondAttempt, contains(new Range(Range.Order.NORMAL, "6")));
} }
@Test
public void liveMessageQuerySubmitTwiceWithDuplicates()
throws ExecutionException, InterruptedException {
final var stub2 = new StubMessage(2);
transformer.transform(stub2.messageTransformation(), stub2.stanzaId());
final var ranges = database.archiveDao().resetLivePage(account(), ACCOUNT);
Assert.assertEquals(2, ranges.size());
MatcherAssert.assertThat(
ranges,
contains(new Range(Range.Order.REVERSE, "2"), new Range(Range.Order.NORMAL, "2")));
final var account = account();
final var transformer =
new Transformer(account, ApplicationProvider.getApplicationContext(), database);
transformer.transform(
Collections.emptyList(),
ACCOUNT,
new Range(Range.Order.REVERSE, "2"),
new ArchiveManager.QueryResult(true, Page.emptyWithCount("2", null)),
true);
transformer.transform(
ImmutableList.of(stub2.messageTransformation()),
ACCOUNT,
new Range(Range.Order.NORMAL, "2"),
new ArchiveManager.QueryResult(false, new Page("3", "4", 2)),
false);
transformer.transform(
Collections.emptyList(),
ACCOUNT,
new Range(Range.Order.NORMAL, "4"),
new ArchiveManager.QueryResult(true, new Page("5", "6", 2)),
false);
}
private Account account() throws ExecutionException, InterruptedException { private Account account() throws ExecutionException, InterruptedException {
return this.database.accountDao().getEnabledAccount(ACCOUNT).get(); return this.database.accountDao().getEnabledAccount(ACCOUNT).get();
} }

View file

@ -72,7 +72,6 @@ public abstract class MessageDao {
// it might return something that was previously a stub (message that only has reactions or // it might return something that was previously a stub (message that only has reactions or
// corrections but no original content). but in the process of invoking this method the stub // corrections but no original content). but in the process of invoking this method the stub
// will be upgraded to an original message (missing information filled in) // will be upgraded to an original message (missing information filled in)
@Transaction
public MessageIdentifier getOrCreateMessage( public MessageIdentifier getOrCreateMessage(
ChatIdentifier chatIdentifier, final MessageTransformation transformation) { ChatIdentifier chatIdentifier, final MessageTransformation transformation) {
final MessageIdentifier messageIdentifier = final MessageIdentifier messageIdentifier =

View file

@ -105,6 +105,8 @@ public class Transformer {
*/ */
private boolean transform( private boolean transform(
final ConversationsDatabase database, final MessageTransformation transformation) { final ConversationsDatabase database, final MessageTransformation transformation) {
Preconditions.checkState(
database.inTransaction(), "Transformations must be run from a transaction");
final var remote = transformation.remote; final var remote = transformation.remote;
final var messageType = transformation.type; final var messageType = transformation.type;
final var muc = transformation.getExtension(MucUser.class); final var muc = transformation.getExtension(MucUser.class);