added inRandomOrder() to the QueryBuilder

- added unit tests
 - added all proxies
 - added docs
This commit is contained in:
silverqx
2022-07-24 14:41:26 +02:00
parent c41671f367
commit 6ac2e4331d
13 changed files with 116 additions and 0 deletions
+8
View File
@@ -558,6 +558,14 @@ The `latest` and `oldest` methods allow you to easily order results by date. By
->latest()
.first();
#### Random Ordering
The `inRandomOrder` method may be used to sort the query results randomly. For example, you may use this method to fetch a random user:
auto randomUser = DB::table("users")
->inRandomOrder()
.first();
#### Removing Existing Orderings
The `reorder` method removes all of the "order by" clauses that have previously been applied to the query:
+3
View File
@@ -62,6 +62,9 @@ namespace Orm::Query::Grammars
virtual std::unordered_map<QString, QVector<QVariant>>
compileTruncate(const QueryBuilder &query) const;
/*! Compile the random statement into SQL. */
virtual QString compileRandom(const QString &seed) const;
/*! Get the grammar specific operators. */
virtual const QVector<QString> &getOperators() const;
@@ -33,6 +33,9 @@ namespace Orm::Query::Grammars
/*! Compile the lock into SQL. */
QString compileLock(const QueryBuilder &query) const override;
/*! Compile the random statement into SQL. */
QString compileRandom(const QString &seed) const override;
/*! Get the grammar specific operators. */
const QVector<QString> &getOperators() const override;
+2
View File
@@ -468,6 +468,8 @@ namespace Orm::Query
template<Queryable T>
inline Builder &orderByDesc(T &&query);
/*! Put the query's results in random order. */
Builder &inRandomOrder(const QString &seed = "");
/*! Add a raw "order by" clause to the query. */
Builder &orderByRaw(const QString &sql, const QVector<QVariant> &bindings = {});
+3
View File
@@ -511,6 +511,9 @@ namespace Relations
static std::unique_ptr<TinyBuilder<Derived>>
orderByDesc(T &&query);
/*! Put the query's results in random order. */
static std::unique_ptr<TinyBuilder<Derived>>
inRandomOrder(const QString &seed = "");
/*! Add a raw "order by" clause to the query. */
static std::unique_ptr<TinyBuilder<Derived>>
orderByRaw(const QString &sql, const QVector<QVariant> &bindings = {});
@@ -487,6 +487,8 @@ namespace Tiny::Relations
template<Queryable T>
const Relation<Model, Related> &orderByDesc(T &&query) const;
/*! Put the query's results in random order. */
const Relation<Model, Related> &inRandomOrder(const QString &seed = "") const;
/*! Add a raw "order by" clause to the query. */
const Relation<Model, Related> &orderByRaw(
const QString &sql, const QVector<QVariant> &bindings = {}) const;
+2
View File
@@ -372,6 +372,8 @@ namespace Tiny
template<Queryable T>
TinyBuilder<Model> &orderByDesc(T &&query);
/*! Put the query's results in random order. */
TinyBuilder<Model> &inRandomOrder(const QString &seed = "");
/*! Add a raw "order by" clause to the query. */
TinyBuilder<Model> &orderByRaw(const QString &sql,
const QVector<QVariant> &bindings = {});
+5
View File
@@ -119,6 +119,11 @@ Grammar::compileTruncate(const QueryBuilder &query) const
return {{QStringLiteral("truncate table %1").arg(wrapTable(query.getFrom())), {}}};
}
QString Grammar::compileRandom(const QString &/*unused*/) const
{
return QStringLiteral("RANDOM()");
}
const QVector<QString> &Grammar::getOperators() const
{
/* I make it this way, I don't declare it as pure virtual intentionally, this gives
+5
View File
@@ -35,6 +35,11 @@ QString MySqlGrammar::compileLock(const QueryBuilder &query) const
return std::get<QString>(lock);
}
QString MySqlGrammar::compileRandom(const QString &seed) const
{
return QStringLiteral("RAND(%1)").arg(seed);
}
const QVector<QString> &MySqlGrammar::getOperators() const
{
static const QVector<QString> cachedOperators {QLatin1String("sounds like")};
+5
View File
@@ -608,6 +608,11 @@ Builder &Builder::orderByDesc(const Column &column)
return orderBy(column, DESC);
}
Builder &Builder::inRandomOrder(const QString &seed)
{
return orderByRaw(m_grammar.compileRandom(seed));
}
Builder &Builder::orderByRaw(const QString &sql, const QVector<QVariant> &bindings)
{
m_orders.append({.sql = sql});
@@ -153,6 +153,7 @@ private Q_SLOTS:
void orderBy() const;
void latestOldest() const;
void inRandomOrder() const;
void limitOffset() const;
void takeSkip() const;
@@ -2275,6 +2276,37 @@ void tst_MySql_QueryBuilder::latestOldest() const
"select * from `torrents` order by `name` asc");
}
void tst_MySql_QueryBuilder::inRandomOrder() const
{
{
auto builder = createQuery();
builder->from("torrents");
builder->inRandomOrder();
QCOMPARE(builder->toSql(),
"select * from `torrents` order by RAND()");
}
{
auto builder = createQuery();
builder->from("torrents");
builder->inRandomOrder("123");
QCOMPARE(builder->toSql(),
"select * from `torrents` order by RAND(123)");
}
{
auto builder = createQuery();
builder->from("torrents");
builder->inRandomOrder("`column_name`");
QCOMPARE(builder->toSql(),
"select * from `torrents` order by RAND(`column_name`)");
}
}
void tst_MySql_QueryBuilder::limitOffset() const
{
auto builder = createQuery();
@@ -108,6 +108,7 @@ private Q_SLOTS:
void orderBy() const;
void latestOldest() const;
void inRandomOrder() const;
void limitOffset() const;
void takeSkip() const;
@@ -1632,6 +1633,28 @@ void tst_PostgreSQL_QueryBuilder::latestOldest() const
"select * from \"torrents\" order by \"name\" asc");
}
void tst_PostgreSQL_QueryBuilder::inRandomOrder() const
{
{
auto builder = createQuery();
builder->from("torrents");
builder->inRandomOrder();
QCOMPARE(builder->toSql(),
"select * from \"torrents\" order by RANDOM()");
}
{
auto builder = createQuery();
builder->from("torrents");
builder->inRandomOrder("seed123");
QCOMPARE(builder->toSql(),
"select * from \"torrents\" order by RANDOM()");
}
}
void tst_PostgreSQL_QueryBuilder::limitOffset() const
{
auto builder = createQuery();
@@ -107,6 +107,7 @@ private Q_SLOTS:
void orderBy() const;
void latestOldest() const;
void inRandomOrder() const;
void limitOffset() const;
void takeSkip() const;
@@ -1585,6 +1586,28 @@ void tst_SQLite_QueryBuilder::latestOldest() const
"select * from \"torrents\" order by \"name\" asc");
}
void tst_SQLite_QueryBuilder::inRandomOrder() const
{
{
auto builder = createQuery();
builder->from("torrents");
builder->inRandomOrder();
QCOMPARE(builder->toSql(),
"select * from \"torrents\" order by RANDOM()");
}
{
auto builder = createQuery();
builder->from("torrents");
builder->inRandomOrder("seed123");
QCOMPARE(builder->toSql(),
"select * from \"torrents\" order by RANDOM()");
}
}
void tst_SQLite_QueryBuilder::limitOffset() const
{
auto builder = createQuery();