diff --git a/include/orm/ormconcepts.hpp b/include/orm/ormconcepts.hpp index 2bcebe515..c7ea734f5 100644 --- a/include/orm/ormconcepts.hpp +++ b/include/orm/ormconcepts.hpp @@ -88,6 +88,11 @@ namespace Query concept DelimiterConcept = std::convertible_to || std::convertible_to; + /*! QString container concept (QStringList or QVector). */ + template + concept QStringContainer = std::convertible_to || + std::convertible_to>; + } // namespace Orm TINYORM_END_COMMON_NAMESPACE diff --git a/include/orm/utils/container.hpp b/include/orm/utils/container.hpp index 79a349529..ce58ece4a 100644 --- a/include/orm/utils/container.hpp +++ b/include/orm/utils/container.hpp @@ -28,6 +28,11 @@ namespace Orm::Utils template static QString join(const T &container, D &&delimiter = Constants::COMMA); + + /*! Get a size of the greatest element in the container. */ + template + static QVector::size_type + maxElementSize(const T &container, QVector::size_type addToElement = 0); }; template @@ -53,6 +58,31 @@ namespace Orm::Utils return columnized; } + template + QVector::size_type + Container::maxElementSize(const T &container, + const QVector::size_type addToElement) + { + // Nothing to do + if (container.empty()) + return 0; + + QVector::size_type result = 0; + + for (const auto &element : container) + if (const auto elementSize = element.size(); + elementSize > result + ) + result = elementSize; + + /* This is the reason for the addToElement argument, this algorithm returns 0, + if the result is 0. */ + if (result == 0) + return 0; + + return result + addToElement; + } + } // namespace Orm::Utils TINYORM_END_COMMON_NAMESPACE diff --git a/src/orm/query/grammars/grammar.cpp b/src/orm/query/grammars/grammar.cpp index 3cc10c0aa..9ced117fb 100644 --- a/src/orm/query/grammars/grammar.cpp +++ b/src/orm/query/grammars/grammar.cpp @@ -580,6 +580,7 @@ QString Grammar::compileDeleteWithJoins(const QueryBuilder &query, const QString QString Grammar::concatenate(const QStringList &segments) { QString result; + result.reserve(ContainerUtils::maxElementSize(segments, 1)); for (const auto &segment : segments) { if (segment.isEmpty())