Skip to content

Commit dd96a11

Browse files
committed
Unit test for connection holder internals
1 parent 5fb2e3c commit dd96a11

File tree

3 files changed

+103
-3
lines changed

3 files changed

+103
-3
lines changed

dev/connection_holder.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#include <sqlite3.h>
44
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
5-
#include <atomic>
5+
#include <atomic> // memory order flags
66
#ifdef SQLITE_ORM_CPP20_SEMAPHORE_SUPPORTED
77
#include <semaphore>
88
#endif
@@ -68,6 +68,7 @@ namespace sqlite_orm {
6868
_didOpenDb{std::move(didOpenDb)} {}
6969

7070
connection_holder(const connection_holder&) = delete;
71+
connection_holder& operator=(const connection_holder&) = delete;
7172

7273
connection_holder(const connection_holder& other, std::function<void(sqlite3*)> didOpenDb) :
7374
_control{.openedForeverHint = other._control.openedForeverHint}, dbArgs{other.dbArgs},
@@ -165,6 +166,7 @@ namespace sqlite_orm {
165166
_didOpenDb{std::move(didOpenDb)} {}
166167

167168
connection_holder(const connection_holder&) = delete;
169+
connection_holder& operator=(const connection_holder&) = delete;
168170

169171
connection_holder(const connection_holder& other, std::function<void(sqlite3*)> didOpenDb) :
170172
_control{}, dbArgs{other.dbArgs}, _didOpenDb{std::move(didOpenDb)} {}

include/sqlite_orm/sqlite_orm.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14470,7 +14470,7 @@ namespace sqlite_orm {
1447014470

1447114471
#include <sqlite3.h>
1447214472
#ifndef SQLITE_ORM_IMPORT_STD_MODULE
14473-
#include <atomic>
14473+
#include <atomic> // memory order flags
1447414474
#ifdef SQLITE_ORM_CPP20_SEMAPHORE_SUPPORTED
1447514475
#include <semaphore>
1447614476
#endif
@@ -14680,6 +14680,7 @@ namespace sqlite_orm {
1468014680
_didOpenDb{std::move(didOpenDb)} {}
1468114681

1468214682
connection_holder(const connection_holder&) = delete;
14683+
connection_holder& operator=(const connection_holder&) = delete;
1468314684

1468414685
connection_holder(const connection_holder& other, std::function<void(sqlite3*)> didOpenDb) :
1468514686
_control{.openedForeverHint = other._control.openedForeverHint}, dbArgs{other.dbArgs},
@@ -14777,6 +14778,7 @@ namespace sqlite_orm {
1477714778
_didOpenDb{std::move(didOpenDb)} {}
1477814779

1477914780
connection_holder(const connection_holder&) = delete;
14781+
connection_holder& operator=(const connection_holder&) = delete;
1478014782

1478114783
connection_holder(const connection_holder& other, std::function<void(sqlite3*)> didOpenDb) :
1478214784
_control{}, dbArgs{other.dbArgs}, _didOpenDb{std::move(didOpenDb)} {}

tests/storage_tests.cpp

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,106 @@
1+
#include <memory> // std::unique_ptr, std::make_unique
12
#include <cstdint>
23
#include <sqlite_orm/sqlite_orm.h>
34
#include <catch2/catch_all.hpp>
45

56
using namespace sqlite_orm;
67

7-
TEST_CASE("connection control") {
8+
TEST_CASE("connection holder tests") {
9+
using namespace sqlite_orm::internal;
10+
11+
const bool openForever = GENERATE(false, true);
12+
SECTION("") {
13+
std::unique_ptr<connection_holder> connection;
14+
connection = std::make_unique<connection_holder>(
15+
"",
16+
// openForever==false: test whether executed under the lock when opening repeatedly
17+
// openForever==true: test whether no lock is held when opening permanently
18+
[&connection, openForever](sqlite3* db) {
19+
// alias
20+
auto& controlBlock = connection->_control;
21+
22+
REQUIRE(controlBlock.db == db);
23+
24+
REQUIRE(controlBlock.retainCount == 1);
25+
#ifdef SQLITE_ORM_CPP20_SEMAPHORE_SUPPORTED
26+
REQUIRE(controlBlock.openedForeverHint == openForever);
27+
REQUIRE(connection_holder::maybe_lock::nRecursionsPerThread == (openForever ? 0 : 1));
28+
REQUIRE(controlBlock.sync.try_acquire() == openForever);
29+
// RAII
30+
controlBlock.sync.release(openForever ? 1 : 0);
31+
#endif
32+
33+
#ifdef SQLITE_ORM_CPP20_SEMAPHORE_SUPPORTED
34+
// test `maybe_lock` - re-entrance at the lowest level
35+
{
36+
const connection_holder::maybe_lock ml{controlBlock.sync, !openForever};
37+
REQUIRE(&ml.sync == &controlBlock.sync);
38+
REQUIRE(ml.isSynced == !openForever);
39+
REQUIRE(connection_holder::maybe_lock::nRecursionsPerThread == (openForever ? 0 : 2));
40+
REQUIRE(ml.sync.try_acquire() == openForever);
41+
ml.sync.release(openForever ? 1 : 0);
42+
}
43+
// ... after destruction
44+
{
45+
REQUIRE(connection_holder::maybe_lock::nRecursionsPerThread == (openForever ? 0 : 1));
46+
REQUIRE(controlBlock.sync.try_acquire() == openForever);
47+
// RAII
48+
controlBlock.sync.release(openForever ? 1 : 0);
49+
}
50+
#endif
51+
52+
// test re-entrance
53+
connection->retain();
54+
{
55+
REQUIRE(controlBlock.retainCount == 2);
56+
#ifdef SQLITE_ORM_CPP20_SEMAPHORE_SUPPORTED
57+
REQUIRE(connection_holder::maybe_lock::nRecursionsPerThread == (openForever ? 0 : 1));
58+
REQUIRE(controlBlock.sync.try_acquire() == openForever);
59+
// RAII
60+
controlBlock.sync.release(openForever ? 1 : 0);
61+
#endif
62+
}
63+
64+
connection->release();
65+
{
66+
REQUIRE(controlBlock.retainCount == 1);
67+
#ifdef SQLITE_ORM_CPP20_SEMAPHORE_SUPPORTED
68+
REQUIRE(controlBlock.openedForeverHint == openForever);
69+
REQUIRE(connection_holder::maybe_lock::nRecursionsPerThread == (openForever ? 0 : 1));
70+
REQUIRE(controlBlock.sync.try_acquire() == openForever);
71+
// RAII
72+
controlBlock.sync.release(openForever ? 1 : 0);
73+
#endif
74+
}
75+
},
76+
connection_control{openForever});
77+
78+
// alias
79+
auto& controlBlock = connection->_control;
80+
81+
connection->retain();
82+
{
83+
REQUIRE(controlBlock.retainCount == 1);
84+
#ifdef SQLITE_ORM_CPP20_SEMAPHORE_SUPPORTED
85+
REQUIRE(connection_holder::maybe_lock::nRecursionsPerThread == 0);
86+
REQUIRE(controlBlock.sync.try_acquire());
87+
// RAII
88+
controlBlock.sync.release();
89+
#endif
90+
}
91+
92+
connection->release();
93+
{
94+
REQUIRE(controlBlock.db == nullptr);
95+
REQUIRE(controlBlock.retainCount == 0);
96+
#ifdef SQLITE_ORM_CPP20_SEMAPHORE_SUPPORTED
97+
REQUIRE(connection_holder::maybe_lock::nRecursionsPerThread == 0);
98+
#endif
99+
}
100+
}
101+
}
102+
103+
TEST_CASE("connection control tests") {
8104
const auto openForever = GENERATE(false, true);
9105
SECTION("") {
10106
bool onOpenCalled = false;

0 commit comments

Comments
 (0)