drivers extracted SqlRecord cache to own class

- added a nice API
This commit is contained in:
silverqx
2024-07-20 12:35:34 +02:00
parent c90c5c1298
commit d29050293a
5 changed files with 121 additions and 9 deletions
+1
View File
@@ -23,6 +23,7 @@ function(tinydrivers_sources out_headers_private out_headers out_sources)
sqlresult_p.hpp
support/connectionshash_p.hpp
support/sqldriverfactory_p.hpp
support/sqlrecordcache_p.hpp
utils/type_p.hpp
)
@@ -18,6 +18,7 @@ headersList += \
$$PWD/orm/drivers/sqlresult_p.hpp \
$$PWD/orm/drivers/support/connectionshash_p.hpp \
$$PWD/orm/drivers/support/sqldriverfactory_p.hpp \
$$PWD/orm/drivers/support/sqlrecordcache_p.hpp \
$$PWD/orm/drivers/utils/type_p.hpp \
HEADERS += $$sorted(headersList)
@@ -0,0 +1,109 @@
#pragma once
#ifndef ORM_DRIVERS_SUPPORT_SQLRECORDCACHE_P_HPP
#define ORM_DRIVERS_SUPPORT_SQLRECORDCACHE_P_HPP
#include "orm/drivers/sqlrecord.hpp"
TINYORM_BEGIN_COMMON_NAMESPACE
namespace Orm::Drivers::Support
{
/*! Cache for the record/WithDefaultValues() methods (SqlRecord). */
struct SqlRecordCachePrivate
{
/*! Cached SqlRecord instance. */
std::optional<SqlRecord> cache = std::nullopt;
/*! Determince whether the cached SqlRecord contains Default Column Values. */
bool hasDefaultValues = false;
/*! Determine if a SqlRecord is cached. */
constexpr bool has() const noexcept;
/*! Determine if a SqlRecord is cached. */
constexpr explicit operator bool() const noexcept;
/*! Retrieve a SqlRecord from the cache. */
constexpr SqlRecord &get() noexcept;
/*! Retrieve a SqlRecord from the cache, const version. */
constexpr const SqlRecord &get() const noexcept;
/*! Retrieve a SqlRecord from the cache. */
constexpr SqlRecord &operator*() noexcept;
/*! Retrieve a SqlRecord from the cache, const version. */
constexpr const SqlRecord &operator*() const noexcept;
/*! Store the given SqlRecord in the cache. */
constexpr SqlRecord &put(SqlRecord &&record, bool defaultValues) noexcept;
/*! Store the given SqlRecord in the cache (helper method only). */
constexpr SqlRecord &put(SqlRecord &record, bool defaultValues) noexcept;
/*! Clear the cache. */
constexpr void clear() noexcept;
};
/* public */
constexpr bool SqlRecordCachePrivate::has() const noexcept
{
return cache.has_value();
}
constexpr SqlRecordCachePrivate::operator bool() const noexcept
{
return cache.has_value();
}
constexpr SqlRecord &SqlRecordCachePrivate::get() noexcept
{
return *cache;
}
constexpr const SqlRecord &SqlRecordCachePrivate::get() const noexcept
{
return *cache;
}
constexpr SqlRecord &SqlRecordCachePrivate::operator*() noexcept
{
return *cache;
}
constexpr const SqlRecord &SqlRecordCachePrivate::operator*() const noexcept
{
return *cache;
}
constexpr SqlRecord &
SqlRecordCachePrivate::put(SqlRecord &&record, const bool defaultValues) noexcept
{
cache = std::move(record);
hasDefaultValues = defaultValues;
return *cache;
}
constexpr SqlRecord &
SqlRecordCachePrivate::put(SqlRecord &record, const bool defaultValues) noexcept
{
/* This is only a helper method to have a nicer code, it allows to call the return
statement like: return cache.put(SqlRecord &). In this case the given SqlRecord
must have the same memory address as the current cached SqlRecord.
Used with: populateFieldDefaultValues(d->recordCache.get()) */
Q_ASSERT(std::addressof(record) == std::addressof(*cache));
hasDefaultValues = defaultValues;
return record;
}
constexpr void SqlRecordCachePrivate::clear() noexcept
{
cache.reset();
hasDefaultValues = false;
}
} // namespace Orm::Drivers::Support
TINYORM_END_COMMON_NAMESPACE
#endif // ORM_DRIVERS_SUPPORT_SQLRECORDCACHE_P_HPP
@@ -5,8 +5,8 @@
#include "orm/drivers/macros/declaresqldriverprivate_p.hpp"
#include "orm/drivers/mysql/mysqldriver.hpp"
#include "orm/drivers/mysql/mysqltypes_p.hpp"
#include "orm/drivers/sqlrecord.hpp"
#include "orm/drivers/sqlresult_p.hpp"
#include "orm/drivers/support/sqlrecordcache_p.hpp"
/* All the in vs out bindings/data-related comments and identifier names related
to the results or prepared bindings are described from the MySQL server perspective and
@@ -120,8 +120,8 @@ namespace Orm::Drivers::MySql
/*! Is the current result set for the prepared statement? */
bool preparedQuery = false;
/*! Cache for the record() method. */
mutable std::optional<SqlRecord> recordCache = std::nullopt;
/*! Cache for the record/WithDefaultValuesCached() method. */
mutable Support::SqlRecordCachePrivate recordCache;
private:
/* Prepared queries */
@@ -145,7 +145,7 @@ bool MySqlResult::exec()
"to the SqlQuery::exec(QString) for normal statements, for '%1' MySQL "
"database connection in %2()."_s.arg(d->connectionName, __tiny_func__));
d->recordCache.reset();
d->recordCache.clear();
/* Prepared queries don't use metadata the same way as normal queries,
it's always RESULTSET_METADATA_NONE. */
@@ -292,7 +292,8 @@ const SqlRecord &MySqlResult::recordCached() const
{
Q_D(const MySqlResult);
return d->recordCache ? *d->recordCache : *(d->recordCache = record());
return d->recordCache ? *d->recordCache
: d->recordCache.put(record(), false);
}
QVariant MySqlResult::lastInsertId() const
@@ -337,7 +338,7 @@ bool MySqlResult::fetch(const size_type index)
if (at() == index)
return true;
d->recordCache.reset();
d->recordCache.clear();
// Fetch the next row in the result set
if (d->preparedQuery) {
@@ -396,7 +397,7 @@ bool MySqlResult::fetchNext()
if (size() == 0)
return false;
d->recordCache.reset();
d->recordCache.clear();
// Fetch the next row in the result set
if (d->preparedQuery) {
@@ -501,7 +502,7 @@ void MySqlResult::cleanupForNormal()
{
Q_D(MySqlResult);
d->recordCache.reset();
d->recordCache.clear();
// Normal queries
mysqlFreeResults();
@@ -514,7 +515,7 @@ void MySqlResult::cleanupForPrepared()
{
Q_D(MySqlResult);
d->recordCache.reset();
d->recordCache.clear();
// Prepared queries
// d->meta != nullptr check is inside as the first thing