mirror of
https://github.com/silverqx/TinyORM.git
synced 2026-05-08 09:59:23 -05:00
drivers get rid of passing weak_ptr<SqlDriver> 🙌
Used the std::enable_shared_from_this<MySqlDriver> base class to avoid passing the weak_ptr<SqlDriver> all around. It greatly simplified the code and also the logic is more correct. It also allowed to remove the SqlDatabase::driverWeak() non-const version which was dedicated exactly for this, to be able to pass it to methods that needed it, no more needed now.
This commit is contained in:
@@ -37,9 +37,7 @@ namespace Concerns
|
||||
|
||||
/* Others */
|
||||
/*! Select all columns in the given table with LIMIT 0 (used by record()). */
|
||||
SqlQuery
|
||||
selectAllColumnsWithLimit0(const QString &table,
|
||||
const std::weak_ptr<SqlDriver> &driver) const;
|
||||
SqlQuery selectAllColumnsWithLimit0(const QString &table) const;
|
||||
|
||||
private:
|
||||
/* Others */
|
||||
|
||||
@@ -125,8 +125,6 @@ namespace Orm::Drivers
|
||||
const SqlDriver *driver() const noexcept;
|
||||
/*! Get the SQL database driver used to access the database connection (const). */
|
||||
std::weak_ptr<const SqlDriver> driverWeak() const noexcept;
|
||||
/*! Get the SQL database driver used to access the database connection. */
|
||||
std::weak_ptr<SqlDriver> driverWeak() noexcept;
|
||||
|
||||
/*! Determine if the same thread check during the database() call is enabled. */
|
||||
static bool isThreadCheckEnabled() noexcept;
|
||||
|
||||
@@ -175,16 +175,12 @@ namespace Orm::Drivers
|
||||
IdentifierType type) const;
|
||||
|
||||
/*! Factory method to create an empty database result. */
|
||||
virtual std::unique_ptr<SqlResult>
|
||||
createResult(const std::weak_ptr<SqlDriver> &driver) const = 0;
|
||||
virtual std::unique_ptr<SqlResult> createResult() const = 0;
|
||||
|
||||
/*! Get a SqlRecord containing the field information for the given table. */
|
||||
virtual SqlRecord
|
||||
record(const QString &table, const std::weak_ptr<SqlDriver> &driver) const = 0;
|
||||
virtual SqlRecord record(const QString &table) const = 0;
|
||||
/*! Get a SqlRecord containing the field information for the given table. */
|
||||
virtual SqlRecord
|
||||
recordWithDefaultValues(const QString &table,
|
||||
const std::weak_ptr<SqlDriver> &driver) const = 0;
|
||||
virtual SqlRecord recordWithDefaultValues(const QString &table) const = 0;
|
||||
|
||||
protected:
|
||||
/* Setters */
|
||||
|
||||
@@ -19,12 +19,11 @@ namespace Orm::Drivers::Concerns
|
||||
/* public */
|
||||
|
||||
SqlQuery
|
||||
SelectsAllColumnsWithLimit0::selectAllColumnsWithLimit0(
|
||||
const QString &table, const std::weak_ptr<SqlDriver> &driver) const
|
||||
SelectsAllColumnsWithLimit0::selectAllColumnsWithLimit0(const QString &table) const
|
||||
{
|
||||
const auto &sqlDriver = this->sqlDriver();
|
||||
|
||||
SqlQuery query(sqlDriver.createResult(driver));
|
||||
SqlQuery query(sqlDriver.createResult());
|
||||
|
||||
/* Don't check if a table exists in the currently selected database because
|
||||
it doesn't make sense, leave the defaults on the database server.
|
||||
|
||||
@@ -284,18 +284,6 @@ std::weak_ptr<const SqlDriver> SqlDatabase::driverWeak() const noexcept
|
||||
return d->sqldriver;
|
||||
}
|
||||
|
||||
/* The reason why the driverWeak() non-const method is exposed only here and isn't also
|
||||
exposed in the Drivers::SqlQuery/SqlResult is to be able to instantiate the SqlQuery
|
||||
manually like this:
|
||||
const auto driver = SqlDatabase::database(Databases::MYSQL).driverWeak();
|
||||
SqlQuery query(driver.lock()->createResult(driver));
|
||||
*/
|
||||
|
||||
std::weak_ptr<SqlDriver> SqlDatabase::driverWeak() noexcept
|
||||
{
|
||||
return d->sqldriver;
|
||||
}
|
||||
|
||||
bool SqlDatabase::isThreadCheckEnabled() noexcept
|
||||
{
|
||||
return SqlDatabasePrivate::checkSameThread();
|
||||
@@ -358,9 +346,9 @@ SqlRecord SqlDatabase::record(const QString &table, const bool withDefaultValues
|
||||
This method will contain field information for ALL columns for the given table,
|
||||
but of course without the field values. */
|
||||
if (withDefaultValues)
|
||||
return d->driver().recordWithDefaultValues(table, d->sqldriver);
|
||||
return d->driver().recordWithDefaultValues(table);
|
||||
|
||||
return d->driver().record(table, d->sqldriver);
|
||||
return d->driver().record(table);
|
||||
}
|
||||
|
||||
/* private */
|
||||
|
||||
@@ -15,9 +15,7 @@ namespace Orm::Drivers
|
||||
SqlResultPrivate::SqlResultPrivate(const std::weak_ptr<SqlDriver> &driver) noexcept
|
||||
: sqldriver(driver)
|
||||
{
|
||||
/* The sqldriver must always be valid during construction, I'm leaving this check
|
||||
here even there is another check in the MySqlDriver::createResult() because
|
||||
the MySqlResult can still be instantiated manually. */
|
||||
// The sqldriver must always be valid/alive during instantiation
|
||||
Q_ASSERT(!sqldriver.expired());
|
||||
|
||||
// Ownership of the shared_ptr()
|
||||
|
||||
@@ -15,7 +15,9 @@ namespace Orm::Drivers::MySql
|
||||
class MySqlDriverPrivate;
|
||||
|
||||
/*! MySQL database driver. */
|
||||
class TINYDRIVERS_EXPORT MySqlDriver final : public SqlDriver
|
||||
class TINYDRIVERS_EXPORT MySqlDriver final :
|
||||
public SqlDriver,
|
||||
public std::enable_shared_from_this<MySqlDriver>
|
||||
{
|
||||
Q_DISABLE_COPY_MOVE(MySqlDriver)
|
||||
Q_DECLARE_PRIVATE(MySqlDriver) // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)
|
||||
@@ -71,16 +73,12 @@ namespace Orm::Drivers::MySql
|
||||
IdentifierType type) const final;
|
||||
|
||||
/*! Factory method to create an empty MySQL result. */
|
||||
std::unique_ptr<SqlResult>
|
||||
createResult(const std::weak_ptr<SqlDriver> &driver) const final;
|
||||
std::unique_ptr<SqlResult> createResult() const final;
|
||||
|
||||
/*! Get a SqlRecord containing the field information for the given table. */
|
||||
SqlRecord record(const QString &table,
|
||||
const std::weak_ptr<SqlDriver> &driver) const final;
|
||||
SqlRecord record(const QString &table) const final;
|
||||
/*! Get a SqlRecord containing the field information for the given table. */
|
||||
SqlRecord
|
||||
recordWithDefaultValues(const QString &table,
|
||||
const std::weak_ptr<SqlDriver> &driver) const final;
|
||||
SqlRecord recordWithDefaultValues(const QString &table) const final;
|
||||
};
|
||||
|
||||
/* public */
|
||||
|
||||
@@ -38,7 +38,7 @@ void PopulatesFieldDefaultValuesPrivate::populateFieldDefaultValuesInternal(
|
||||
// Ownership of the shared_ptr()
|
||||
const auto driver = sqldriver.lock();
|
||||
|
||||
SqlQuery sqlQuery(driver->createResult(sqldriver));
|
||||
SqlQuery sqlQuery(driver->createResult());
|
||||
|
||||
// Prepare the query string and field names based on the allColumns
|
||||
const auto [queryString, fieldNames] = prepareQueryStringAndFieldNames(
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "orm/drivers/mysql/mysqldriver.hpp"
|
||||
|
||||
#include <orm/macros/likely.hpp>
|
||||
|
||||
#include "orm/drivers/exceptions/invalidargumenterror.hpp"
|
||||
#include "orm/drivers/exceptions/logicerror.hpp"
|
||||
#include "orm/drivers/exceptions/sqltransactionerror.hpp"
|
||||
#include "orm/drivers/mysql/mysqlconstants_p.hpp"
|
||||
#include "orm/drivers/mysql/mysqldriver_p.hpp"
|
||||
@@ -223,42 +221,24 @@ bool MySqlDriver::isIdentifierEscaped(const QString &identifier,
|
||||
identifier.endsWith(BACKTICK);
|
||||
}
|
||||
|
||||
std::unique_ptr<SqlResult>
|
||||
MySqlDriver::createResult(const std::weak_ptr<SqlDriver> &driver) const
|
||||
std::unique_ptr<SqlResult> MySqlDriver::createResult() const
|
||||
{
|
||||
if (const auto driverShared = driver.lock(); driverShared) T_LIKELY
|
||||
/* We need to upcast here, there is no other way, it also has to be
|
||||
std::weak_ptr(), it can't be done better. This upcast is kind of check,
|
||||
we can't pass down the SqlDriver to the MySqlResult.
|
||||
Even if it would be the shared_ptr<SqlDriver> we had to upcast the same way.
|
||||
Revisited, also, all driver data members like host, port, username, ..., and
|
||||
also connectionName will be still the same, it only creates an empty result
|
||||
set. I'm noting this because of SqlQuery::clear() as it was confusing that
|
||||
all these data members stay unchanged, but it's correct. */
|
||||
return std::make_unique<MySqlResult>(
|
||||
std::dynamic_pointer_cast<MySqlDriver>(driverShared));
|
||||
|
||||
else T_UNLIKELY {
|
||||
Q_D(const MySqlDriver);
|
||||
|
||||
throw Exceptions::InvalidArgumentError(
|
||||
u"The 'driver' argument can't be nullptr, it can't be expired, "
|
||||
"for '%1' MySQL database connection in %2()."_s
|
||||
.arg(d->connectionName, __tiny_func__));
|
||||
}
|
||||
/* We must use the const_cast<> as the weak_from_this() return type is controlled
|
||||
by the current method const-nes, what means it's only our implementation detail
|
||||
as we can't control this. Also, it's better to have the same const-nes as
|
||||
in the QtSql. */
|
||||
return std::make_unique<MySqlResult>(
|
||||
const_cast<MySqlDriver &>(*this).weak_from_this()); // NOLINT(cppcoreguidelines-pro-type-const-cast)
|
||||
}
|
||||
|
||||
SqlRecord
|
||||
MySqlDriver::record(const QString &table, const std::weak_ptr<SqlDriver> &driver) const
|
||||
SqlRecord MySqlDriver::record(const QString &table) const
|
||||
{
|
||||
return selectAllColumnsWithLimit0(table, driver).record(false);
|
||||
return selectAllColumnsWithLimit0(table).record(false);
|
||||
}
|
||||
|
||||
SqlRecord
|
||||
MySqlDriver::recordWithDefaultValues(const QString &table,
|
||||
const std::weak_ptr<SqlDriver> &driver) const
|
||||
SqlRecord MySqlDriver::recordWithDefaultValues(const QString &table) const
|
||||
{
|
||||
return selectAllColumnsWithLimit0(table, driver).recordAllColumns(true);
|
||||
return selectAllColumnsWithLimit0(table).recordAllColumns(true);
|
||||
}
|
||||
|
||||
} // namespace Orm::Drivers::MySql
|
||||
|
||||
Reference in New Issue
Block a user