mirror of
https://github.com/silverqx/TinyORM.git
synced 2026-01-06 10:59:31 -06:00
groupBy column expressions and new overload
groupBy() methods now take column expressions. - added all proxies - added new perfectly forwarded groupBy(&&...args) overload - all new code tested manually in the TinyOrmPlayground
This commit is contained in:
@@ -2,6 +2,7 @@ INCLUDEPATH += $$PWD
|
||||
|
||||
HEADERS += \
|
||||
$$PWD/orm/basegrammar.hpp \
|
||||
$$PWD/orm/concepts.hpp \
|
||||
$$PWD/orm/concerns/detectslostconnections.hpp \
|
||||
$$PWD/orm/concerns/hasconnectionresolver.hpp \
|
||||
$$PWD/orm/configuration.hpp \
|
||||
|
||||
44
include/orm/concepts.hpp
Normal file
44
include/orm/concepts.hpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef ORM_CONCEPTS_HPP
|
||||
#define ORM_CONCEPTS_HPP
|
||||
|
||||
#ifdef TINYORM_COMMON_NAMESPACE
|
||||
namespace TINYORM_COMMON_NAMESPACE
|
||||
{
|
||||
#endif
|
||||
namespace Orm
|
||||
{
|
||||
|
||||
namespace Query
|
||||
{
|
||||
class Builder;
|
||||
class Expression;
|
||||
}
|
||||
using QueryBuilder = Query::Builder;
|
||||
|
||||
/*! Concept for the subquery, used in the from clause (tablename), join clause, ... */
|
||||
template<typename T>
|
||||
concept SubQuery = std::convertible_to<T, Orm::QueryBuilder &> ||
|
||||
std::convertible_to<T, QString> ||
|
||||
std::invocable<T, Orm::QueryBuilder &>;
|
||||
|
||||
/*! Concept for the join's table. */
|
||||
template<typename T>
|
||||
concept JoinTable = std::same_as<T, Query::Expression> ||
|
||||
std::convertible_to<T, QString>;
|
||||
|
||||
/*! Concept for the table column. */
|
||||
template<typename T>
|
||||
concept ColumnConcept =
|
||||
std::convertible_to<T, std::variant<QString, Query::Expression>>;
|
||||
|
||||
/*! Concept for the QString. */
|
||||
template<typename T>
|
||||
concept QStringConcept = std::convertible_to<T, const QString &> ||
|
||||
std::convertible_to<T, QString>;
|
||||
|
||||
} // namespace Orm
|
||||
#ifdef TINYORM_COMMON_NAMESPACE
|
||||
} // namespace TINYORM_COMMON_NAMESPACE
|
||||
#endif
|
||||
|
||||
#endif // ORM_CONCEPTS_HPP
|
||||
@@ -31,17 +31,6 @@ namespace Query
|
||||
}
|
||||
using QueryBuilder = Query::Builder;
|
||||
|
||||
/*! Concept for the subquery, used in the from clause (tablename), join clause, ... */
|
||||
template<typename T>
|
||||
concept SubQuery = std::convertible_to<T, Orm::QueryBuilder &> ||
|
||||
std::convertible_to<T, QString> ||
|
||||
std::invocable<T, Orm::QueryBuilder &>;
|
||||
|
||||
/*! Concept for the join's table. */
|
||||
template<typename T>
|
||||
concept JoinTable = std::same_as<T, Query::Expression> ||
|
||||
std::convertible_to<T, QString>;
|
||||
|
||||
/*! Type for the database column. */
|
||||
using Column = std::variant<QString, Query::Expression>;
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <optional>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "orm/concepts.hpp"
|
||||
#include "orm/ormtypes.hpp"
|
||||
#include "orm/query/grammars/grammar.hpp"
|
||||
|
||||
@@ -286,9 +287,12 @@ namespace Query
|
||||
Builder &orWhereNotNull(const Column &column);
|
||||
|
||||
/*! Add a "group by" clause to the query. */
|
||||
Builder &groupBy(const QStringList &groups);
|
||||
Builder &groupBy(const QVector<Column> &groups);
|
||||
/*! Add a "group by" clause to the query. */
|
||||
Builder &groupBy(const QString &group);
|
||||
Builder &groupBy(const Column &group);
|
||||
/*! Add a "group by" clause to the query. */
|
||||
template<ColumnConcept ...Args>
|
||||
Builder &groupBy(Args &&...groups);
|
||||
|
||||
/*! Add a "having" clause to the query. */
|
||||
Builder &having(const QString &column, const QString &comparison,
|
||||
@@ -389,7 +393,7 @@ namespace Query
|
||||
inline const QVector<WhereConditionItem> &getWheres() const
|
||||
{ return m_wheres; }
|
||||
/*! Get the groupings for the query. */
|
||||
inline const QStringList &getGroups() const
|
||||
inline const QVector<Column> &getGroups() const
|
||||
{ return m_groups; }
|
||||
/*! Get the having constraints for the query. */
|
||||
inline const QVector<HavingConditionItem> &getHavings() const
|
||||
@@ -562,7 +566,7 @@ namespace Query
|
||||
/*! The where constraints for the query. */
|
||||
QVector<WhereConditionItem> m_wheres;
|
||||
/*! The groupings for the query. */
|
||||
QStringList m_groups;
|
||||
QVector<Column> m_groups;
|
||||
/*! The having constraints for the query. */
|
||||
QVector<HavingConditionItem> m_havings;
|
||||
/*! The orderings for the query. */
|
||||
@@ -779,6 +783,12 @@ namespace Query
|
||||
QStringLiteral("right"));
|
||||
}
|
||||
|
||||
template<ColumnConcept ...Args>
|
||||
inline Builder &Builder::groupBy(Args &&...groups)
|
||||
{
|
||||
return groupBy(QVector<Column> {std::forward<Args>(groups)...});
|
||||
}
|
||||
|
||||
inline const std::optional<AggregateItem> &Builder::getAggregate() const
|
||||
{
|
||||
return m_aggregate;
|
||||
|
||||
@@ -78,6 +78,7 @@ namespace Relations {
|
||||
// TODO perf, run TinyOrmPlayground 30 times with disabled terminal output and calculate sum value of execution times to compare perf silverqx
|
||||
// TODO dilemma, function params. like direction asc/desc for orderBy, operators for where are QStrings, but they should be flags for performance reasons, how to solve this and preserve nice clean api? that is the question 🤔 silverqx
|
||||
// BUG Qt sql drivers do not work with mysql json columns silverqx
|
||||
// CUR solve all cur task about expressions, remove commented code in basegrammar and add new tasks about left column expressions in orderby, incerement/decrement, having and maybe groupby that I finish it later or something silverqx
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
class Model :
|
||||
public Concerns::HasRelationStore<Derived, AllRelations...>,
|
||||
@@ -465,10 +466,14 @@ namespace Relations {
|
||||
|
||||
/*! Add a "group by" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
groupBy(const QStringList &groups);
|
||||
groupBy(const QVector<Column> &groups);
|
||||
/*! Add a "group by" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
groupBy(const QString &group);
|
||||
groupBy(const Column &group);
|
||||
/*! Add a "group by" clause to the query. */
|
||||
template<ColumnConcept ...Args>
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
groupBy(Args &&...groups);
|
||||
|
||||
/*! Add a "having" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
@@ -2247,7 +2252,7 @@ namespace Relations {
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::groupBy(const QStringList &groups)
|
||||
Model<Derived, AllRelations...>::groupBy(const QVector<Column> &groups)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
@@ -2258,7 +2263,7 @@ namespace Relations {
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::groupBy(const QString &group)
|
||||
Model<Derived, AllRelations...>::groupBy(const Column &group)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
@@ -2267,6 +2272,18 @@ namespace Relations {
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
template<ColumnConcept ...Args>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::groupBy(Args &&...groups)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
builder->groupBy(QVector<Column> {std::forward<Args>(groups)...});
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::having(
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <range/v3/action/sort.hpp>
|
||||
#include <range/v3/action/unique.hpp>
|
||||
|
||||
#include "orm/concepts.hpp"
|
||||
#include "orm/ormtypes.hpp"
|
||||
|
||||
#ifdef TINYORM_COMMON_NAMESPACE
|
||||
@@ -407,9 +408,12 @@ namespace Relations
|
||||
const Relation &orWhereNotNull(const Column &column) const;
|
||||
|
||||
/*! Add a "group by" clause to the query. */
|
||||
const Relation &groupBy(const QStringList &groups) const;
|
||||
const Relation &groupBy(const QVector<Column> &groups) const;
|
||||
/*! Add a "group by" clause to the query. */
|
||||
const Relation &groupBy(const QString &group) const;
|
||||
const Relation &groupBy(const Column &group) const;
|
||||
/*! Add a "group by" clause to the query. */
|
||||
template<ColumnConcept ...Args>
|
||||
const Relation &groupBy(Args &&...groups) const;
|
||||
|
||||
/*! Add a "having" clause to the query. */
|
||||
const Relation &having(const QString &column, const QString &comparison,
|
||||
@@ -1340,7 +1344,7 @@ namespace Relations
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::groupBy(const QStringList &groups) const
|
||||
Relation<Model, Related>::groupBy(const QVector<Column> &groups) const
|
||||
{
|
||||
m_query->groupBy(groups);
|
||||
|
||||
@@ -1349,13 +1353,23 @@ namespace Relations
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::groupBy(const QString &group) const
|
||||
Relation<Model, Related>::groupBy(const Column &group) const
|
||||
{
|
||||
m_query->groupBy(group);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
template<ColumnConcept ...Args>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::groupBy(Args &&...groups) const
|
||||
{
|
||||
m_query->groupBy(QVector<Column> {std::forward<Args>(groups)...});
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::having(
|
||||
|
||||
@@ -310,9 +310,12 @@ namespace Relations
|
||||
Builder &orWhereNotNull(const Column &column);
|
||||
|
||||
/*! Add a "group by" clause to the query. */
|
||||
Builder &groupBy(const QStringList &groups);
|
||||
Builder &groupBy(const QVector<Column> &groups);
|
||||
/*! Add a "group by" clause to the query. */
|
||||
Builder &groupBy(const QString &group);
|
||||
Builder &groupBy(const Column &group);
|
||||
/*! Add a "group by" clause to the query. */
|
||||
template<ColumnConcept ...Args>
|
||||
Builder &groupBy(Args &&...groups);
|
||||
|
||||
/*! Add a "having" clause to the query. */
|
||||
Builder &having(const QString &column, const QString &comparison,
|
||||
@@ -1264,19 +1267,27 @@ namespace Relations
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &Builder<Model>::groupBy(const QStringList &groups)
|
||||
Builder<Model> &Builder<Model>::groupBy(const QVector<Column> &groups)
|
||||
{
|
||||
toBase().groupBy(groups);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &Builder<Model>::groupBy(const QString &group)
|
||||
Builder<Model> &Builder<Model>::groupBy(const Column &group)
|
||||
{
|
||||
toBase().groupBy(group);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
template<ColumnConcept ...Args>
|
||||
Builder<Model> &Builder<Model>::groupBy(Args &&...groups)
|
||||
{
|
||||
toBase().groupBy(QVector<Column> {std::forward<Args>(groups)...});
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::having(const QString &column, const QString &comparison,
|
||||
|
||||
@@ -440,7 +440,7 @@ Builder &Builder::orWhereNotNull(const Column &column)
|
||||
return orWhereNotNull(QVector<Column> {column});
|
||||
}
|
||||
|
||||
Builder &Builder::groupBy(const QStringList &groups)
|
||||
Builder &Builder::groupBy(const QVector<Column> &groups)
|
||||
{
|
||||
if (groups.isEmpty())
|
||||
return *this;
|
||||
@@ -450,9 +450,9 @@ Builder &Builder::groupBy(const QStringList &groups)
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder &Builder::groupBy(const QString &group)
|
||||
Builder &Builder::groupBy(const Column &group)
|
||||
{
|
||||
return groupBy(QStringList {group});
|
||||
return groupBy(QVector<Column> {group});
|
||||
}
|
||||
|
||||
Builder &Builder::having(const QString &column, const QString &comparison,
|
||||
|
||||
Reference in New Issue
Block a user