Skip to content

Commit

Permalink
Made transaction MSVC-compatible
Browse files Browse the repository at this point in the history
MSVC didn't like the use of `borrowed_writeable_database` in the
header when `pool` hadn't been defined yet.
  • Loading branch information
snej committed May 2, 2024
1 parent 67383d6 commit 63ff2b3
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 12 deletions.
6 changes: 4 additions & 2 deletions include/sqnice/pool.hh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ namespace sqnice {


/** A thread-safe pool of databases, for multi-threaded use. */
class pool {
class pool : noncopyable {
public:
/// Constructs a pool that will manage databases on the given file.
/// No databases are opened until one of the borrow methods is called,
Expand All @@ -62,7 +62,7 @@ namespace sqnice {
const char* _Nullable vfs = nullptr);

/// `pool`'s destructor waits until all borrowed databases have been returned.
~pool() {close_all();}
~pool();

/// The maximum number of databases the pool will create, including one writeable one.
/// Defaults to 5. Minimum value is 2 (otherwise why are you using a pool at all?)
Expand Down Expand Up @@ -117,6 +117,8 @@ namespace sqnice {
friend borrowed_database;
friend borrowed_writeable_database;

pool(pool&&) = delete;
pool& operator=(pool&&) = delete;
borrowed_database borrow(bool);
borrowed_writeable_database borrow_writeable(bool);
std::unique_ptr<database> new_db(bool writeable);
Expand Down
2 changes: 1 addition & 1 deletion include/sqnice/transaction.hh
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ namespace sqnice {
private:
status end(bool commit);

std::optional<std::unique_ptr<database, pool&>> borrowed_db_;
database* _Nullable db_ = nullptr;
pool* _Nullable from_pool_ = nullptr;
bool autocommit_ = false;
};

Expand Down
5 changes: 5 additions & 0 deletions src/pool.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ namespace sqnice {
}


pool::~pool() {
close_all();
}


unsigned pool::capacity() {
unique_lock lock(_mutex);
return _ro_capacity + 1; // public API includes writeable db in capacity
Expand Down
30 changes: 21 additions & 9 deletions src/transaction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,19 @@ namespace sqnice {
db.raise(rc); // always throw -- constructor cannot return a status
}

transaction::transaction(pool& pool, bool autocommit, bool immediate)
:borrowed_db_(pool.borrow_writeable())
{
status rc = begin(*borrowed_db_->get(), autocommit, immediate);
transaction::transaction(pool& pool, bool autocommit, bool immediate) {
status rc = begin(pool, autocommit, immediate);
if (!ok(rc)) [[unlikely]]
(*borrowed_db_)->raise(rc); // always throw -- constructor cannot return a status
checking::raise(rc, "can't begin transaction"); // always throw -- constructor cannot return a status
}

transaction::transaction(transaction &&t) noexcept
:borrowed_db_(std::move(t.borrowed_db_))
,db_(t.db_)
:db_(t.db_)
,from_pool_(t.from_pool_)
,autocommit_(t.autocommit_)
{
t.db_ = nullptr;
t.from_pool_ = nullptr;
}

status transaction::begin(database& db, bool autocommit, bool immediate) {
Expand All @@ -75,15 +74,23 @@ namespace sqnice {
}

status transaction::begin(pool& pool, bool autocommit, bool immediate) {
if (db_) [[unlikely]]
throw std::logic_error("transaction is already active");
auto db = pool.borrow_writeable();
status rc = begin(*db, autocommit, immediate);
if (ok(rc))
borrowed_db_.emplace(std::move(db));
if (ok(rc)) {
from_pool_ = &db.get_deleter();
db_ = db.release();
}
return rc;
}

transaction::~transaction() {
if (db_) {
optional<borrowed_writeable_database> bdb;
if (from_pool_)
bdb.emplace(db_, *from_pool_); // will be returned to pool on exit

if (autocommit_ && !current_exception()) {
// It is legal (though discouraged) to throw an exception from a destructor,
// as long as the destructor was not called as part of unwinding the stack
Expand All @@ -108,6 +115,11 @@ namespace sqnice {

status transaction::end(bool commit) {
if (auto db = db_) [[likely]] {
optional<borrowed_writeable_database> bdb; // will be returned to pool on exit
if (from_pool_) {
bdb.emplace(db_, *from_pool_);
from_pool_ = nullptr;
}
db_ = nullptr;
return db->end_transaction(commit);
} else if (commit) {
Expand Down
7 changes: 7 additions & 0 deletions test/testdb.cc
Original file line number Diff line number Diff line change
Expand Up @@ -191,4 +191,11 @@ TEST_CASE("SQNice pool", "[sqnice]") {
CHECK(p.borrowed_count() == 3);
auto db5 = p.borrow();
CHECK(p.borrowed_count() == 4);

{
sqnice::transaction txn(p);
CHECK(p.borrowed_count() == 5);
CHECK(p.try_borrow_writeable() == nullptr);
}
CHECK(p.borrowed_count() == 4);
}

0 comments on commit 63ff2b3

Please sign in to comment.