mirror of
https://github.com/silverqx/TinyORM.git
synced 2026-02-11 04:49:15 -06:00
added missing raw methods
or/whereRaw(), groupByRaw(), or/havingRaw(), orderByRaw(). - added docs - tested manually in Playground
This commit is contained in:
@@ -148,6 +148,55 @@ The `selectRaw` method can be used in place of `addSelect(DB::raw(...))`. This m
|
||||
->selectRaw("price * ? as price_with_tax", {1.0825})
|
||||
.get();
|
||||
|
||||
<a name="fromraw"></a>
|
||||
#### `fromRaw`
|
||||
|
||||
The `fromRaw` method may be used to provide a raw string as the value of the "from" clause:
|
||||
|
||||
auto users = DB::connection("postgres").query()
|
||||
->fromRaw("(select id, name from users where id < ?) as u", {5})
|
||||
.where("id", "<", 3)
|
||||
.get();
|
||||
|
||||
<a name="whereraw-orwhereraw"></a>
|
||||
#### `whereRaw / orWhereRaw`
|
||||
|
||||
The `whereRaw` and `orWhereRaw` methods can be used to inject a raw "where" clause into your query. These methods accept an optional vector of bindings as their second argument:
|
||||
|
||||
auto orders = DB::table("orders")
|
||||
->whereRaw("price > IF(state = \"TX\", ?, 100)", {200})
|
||||
.get();
|
||||
|
||||
<a name="groupbyraw"></a>
|
||||
### `groupByRaw`
|
||||
|
||||
The `groupByRaw` method may be used to provide a raw string as the value of the `group by` clause:
|
||||
|
||||
auto orders = DB::table("orders")
|
||||
->select({"city", "state"})
|
||||
.groupByRaw("city, state")
|
||||
.get();
|
||||
|
||||
<a name="havingraw-orhavingraw"></a>
|
||||
#### `havingRaw / orHavingRaw`
|
||||
|
||||
The `havingRaw` and `orHavingRaw` methods may be used to provide a raw string as the value of the "having" clause. These methods accept an optional vector of bindings as their second argument:
|
||||
|
||||
auto orders = DB::table("orders")
|
||||
->select({"department", DB::raw("SUM(price) as total_sales")})
|
||||
.groupBy("department")
|
||||
.havingRaw("SUM(price) > ?", {2500})
|
||||
.get();
|
||||
|
||||
<a name="orderbyraw"></a>
|
||||
#### `orderByRaw`
|
||||
|
||||
The `orderByRaw` method may be used to provide a raw string as the value of the "order by" clause:
|
||||
|
||||
auto orders = DB::table("orders")
|
||||
->orderByRaw("updated_at - created_at DESC")
|
||||
.get();
|
||||
|
||||
<a name="joins"></a>
|
||||
## Joins
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ namespace Query
|
||||
NOT_IN,
|
||||
NULL_,
|
||||
NOT_NULL,
|
||||
RAW,
|
||||
};
|
||||
|
||||
struct WhereConditionItem
|
||||
@@ -81,13 +82,16 @@ namespace Query
|
||||
QSharedPointer<QueryBuilder> nestedQuery {nullptr};
|
||||
QVector<QVariant> values {};
|
||||
Column columnTwo {};
|
||||
QString sql {};
|
||||
};
|
||||
|
||||
enum struct HavingType
|
||||
{
|
||||
UNDEFINED = -1,
|
||||
BASIC,
|
||||
RAW,
|
||||
};
|
||||
|
||||
struct HavingConditionItem
|
||||
{
|
||||
Column column;
|
||||
@@ -95,12 +99,14 @@ namespace Query
|
||||
QString comparison {"="};
|
||||
QString condition {"and"};
|
||||
HavingType type {HavingType::UNDEFINED};
|
||||
QString sql {};
|
||||
};
|
||||
|
||||
struct OrderByItem
|
||||
{
|
||||
Column column;
|
||||
QString direction {"asc"};
|
||||
Column column;
|
||||
QString direction {"asc"};
|
||||
QString sql {};
|
||||
};
|
||||
|
||||
struct SHAREDLIB_EXPORT UpdateItem
|
||||
|
||||
@@ -140,7 +140,10 @@ namespace Orm::Query::Grammars
|
||||
QString whereNull(const WhereConditionItem &where) const;
|
||||
/*! Compile a "where not null" clause. */
|
||||
QString whereNotNull(const WhereConditionItem &where) const;
|
||||
/*! Compile a raw where clause. */
|
||||
QString whereRaw(const WhereConditionItem &where) const;
|
||||
|
||||
// CUR reorder silverqx
|
||||
/*! Compile the "order by" portions of the query. */
|
||||
QString compileOrders(const QueryBuilder &query) const;
|
||||
/*! Compile the query orders to the vector. */
|
||||
|
||||
@@ -144,13 +144,12 @@ namespace Query
|
||||
/*! Set the table which the query is targeting. */
|
||||
Builder &from(Expression &&table);
|
||||
|
||||
/*! Set the table which the query is targeting. */
|
||||
Builder &fromRaw(const QString &expression,
|
||||
const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Makes "from" fetch from a subquery. */
|
||||
template<SubQuery T>
|
||||
Builder &fromSub(T &&query, const QString &as);
|
||||
/*! Set the table which the query is targeting. */
|
||||
Builder &fromRaw(const QString &expression,
|
||||
const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add a join clause to the query. */
|
||||
template<JoinTable T>
|
||||
@@ -299,6 +298,12 @@ namespace Query
|
||||
/*! Add an "or where not null" clause to the query. */
|
||||
Builder &orWhereNotNull(const Column &column);
|
||||
|
||||
/*! Add a raw "where" clause to the query. */
|
||||
Builder &whereRaw(const QString &sql, const QVector<QVariant> &bindings = {},
|
||||
const QString &condition = "and");
|
||||
/*! Add a raw "or where" clause to the query. */
|
||||
Builder &orWhereRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add a "group by" clause to the query. */
|
||||
Builder &groupBy(const QVector<Column> &groups);
|
||||
/*! Add a "group by" clause to the query. */
|
||||
@@ -307,6 +312,9 @@ namespace Query
|
||||
template<ColumnConcept ...Args>
|
||||
Builder &groupBy(Args &&...groups);
|
||||
|
||||
/*! Add a raw "groupBy" clause to the query. */
|
||||
Builder &groupByRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add a "having" clause to the query. */
|
||||
Builder &having(const Column &column, const QString &comparison,
|
||||
const QVariant &value, const QString &condition = "and");
|
||||
@@ -314,11 +322,20 @@ namespace Query
|
||||
Builder &orHaving(const Column &column, const QString &comparison,
|
||||
const QVariant &value);
|
||||
|
||||
/*! Add a raw "having" clause to the query. */
|
||||
Builder &havingRaw(const QString &sql, const QVector<QVariant> &bindings = {},
|
||||
const QString &condition = "and");
|
||||
/*! Add a raw "or having" clause to the query. */
|
||||
Builder &orHavingRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add an "order by" clause to the query. */
|
||||
Builder &orderBy(const Column &column, const QString &direction = "asc");
|
||||
/*! Add a descending "order by" clause to the query. */
|
||||
Builder &orderByDesc(const Column &column);
|
||||
|
||||
/*! Add a raw "order by" clause to the query. */
|
||||
Builder &orderByRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add an "order by" clause for a timestamp to the query. */
|
||||
Builder &latest(const Column &column = "created_at");
|
||||
/*! Add an "order by" clause for a timestamp to the query. */
|
||||
|
||||
@@ -499,6 +499,14 @@ namespace Relations {
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
orWhereNotNull(const Column &column);
|
||||
|
||||
/*! Add a raw "where" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
whereRaw(const QString &sql, const QVector<QVariant> &bindings = {},
|
||||
const QString &condition = "and");
|
||||
/*! Add a raw "or where" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
orWhereRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add a "group by" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
groupBy(const QVector<Column> &groups);
|
||||
@@ -510,6 +518,10 @@ namespace Relations {
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
groupBy(Args &&...groups);
|
||||
|
||||
/*! Add a raw "groupBy" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
groupByRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add a "having" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
having(const Column &column, const QString &comparison,
|
||||
@@ -519,6 +531,14 @@ namespace Relations {
|
||||
orHaving(const Column &column, const QString &comparison,
|
||||
const QVariant &value);
|
||||
|
||||
/*! Add a raw "having" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
havingRaw(const QString &sql, const QVector<QVariant> &bindings = {},
|
||||
const QString &condition = "and");
|
||||
/*! Add a raw "or having" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
orHavingRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add an "order by" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
orderBy(const Column &column, const QString &direction = "asc");
|
||||
@@ -526,6 +546,10 @@ namespace Relations {
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
orderByDesc(const Column &column);
|
||||
|
||||
/*! Add a raw "order by" clause to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
orderByRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add an "order by" clause for a timestamp to the query. */
|
||||
static std::unique_ptr<TinyBuilder<Derived>>
|
||||
latest(const Column &column = "");
|
||||
@@ -2379,6 +2403,31 @@ namespace Relations {
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::whereRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings,
|
||||
const QString &condition)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
builder->whereRaw(sql, bindings, condition);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::orWhereRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
builder->whereRaw(sql, bindings, QStringLiteral("or"));
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::groupBy(const QVector<Column> &groups)
|
||||
@@ -2401,6 +2450,18 @@ namespace Relations {
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::groupByRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
builder->groupByRaw(sql, bindings);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
template<ColumnConcept ...Args>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
@@ -2438,6 +2499,31 @@ namespace Relations {
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::havingRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings,
|
||||
const QString &condition)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
builder->havingRaw(sql, bindings, condition);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::orHavingRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
builder->havingRaw(sql, bindings, QStringLiteral("or"));
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::orderBy(const Column &column,
|
||||
@@ -2461,6 +2547,18 @@ namespace Relations {
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::orderByRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings)
|
||||
{
|
||||
auto builder = query();
|
||||
|
||||
builder->orderByRaw(sql, bindings);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::unique_ptr<TinyBuilder<Derived>>
|
||||
Model<Derived, AllRelations...>::latest(const Column &column)
|
||||
|
||||
@@ -443,6 +443,14 @@ namespace Relations
|
||||
/*! Add an "or where not null" clause to the query. */
|
||||
const Relation &orWhereNotNull(const Column &column) const;
|
||||
|
||||
/*! Add a raw "where" clause to the query. */
|
||||
const Relation &whereRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings = {},
|
||||
const QString &condition = "and") const;
|
||||
/*! Add a raw "or where" clause to the query. */
|
||||
const Relation &orWhereRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings = {}) const;
|
||||
|
||||
/*! Add a "group by" clause to the query. */
|
||||
const Relation &groupBy(const QVector<Column> &groups) const;
|
||||
/*! Add a "group by" clause to the query. */
|
||||
@@ -451,6 +459,10 @@ namespace Relations
|
||||
template<ColumnConcept ...Args>
|
||||
const Relation &groupBy(Args &&...groups) const;
|
||||
|
||||
/*! Add a raw "groupBy" clause to the query. */
|
||||
const Relation &groupByRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings = {}) const;
|
||||
|
||||
/*! Add a "having" clause to the query. */
|
||||
const Relation &having(const Column &column, const QString &comparison,
|
||||
const QVariant &value,
|
||||
@@ -459,12 +471,24 @@ namespace Relations
|
||||
const Relation &orHaving(const Column &column, const QString &comparison,
|
||||
const QVariant &value) const;
|
||||
|
||||
/*! Add a raw "having" clause to the query. */
|
||||
const Relation &havingRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings = {},
|
||||
const QString &condition = "and") const;
|
||||
/*! Add a raw "or having" clause to the query. */
|
||||
const Relation &orHavingRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings = {}) const;
|
||||
|
||||
/*! Add an "order by" clause to the query. */
|
||||
const Relation &orderBy(const Column &column,
|
||||
const QString &direction = "asc") const;
|
||||
/*! Add a descending "order by" clause to the query. */
|
||||
const Relation &orderByDesc(const Column &column) const;
|
||||
|
||||
/*! Add a raw "order by" clause to the query. */
|
||||
const Relation &orderByRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings = {}) const;
|
||||
|
||||
/*! Add an "order by" clause for a timestamp to the query. */
|
||||
const Relation &latest(const Column &column = "") const;
|
||||
/*! Add an "order by" clause for a timestamp to the query. */
|
||||
@@ -1466,6 +1490,27 @@ namespace Relations
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::whereRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings,
|
||||
const QString &condition) const
|
||||
{
|
||||
m_query->whereRaw(sql, bindings, condition);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::orWhereRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings) const
|
||||
{
|
||||
m_query->whereRaw(sql, bindings, QStringLiteral("or"));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::groupBy(const QVector<Column> &groups) const
|
||||
@@ -1494,6 +1539,16 @@ namespace Relations
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::groupByRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings) const
|
||||
{
|
||||
m_query->groupByRaw(sql, bindings);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::having(
|
||||
@@ -1515,6 +1570,27 @@ namespace Relations
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::havingRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings,
|
||||
const QString &condition) const
|
||||
{
|
||||
m_query->havingRaw(sql, bindings, condition);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::orHavingRaw(
|
||||
const QString &sql, const QVector<QVariant> &bindings) const
|
||||
{
|
||||
m_query->havingRaw(sql, bindings, QStringLiteral("or"));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::orderBy(const Column &column,
|
||||
@@ -1534,6 +1610,16 @@ namespace Relations
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::orderByRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings) const
|
||||
{
|
||||
m_query->orderByRaw(sql, bindings);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<class Model, class Related>
|
||||
const Relation<Model, Related> &
|
||||
Relation<Model, Related>::latest(const Column &column) const
|
||||
|
||||
@@ -342,6 +342,12 @@ namespace Relations
|
||||
/*! Add an "or where not null" clause to the query. */
|
||||
Builder &orWhereNotNull(const Column &column);
|
||||
|
||||
/*! Add a raw "where" clause to the query. */
|
||||
Builder &whereRaw(const QString &sql, const QVector<QVariant> &bindings = {},
|
||||
const QString &condition = "and");
|
||||
/*! Add a raw "or where" clause to the query. */
|
||||
Builder &orWhereRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add a "group by" clause to the query. */
|
||||
Builder &groupBy(const QVector<Column> &groups);
|
||||
/*! Add a "group by" clause to the query. */
|
||||
@@ -350,6 +356,9 @@ namespace Relations
|
||||
template<ColumnConcept ...Args>
|
||||
Builder &groupBy(Args &&...groups);
|
||||
|
||||
/*! Add a raw "groupBy" clause to the query. */
|
||||
Builder &groupByRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add a "having" clause to the query. */
|
||||
Builder &having(const Column &column, const QString &comparison,
|
||||
const QVariant &value, const QString &condition = "and");
|
||||
@@ -357,11 +366,20 @@ namespace Relations
|
||||
Builder &orHaving(const Column &column, const QString &comparison,
|
||||
const QVariant &value);
|
||||
|
||||
/*! Add a raw "having" clause to the query. */
|
||||
Builder &havingRaw(const QString &sql, const QVector<QVariant> &bindings = {},
|
||||
const QString &condition = "and");
|
||||
/*! Add a raw "or having" clause to the query. */
|
||||
Builder &orHavingRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add an "order by" clause to the query. */
|
||||
Builder &orderBy(const Column &column, const QString &direction = "asc");
|
||||
/*! Add a descending "order by" clause to the query. */
|
||||
Builder &orderByDesc(const Column &column);
|
||||
|
||||
/*! Add a raw "order by" clause to the query. */
|
||||
Builder &orderByRaw(const QString &sql, const QVector<QVariant> &bindings = {});
|
||||
|
||||
/*! Add an "order by" clause for a timestamp to the query. */
|
||||
Builder &latest(const Column &column = "");
|
||||
/*! Add an "order by" clause for a timestamp to the query. */
|
||||
@@ -1380,6 +1398,23 @@ namespace Relations
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::whereRaw(const QString &sql, const QVector<QVariant> &bindings,
|
||||
const QString &condition)
|
||||
{
|
||||
toBase().whereRaw(sql, bindings, condition);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::orWhereRaw(const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
toBase().whereRaw(sql, bindings, QStringLiteral("or"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &Builder<Model>::groupBy(const QVector<Column> &groups)
|
||||
{
|
||||
@@ -1402,6 +1437,14 @@ namespace Relations
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::groupByRaw(const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
toBase().groupByRaw(sql, bindings);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::having(const Column &column, const QString &comparison,
|
||||
@@ -1420,6 +1463,23 @@ namespace Relations
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::havingRaw(const QString &sql, const QVector<QVariant> &bindings,
|
||||
const QString &condition)
|
||||
{
|
||||
toBase().havingRaw(sql, bindings, condition);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::orHavingRaw(const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
toBase().havingRaw(sql, bindings, QStringLiteral("or"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::orderBy(const Column &column, const QString &direction)
|
||||
@@ -1435,6 +1495,14 @@ namespace Relations
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &Builder<Model>::orderByRaw(const QString &sql,
|
||||
const QVector<QVariant> &bindings)
|
||||
{
|
||||
toBase().orderByRaw(sql, bindings);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
Builder<Model> &
|
||||
Builder<Model>::latest(const Column &column)
|
||||
|
||||
@@ -284,10 +284,19 @@ QString Grammar::compileHavings(const QueryBuilder &query) const
|
||||
|
||||
QString Grammar::compileHaving(const HavingConditionItem &having) const
|
||||
{
|
||||
/* If the having clause is "raw", we can just return the clause straight away
|
||||
without doing any more processing on it. Otherwise, we will compile the
|
||||
clause into SQL based on the components that make it up from builder. */
|
||||
switch (having.type) {
|
||||
T_LIKELY
|
||||
case HavingType::BASIC:
|
||||
return compileBasicHaving(having);
|
||||
|
||||
T_UNLIKELY
|
||||
case HavingType::RAW:
|
||||
return QStringLiteral("%1 %2").arg(having.condition, having.sql);
|
||||
|
||||
T_UNLIKELY
|
||||
default:
|
||||
throw RuntimeError(QStringLiteral("Unknown HavingType (%1).")
|
||||
.arg(static_cast<int>(having.type)));
|
||||
@@ -357,6 +366,11 @@ QString Grammar::whereNotNull(const WhereConditionItem &where) const
|
||||
return QStringLiteral("%1 is not null").arg(wrap(where.column));
|
||||
}
|
||||
|
||||
QString Grammar::whereRaw(const WhereConditionItem &where) const
|
||||
{
|
||||
return where.sql;
|
||||
}
|
||||
|
||||
QString Grammar::compileOrders(const QueryBuilder &query) const
|
||||
{
|
||||
if (query.getOrders().isEmpty())
|
||||
@@ -373,8 +387,11 @@ QStringList Grammar::compileOrdersToVector(const QueryBuilder &query) const
|
||||
compiledOrders.reserve(orders.size());
|
||||
|
||||
for (const auto &order : orders)
|
||||
compiledOrders << QStringLiteral("%1 %2")
|
||||
.arg(wrap(order.column), order.direction.toLower());
|
||||
if (order.sql.isEmpty()) T_LIKELY
|
||||
compiledOrders << QStringLiteral("%1 %2")
|
||||
.arg(wrap(order.column), order.direction.toLower());
|
||||
else T_UNLIKELY
|
||||
compiledOrders << order.sql;
|
||||
|
||||
return compiledOrders;
|
||||
}
|
||||
|
||||
@@ -155,6 +155,7 @@ MySqlGrammar::getWhereMethod(const WhereType whereType) const
|
||||
getBind(&MySqlGrammar::whereNotIn),
|
||||
getBind(&MySqlGrammar::whereNull),
|
||||
getBind(&MySqlGrammar::whereNotNull),
|
||||
getBind(&MySqlGrammar::whereRaw),
|
||||
};
|
||||
|
||||
static const auto size = cached.size();
|
||||
|
||||
@@ -160,6 +160,7 @@ PostgresGrammar::getWhereMethod(const WhereType whereType) const
|
||||
getBind(&PostgresGrammar::whereNotIn),
|
||||
getBind(&PostgresGrammar::whereNull),
|
||||
getBind(&PostgresGrammar::whereNotNull),
|
||||
getBind(&PostgresGrammar::whereRaw),
|
||||
};
|
||||
|
||||
static const auto size = cached.size();
|
||||
|
||||
@@ -136,6 +136,7 @@ SQLiteGrammar::getWhereMethod(const WhereType whereType) const
|
||||
getBind(&SQLiteGrammar::whereNotIn),
|
||||
getBind(&SQLiteGrammar::whereNull),
|
||||
getBind(&SQLiteGrammar::whereNotNull),
|
||||
getBind(&SQLiteGrammar::whereRaw),
|
||||
};
|
||||
|
||||
static const auto size = cached.size();
|
||||
|
||||
@@ -438,6 +438,21 @@ Builder &Builder::orWhereNotNull(const Column &column)
|
||||
return orWhereNotNull(QVector<Column> {column});
|
||||
}
|
||||
|
||||
Builder &Builder::whereRaw(const QString &sql, const QVector<QVariant> &bindings,
|
||||
const QString &condition)
|
||||
{
|
||||
m_wheres.append({.condition = condition, .type = WhereType::RAW, .sql = sql});
|
||||
|
||||
addBinding(bindings, BindingType::WHERE);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder &Builder::orWhereRaw(const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
return whereRaw(sql, bindings, QStringLiteral("or"));
|
||||
}
|
||||
|
||||
Builder &Builder::groupBy(const QVector<Column> &groups)
|
||||
{
|
||||
if (groups.isEmpty())
|
||||
@@ -453,6 +468,15 @@ Builder &Builder::groupBy(const Column &group)
|
||||
return groupBy(QVector<Column> {group});
|
||||
}
|
||||
|
||||
Builder &Builder::groupByRaw(const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
m_groups.append(Expression(sql));
|
||||
|
||||
addBinding(bindings, BindingType::GROUPBY);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder &Builder::having(const Column &column, const QString &comparison,
|
||||
const QVariant &value, const QString &condition)
|
||||
{
|
||||
@@ -474,6 +498,21 @@ Builder &Builder::orHaving(const Column &column, const QString &comparison,
|
||||
return having(column, comparison, value, QStringLiteral("or"));
|
||||
}
|
||||
|
||||
Builder &Builder::havingRaw(const QString &sql, const QVector<QVariant> &bindings,
|
||||
const QString &condition)
|
||||
{
|
||||
m_havings.append({.condition = condition, .type = HavingType::RAW, .sql = sql});
|
||||
|
||||
addBinding(bindings, BindingType::HAVING);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder &Builder::orHavingRaw(const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
return havingRaw(sql, bindings, QStringLiteral("or"));
|
||||
}
|
||||
|
||||
Builder &Builder::orderBy(const Column &column, const QString &direction)
|
||||
{
|
||||
const auto &directionLower = direction.toLower();
|
||||
@@ -494,6 +533,15 @@ Builder &Builder::orderByDesc(const Column &column)
|
||||
return orderBy(column, QStringLiteral("desc"));
|
||||
}
|
||||
|
||||
Builder &Builder::orderByRaw(const QString &sql, const QVector<QVariant> &bindings)
|
||||
{
|
||||
m_orders.append({.sql = sql});
|
||||
|
||||
addBinding(bindings, BindingType::ORDER);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Builder &Builder::latest(const Column &column)
|
||||
{
|
||||
/* Default value "created_at" is ok, because we are in the QueryBuilder,
|
||||
|
||||
Reference in New Issue
Block a user