Skip to content

Commit 3b3f64d

Browse files
committed
Cleanup ADatabase::begin and add tests
1 parent a396e8a commit 3b3f64d

4 files changed

Lines changed: 94 additions & 21 deletions

File tree

src/adatabase.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ bool ADatabase::isOpen() const
124124

125125
AExpectedResult beginHelper(const std::shared_ptr<ADriver> &d, QObject *receiver)
126126
{
127-
Q_ASSERT(d);
128127
AExpectedResult coro(receiver);
129128
d->begin(d, receiver, coro.ref());
130129
return coro;
@@ -136,11 +135,11 @@ AExpectedTransaction ADatabase::begin(QObject *receiver)
136135
AExpectedTransaction coro(receiver);
137136
[](auto chainData, ADatabase db, QObject *receiver) -> ACoroTerminator {
138137
auto result = co_await beginHelper(db.d, receiver);
139-
if (result.has_value()) {
140-
chainData->deliverDirect(ATransaction::fromStarted(db));
141-
} else {
142-
chainData->deliverDirect(std::unexpected(result.error()));
138+
if (result) {
139+
chainData->deliverDirect(ATransaction(db, true));
140+
co_return;
143141
}
142+
chainData->deliverDirect(std::unexpected(result.error()));
144143
}(coro.m_data, *this, receiver);
145144
return coro;
146145
}

src/atransaction.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,6 @@ ATransaction::ATransaction(const ADatabase &db, bool started)
4646
d->running = started;
4747
}
4848

49-
ATransaction ATransaction::fromStarted(const ADatabase &db)
50-
{
51-
return ATransaction(db, true);
52-
}
53-
5449
ATransaction::ATransaction(const ADatabase &db)
5550
: d(std::make_shared<ATransactionPrivate>(db))
5651
{

src/atransaction.h

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,6 @@ class ASQL_EXPORT ATransaction
3737
return *this;
3838
}
3939

40-
/*!
41-
* \brief fromStarted creates an ATransaction that is already in a started state.
42-
*
43-
* This factory is used internally when a BEGIN query has already been sent to the
44-
* database (e.g. by ADatabase::beginTransaction or APool::begin) and the transaction
45-
* object just needs to track that running state.
46-
*
47-
* \param db the database connection that issued BEGIN
48-
*/
49-
static ATransaction fromStarted(const ADatabase &db);
50-
5140
/*!
5241
* \brief commit a transaction only if our usage count equals 1
5342
*
@@ -77,6 +66,7 @@ class ASQL_EXPORT ATransaction
7766
[[nodiscard]] bool isActive() const;
7867

7968
private:
69+
friend class ADatabase;
8070
ATransaction(const ADatabase &db, bool started);
8171
std::shared_ptr<ATransactionPrivate> d;
8272
};

tests/sqlite_tst.cpp

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ private Q_SLOTS:
2727
void testQueries();
2828
void testPoolBeginCommit();
2929
void testPoolBeginRollback();
30+
void testDatabaseBeginCommit();
31+
void testDatabaseBeginRollback();
3032
};
3133

3234
void TestSqlite::initTest()
@@ -364,6 +366,93 @@ void TestSqlite::testPoolBeginRollback()
364366
loop.exec();
365367
}
366368

369+
void TestSqlite::testDatabaseBeginCommit()
370+
{
371+
QEventLoop loop;
372+
{
373+
auto finished = std::make_shared<QObject>();
374+
connect(finished.get(), &QObject::destroyed, &loop, &QEventLoop::quit);
375+
376+
auto dbBeginCommit = [finished]() -> ACoroTerminator {
377+
auto _ = qScopeGuard(
378+
[finished] { qDebug() << "dbBeginCommit exited" << finished.use_count(); });
379+
380+
auto db = co_await APool::database(nullptr, u"file"_s);
381+
AVERIFY(db);
382+
383+
auto create =
384+
co_await db->exec(u"CREATE TABLE IF NOT EXISTS db_commit_test (id INTEGER)"_s);
385+
AVERIFY(create);
386+
387+
auto t = co_await db->begin();
388+
AVERIFY(t);
389+
AVERIFY(t->isActive());
390+
391+
auto insert = co_await t->database().exec(u"INSERT INTO db_commit_test VALUES (1)"_s);
392+
AVERIFY(insert);
393+
ACOMPARE_EQ(insert->numRowsAffected(), qint64(1));
394+
395+
auto commitResult = co_await t->commit();
396+
AVERIFY(commitResult);
397+
AVERIFY(!commitResult->hasError());
398+
399+
auto verifyDb = co_await APool::database(nullptr, u"file"_s);
400+
AVERIFY(verifyDb);
401+
auto select = co_await verifyDb->exec(u"SELECT COUNT(*) FROM db_commit_test"_s);
402+
AVERIFY(select);
403+
ACOMPARE_EQ((*select)[0][0].toInt(), 1);
404+
405+
co_await verifyDb->exec(u"DROP TABLE db_commit_test"_s);
406+
};
407+
dbBeginCommit();
408+
}
409+
loop.exec();
410+
}
411+
412+
void TestSqlite::testDatabaseBeginRollback()
413+
{
414+
QEventLoop loop;
415+
{
416+
auto finished = std::make_shared<QObject>();
417+
connect(finished.get(), &QObject::destroyed, &loop, &QEventLoop::quit);
418+
419+
auto dbBeginRollback = [finished]() -> ACoroTerminator {
420+
auto _ = qScopeGuard(
421+
[finished] { qDebug() << "dbBeginRollback exited" << finished.use_count(); });
422+
423+
auto db = co_await APool::database(nullptr, u"file"_s);
424+
AVERIFY(db);
425+
426+
auto create =
427+
co_await db->exec(u"CREATE TABLE IF NOT EXISTS db_rollback_test (id INTEGER)"_s);
428+
AVERIFY(create);
429+
430+
auto t = co_await db->begin();
431+
AVERIFY(t);
432+
AVERIFY(t->isActive());
433+
434+
auto insert =
435+
co_await t->database().exec(u"INSERT INTO db_rollback_test VALUES (42)"_s);
436+
AVERIFY(insert);
437+
ACOMPARE_EQ(insert->numRowsAffected(), qint64(1));
438+
439+
auto rollbackResult = co_await t->rollback();
440+
AVERIFY(rollbackResult);
441+
AVERIFY(!rollbackResult->hasError());
442+
443+
auto verifyDb = co_await APool::database(nullptr, u"file"_s);
444+
AVERIFY(verifyDb);
445+
auto select = co_await verifyDb->exec(u"SELECT COUNT(*) FROM db_rollback_test"_s);
446+
AVERIFY(select);
447+
ACOMPARE_EQ((*select)[0][0].toInt(), 0);
448+
449+
co_await verifyDb->exec(u"DROP TABLE db_rollback_test"_s);
450+
};
451+
dbBeginRollback();
452+
}
453+
loop.exec();
454+
}
455+
367456
QTEST_MAIN(TestSqlite)
368457
#include "sqlite_tst.moc"
369458

0 commit comments

Comments
 (0)