mirror of
https://github.com/silverqx/TinyORM.git
synced 2025-12-30 07:19:34 -06:00
added TinyBuilder::touch()
- added unit tests - added model proxy touchAll() - added docs
This commit is contained in:
@@ -249,6 +249,24 @@ You can make these static constants non-inline and initialize them in the cpp fi
|
||||
You may also use `Orm::CREATED_AT` and `Orm::UPDATED_AT` string constants instead of `QStringLiteral("created_at")`.
|
||||
:::
|
||||
|
||||
#### Touching timestamps
|
||||
|
||||
You can explicitly touch timestamps using the `touch` method defined on the Model:
|
||||
|
||||
auto flight = Flight::find(1);
|
||||
|
||||
flight->touch();
|
||||
flight->touch("added_on"); // Custom column name
|
||||
|
||||
You can also touch multiple rows at once using the `touch` method defined on the TinyBuilder:
|
||||
|
||||
auto [affected, query] = Flight::whereEq("status", "new")->touch();
|
||||
|
||||
The `touch` method may also be called when building a [relationship](/tinyorm/relationships.mdx) query:
|
||||
|
||||
flight->history()->touch();
|
||||
flight->history()->whereEq("status", "new").touch();
|
||||
|
||||
### Database Connections
|
||||
|
||||
By default, all TinyORM models will use the default database connection that is configured for your application. If you would like to specify a different connection that should be used when interacting with a particular model, you should define a `u_connection` private data member on the model:
|
||||
|
||||
@@ -225,6 +225,11 @@ namespace Tiny
|
||||
/*! Run a truncate statement on the table. */
|
||||
static void truncate();
|
||||
|
||||
/* Touching timestamps */
|
||||
/*! Update the column's update timestamp on all Models. */
|
||||
static std::tuple<int, std::optional<QSqlQuery>>
|
||||
touchAll(const QString &column = "");
|
||||
|
||||
/* Select */
|
||||
/*! Retrieve the "count" result of the query. */
|
||||
static quint64 count(const QVector<Column> &columns = {ASTERISK});
|
||||
@@ -1417,6 +1422,15 @@ namespace Tiny
|
||||
query()->truncate();
|
||||
}
|
||||
|
||||
/* Touching timestamps */
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
std::tuple<int, std::optional<QSqlQuery>>
|
||||
ModelProxies<Derived, AllRelations...>::touchAll(const QString &column)
|
||||
{
|
||||
return query()->touch(column);
|
||||
}
|
||||
|
||||
/* Select */
|
||||
|
||||
template<typename Derived, AllRelationsConcept ...AllRelations>
|
||||
|
||||
@@ -191,6 +191,10 @@ namespace Orm::Tiny
|
||||
Model updateOrCreate(const QVector<WhereItem> &attributes,
|
||||
const QVector<AttributeItem> &values = {});
|
||||
|
||||
/*! Update the column's update timestamp. */
|
||||
std::tuple<int, std::optional<QSqlQuery>>
|
||||
touch(const QString &column = "");
|
||||
|
||||
/* QueryBuilder proxy methods that need modifications */
|
||||
/*! Update records in the database. */
|
||||
std::tuple<int, QSqlQuery>
|
||||
@@ -838,6 +842,23 @@ namespace Orm::Tiny
|
||||
return instance;
|
||||
}
|
||||
|
||||
template<typename Model>
|
||||
std::tuple<int, std::optional<QSqlQuery>>
|
||||
Builder<Model>::touch(const QString &column)
|
||||
{
|
||||
auto time = m_model.freshTimestamp();
|
||||
|
||||
if (!column.isEmpty())
|
||||
return toBase().update({{column, std::move(time)}});
|
||||
|
||||
const auto &updatedAtColumn = m_model.getUpdatedAtColumn();
|
||||
|
||||
if (!m_model.usesTimestamps() || updatedAtColumn.isEmpty())
|
||||
return {0, std::nullopt};
|
||||
|
||||
return toBase().update({{updatedAtColumn, std::move(time)}});
|
||||
}
|
||||
|
||||
/* QueryBuilder proxy methods that need modifications */
|
||||
|
||||
template<typename Model>
|
||||
|
||||
@@ -39,6 +39,10 @@ class tst_MySql_TinyBuilder : public QObject // clazy:exclude=ctor-missing-paren
|
||||
private slots:
|
||||
void initTestCase();
|
||||
|
||||
void touch() const;
|
||||
void touch_CustomColumn() const;
|
||||
void touch_NotUsesTimestamps() const;
|
||||
|
||||
/* Querying Relationship Existence/Absence on HasMany */
|
||||
void has_Basic_OnHasMany() const;
|
||||
void has_Count_OnHasMany() const;
|
||||
@@ -113,6 +117,79 @@ void tst_MySql_TinyBuilder::initTestCase()
|
||||
.toUtf8().constData(), );
|
||||
}
|
||||
|
||||
void tst_MySql_TinyBuilder::touch() const
|
||||
{
|
||||
auto timeBeforeTouch = QDateTime::currentDateTime();
|
||||
// Reset milliseconds to 0
|
||||
{
|
||||
auto time = timeBeforeTouch.time();
|
||||
timeBeforeTouch.setTime(QTime(time.hour(), time.minute(), time.second()));
|
||||
}
|
||||
|
||||
auto log = DB::connection(m_connection).pretend([this]
|
||||
{
|
||||
User::on(m_connection)
|
||||
->whereEq("status", "new")
|
||||
.touch();
|
||||
});
|
||||
|
||||
QCOMPARE(log.size(), 1);
|
||||
const auto &firstLog = log.first();
|
||||
|
||||
QCOMPARE(firstLog.query,
|
||||
"update `users` "
|
||||
"set `updated_at` = ? "
|
||||
"where `status` = ? and `users`.`deleted_at` is null");
|
||||
QVERIFY(firstLog.boundValues.size() == 2);
|
||||
QVERIFY(firstLog.boundValues.at(0).value<QDateTime>() >= timeBeforeTouch);
|
||||
QCOMPARE(firstLog.boundValues.at(1), QVariant(QString("new")));
|
||||
}
|
||||
|
||||
void tst_MySql_TinyBuilder::touch_CustomColumn() const
|
||||
{
|
||||
auto timeBeforeTouch = QDateTime::currentDateTime();
|
||||
// Reset milliseconds to 0
|
||||
{
|
||||
auto time = timeBeforeTouch.time();
|
||||
timeBeforeTouch.setTime(QTime(time.hour(), time.minute(), time.second()));
|
||||
}
|
||||
|
||||
auto log = DB::connection(m_connection).pretend([this]
|
||||
{
|
||||
User::on(m_connection)
|
||||
->whereEq("status", "new")
|
||||
.touch("updated_on");
|
||||
});
|
||||
|
||||
QCOMPARE(log.size(), 1);
|
||||
const auto &firstLog = log.first();
|
||||
|
||||
QCOMPARE(firstLog.query,
|
||||
"update `users` "
|
||||
"set `updated_on` = ? "
|
||||
"where `status` = ? and `users`.`deleted_at` is null");
|
||||
QVERIFY(firstLog.boundValues.size() == 2);
|
||||
QVERIFY(firstLog.boundValues.at(0).value<QDateTime>() >= timeBeforeTouch);
|
||||
QCOMPARE(firstLog.boundValues.at(1), QVariant(QString("new")));
|
||||
}
|
||||
|
||||
void tst_MySql_TinyBuilder::touch_NotUsesTimestamps() const
|
||||
{
|
||||
int affected = -1;
|
||||
std::optional<QSqlQuery> query = std::nullopt;
|
||||
|
||||
auto log = DB::connection(m_connection).pretend([this, &affected, &query]
|
||||
{
|
||||
std::tie(affected, query) = Phone::on(m_connection)
|
||||
->whereEq("status", "new")
|
||||
.touch();
|
||||
});
|
||||
|
||||
QVERIFY(log.isEmpty());
|
||||
QCOMPARE(affected, 0);
|
||||
QCOMPARE(query, std::nullopt);
|
||||
}
|
||||
|
||||
void tst_MySql_TinyBuilder::has_Basic_OnHasMany() const
|
||||
{
|
||||
auto builder = createTinyQuery<Torrent>();
|
||||
|
||||
Reference in New Issue
Block a user