summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2023-08-23 00:26:20 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2023-08-23 00:26:20 +0100
commitbbae6d83c6d7ea25f17965fd68062f0cab3da5e4 (patch)
tree8772d1ca67a37cb50192f51fd32256c6fc0a056b
parentAdd a copying to_lower wrapper (diff)
downloadslicer-bbae6d83c6d7ea25f17965fd68062f0cab3da5e4.tar.bz2
slicer-bbae6d83c6d7ea25f17965fd68062f0cab3da5e4.tar.xz
slicer-bbae6d83c6d7ea25f17965fd68062f0cab3da5e4.zip
Cache the Hook name/column relation for non-subclass multi-row selects
-rw-r--r--slicer/db/sqlSelectDeserializer.cpp78
-rw-r--r--slicer/db/sqlSelectDeserializer.h13
2 files changed, 72 insertions, 19 deletions
diff --git a/slicer/db/sqlSelectDeserializer.cpp b/slicer/db/sqlSelectDeserializer.cpp
index e11493e..8081d76 100644
--- a/slicer/db/sqlSelectDeserializer.cpp
+++ b/slicer/db/sqlSelectDeserializer.cpp
@@ -5,6 +5,7 @@
#include <memory>
#include <selectcommand.h>
#include <slicer/common.h>
+#include <slicer/hookMap.h>
#include <slicer/modelParts.h>
#include <utility>
@@ -59,9 +60,52 @@ namespace Slicer {
}
void
+ SqlSelectDeserializer::fillLowerColumnNameCache()
+ {
+ BOOST_ASSERT(lowerColumnNames.empty());
+ lowerColumnNames.reserve(columnCount);
+ orderedColumns.reserve(columnCount);
+ for (auto col = 0U; col < columnCount; col += 1) {
+ const DB::Column & c = (*cmd)[col];
+ lowerColumnNames.emplace_back(to_lower_copy(c.name));
+ }
+ }
+
+ const DB::Column *
+ SqlSelectDeserializer::searchOrFilleColumnCache(size_t idx, const HookCommon * hook)
+ {
+ if (idx < orderedColumns.size()) {
+ return orderedColumns[idx];
+ }
+ BOOST_ASSERT(idx == orderedColumns.size());
+ if (const auto itr = std::find(lowerColumnNames.begin(), lowerColumnNames.end(), hook->nameLower);
+ itr != lowerColumnNames.end()) {
+ return orderedColumns.emplace_back(&(*cmd)[static_cast<unsigned int>(itr - lowerColumnNames.begin())]);
+ }
+ else {
+ return orderedColumns.emplace_back(nullptr);
+ }
+ }
+
+ namespace {
+ void
+ assignFromColumn(ModelPartParam fmp, const DB::Column & c)
+ {
+ BOOST_ASSERT(fmp);
+ BOOST_ASSERT(!c.isNull());
+ fmp->Create();
+ fmp->SetValue(SqlSource(c));
+ fmp->Complete();
+ }
+ }
+
+ void
SqlSelectDeserializer::DeserializeSequence(ModelPartParam omp)
{
omp->OnAnonChild([this](auto && mp, auto &&) {
+ if (!typeIdColIdx && lowerColumnNames.empty()) {
+ fillLowerColumnNameCache();
+ }
while (cmd->fetch()) {
DeserializeRow(mp);
}
@@ -92,20 +136,26 @@ namespace Slicer {
case Slicer::ModelPartType::Complex: {
auto apply = [this](auto && rcmp) {
rcmp->Create();
- for (auto col = 0U; col < columnCount; col += 1) {
- const DB::Column & c = (*cmd)[col];
- if (!c.isNull()) {
- rcmp->OnChild(
- [&c](auto && fmp, auto &&) {
- if (fmp) {
- fmp->Create();
- fmp->SetValue(SqlSource(c));
- fmp->Complete();
- }
- },
- c.name, nullptr, false);
+ if (typeIdColIdx || lowerColumnNames.empty()) {
+ for (auto col = 0U; col < columnCount; col += 1) {
+ const DB::Column & c = (*cmd)[col];
+ if (!c.isNull()) {
+ rcmp->OnChild(
+ [&c](auto && fmp, auto &&) {
+ assignFromColumn(fmp, c);
+ },
+ c.name, nullptr, false);
+ }
}
}
+ else {
+ rcmp->OnEachChild([idx = 0U, this](auto &&, auto && fmp, auto && hook) mutable {
+ if (auto c = searchOrFilleColumnCache(idx, hook); c && !c->isNull()) {
+ assignFromColumn(fmp, *c);
+ }
+ ++idx;
+ });
+ }
rcmp->Complete();
};
if (typeIdColIdx) {
@@ -116,12 +166,10 @@ namespace Slicer {
apply(rmp);
} break;
case Slicer::ModelPartType::Simple: {
- rmp->Create();
const DB::Column & c = (*cmd)[0];
if (!c.isNull()) {
- rmp->SetValue(SqlSource(c));
+ assignFromColumn(rmp, c);
}
- rmp->Complete();
} break;
default:
throw UnsupportedModelType();
diff --git a/slicer/db/sqlSelectDeserializer.h b/slicer/db/sqlSelectDeserializer.h
index f8fce08..b911fb1 100644
--- a/slicer/db/sqlSelectDeserializer.h
+++ b/slicer/db/sqlSelectDeserializer.h
@@ -9,6 +9,7 @@
namespace DB {
class SelectCommand;
+ class Column;
}
namespace Slicer {
@@ -20,15 +21,19 @@ namespace Slicer {
void Deserialize(ModelPartForRootParam) override;
protected:
- void DLL_PRIVATE DeserializeSimple(ModelPartParam);
- void DLL_PRIVATE DeserializeObject(ModelPartParam);
- void DLL_PRIVATE DeserializeSequence(ModelPartParam);
- void DLL_PRIVATE DeserializeRow(ModelPartParam);
+ DLL_PRIVATE void DeserializeSimple(ModelPartParam);
+ DLL_PRIVATE void DeserializeObject(ModelPartParam);
+ DLL_PRIVATE void DeserializeSequence(ModelPartParam);
+ DLL_PRIVATE void DeserializeRow(ModelPartParam);
+ DLL_PRIVATE void fillLowerColumnNameCache();
+ DLL_PRIVATE inline const DB::Column * searchOrFilleColumnCache(size_t idx, const HookCommon * hook);
DB::SelectCommand * cmd;
unsigned int columnCount;
std::optional<std::string> typeIdColName;
std::optional<unsigned int> typeIdColIdx;
+ std::vector<std::string> lowerColumnNames;
+ std::vector<const DB::Column *> orderedColumns;
};
}