wip: date time functions
This commit is contained in:
parent
73c5295f6d
commit
f02e409ee2
|
|
@ -290,4 +290,41 @@ bool MySqlGenerator::readInsideParentese(QString &text, QString &out)
|
||||||
// return command;
|
// return command;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
QString MySqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
|
{
|
||||||
|
if (!d)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
PhraseData::Condition op = d->operatorCond;
|
||||||
|
//apply not (!)
|
||||||
|
if (d->isNot) {
|
||||||
|
if (op < 20)
|
||||||
|
op = static_cast<PhraseData::Condition>((op + 10) % 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->type == PhraseData::WithVariant) {
|
||||||
|
if (op == PhraseData::AddYears)
|
||||||
|
return QString("DATE_ADD(%2, INTERVAL %1 YEAR)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddMonths)
|
||||||
|
return QString("DATE_ADD(%2, INTERVAL %1 MONTH)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddDays)
|
||||||
|
return QString("DATE_ADD(%2, INTERVAL %1 DAY)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddHours)
|
||||||
|
return QString("DATE_ADD(%2, INTERVAL %1 HOUR)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddMinutes)
|
||||||
|
return QString("DATE_ADD(%2, INTERVAL %1 MINUTE)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddSeconds)
|
||||||
|
return QString("DATE_ADD(%2, INTERVAL %1 SECOND)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return SqlGeneratorBase::createConditionalPhrase(d);
|
||||||
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,12 @@ class MySqlGenerator : public SqlGeneratorBase
|
||||||
public:
|
public:
|
||||||
explicit MySqlGenerator(Database *parent = 0);
|
explicit MySqlGenerator(Database *parent = 0);
|
||||||
|
|
||||||
QString fieldType(FieldModel *field);
|
QString fieldType(FieldModel *field) override;
|
||||||
QString escapeValue(const QVariant &v) const;
|
QString escapeValue(const QVariant &v) const override;
|
||||||
QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue);
|
QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue) override;
|
||||||
// QString phrase(const PhraseData *d) const;
|
// QString phrase(const PhraseData *d) const;
|
||||||
// QString selectCommand(AgregateType t, QString agregateArg, QString tableName, QList<WherePhrase> &wheres, QList<WherePhrase> &orders, QList<RelationModel *> joins, int skip, int take);
|
// QString selectCommand(AgregateType t, QString agregateArg, QString tableName, QList<WherePhrase> &wheres, QList<WherePhrase> &orders, QList<RelationModel *> joins, int skip, int take);
|
||||||
|
QString createConditionalPhrase(const PhraseData *d) const override;
|
||||||
private:
|
private:
|
||||||
bool readInsideParentese(QString &text, QString &out);
|
bool readInsideParentese(QString &text, QString &out);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -328,12 +328,38 @@ QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
if (!d)
|
if (!d)
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
|
PhraseData::Condition op = d->operatorCond;
|
||||||
|
//apply not (!)
|
||||||
|
if (d->isNot) {
|
||||||
|
if (op < 20)
|
||||||
|
op = static_cast<PhraseData::Condition>((op + 10) % 20);
|
||||||
|
}
|
||||||
|
|
||||||
if (d->type == PhraseData::WithVariant) {
|
if (d->type == PhraseData::WithVariant) {
|
||||||
if (isPostGisType(d->operand.type()) && d->operatorCond == PhraseData::Equal) {
|
if (isPostGisType(d->operand.type()) && d->operatorCond == PhraseData::Equal) {
|
||||||
return QString("%1 ~= %2")
|
return QString("%1 ~= %2")
|
||||||
.arg(SqlGeneratorBase::createConditionalPhrase(d->left),
|
.arg(SqlGeneratorBase::createConditionalPhrase(d->left),
|
||||||
escapeValue(d->operand));
|
escapeValue(d->operand));
|
||||||
}
|
}
|
||||||
|
if (op == PhraseData::AddYears)
|
||||||
|
return QString("DATEADD(year, %1, %2)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddMonths)
|
||||||
|
return QString("DATEADD(month, %1, %2)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddDays)
|
||||||
|
return QString("DATEADD(day, %1, %2)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddHours)
|
||||||
|
return QString("DATEADD(hour, %1, %2)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddMinutes)
|
||||||
|
return QString("DATEADD(minute, %1, %2)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
else if (op == PhraseData::AddSeconds)
|
||||||
|
return QString("DATEADD(second, %1, %2)")
|
||||||
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SqlGeneratorBase::createConditionalPhrase(d);
|
return SqlGeneratorBase::createConditionalPhrase(d);
|
||||||
|
|
|
||||||
|
|
@ -785,6 +785,19 @@ void SqlGeneratorBase::removeTableNames(QString &command)
|
||||||
command = command.replace("[" + m->className() + "].", "");
|
command = command.replace("[" + m->className() + "].", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SqlGeneratorBase::dateTimePartName(const PhraseData::Condition &op) const
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case PhraseData::AddYears: return "YEAR";
|
||||||
|
case PhraseData::AddMonths: return "MONTH";
|
||||||
|
case PhraseData::AddDays: return "DAY";
|
||||||
|
case PhraseData::AddHours: return "HOUR";
|
||||||
|
case PhraseData::AddMinutes: return "MINUTE";
|
||||||
|
case PhraseData::AddSeconds: return "SECOND";
|
||||||
|
}
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
//QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
|
//QString SqlGeneratorBase::deleteCommand(QList<WherePhrase> &wheres,
|
||||||
// QString tableName)
|
// QString tableName)
|
||||||
//{
|
//{
|
||||||
|
|
@ -973,7 +986,7 @@ QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PhraseData::WithVariant:
|
case PhraseData::WithVariant:
|
||||||
if (op == PhraseData::AddYears)
|
/* if (op == PhraseData::AddYears)
|
||||||
ret = QString("DATEADD(year, %1, %2)")
|
ret = QString("DATEADD(year, %1, %2)")
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
else if (op == PhraseData::AddMonths)
|
else if (op == PhraseData::AddMonths)
|
||||||
|
|
@ -991,7 +1004,7 @@ QString SqlGeneratorBase::createConditionalPhrase(const PhraseData *d) const
|
||||||
else if (op == PhraseData::AddSeconds)
|
else if (op == PhraseData::AddSeconds)
|
||||||
ret = QString("DATEADD(second, %1, %2)")
|
ret = QString("DATEADD(second, %1, %2)")
|
||||||
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
.arg(d->operand.toString(), createConditionalPhrase(d->left));
|
||||||
else if (op == PhraseData::Between) {
|
else */if (op == PhraseData::Between) {
|
||||||
QVariantList list = d->operand.toList();
|
QVariantList list = d->operand.toList();
|
||||||
ret = QString("%1 BETWEEN %2 AND %3")
|
ret = QString("%1 BETWEEN %2 AND %3")
|
||||||
.arg(createConditionalPhrase(d->left), escapeValue(list.at(0)), escapeValue(list.at(1)));
|
.arg(createConditionalPhrase(d->left), escapeValue(list.at(0)), escapeValue(list.at(1)));
|
||||||
|
|
|
||||||
|
|
@ -162,6 +162,7 @@ protected:
|
||||||
|
|
||||||
void replaceTableNames(QString &command);
|
void replaceTableNames(QString &command);
|
||||||
void removeTableNames(QString &command);
|
void removeTableNames(QString &command);
|
||||||
|
QString dateTimePartName(const PhraseData::Condition &op) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -205,4 +205,36 @@ QString SqliteGenerator::primaryKeyConstraint(const TableModel *table) const
|
||||||
// return sql;
|
// return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
|
{
|
||||||
|
if (!d)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
PhraseData::Condition op = d->operatorCond;
|
||||||
|
//apply not (!)
|
||||||
|
if (d->isNot) {
|
||||||
|
if (op < 20)
|
||||||
|
op = static_cast<PhraseData::Condition>((op + 10) % 20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->type == PhraseData::WithVariant) {
|
||||||
|
QString part;
|
||||||
|
switch (op) {
|
||||||
|
case PhraseData::AddYears:
|
||||||
|
case PhraseData::AddMonths:
|
||||||
|
case PhraseData::AddDays:
|
||||||
|
case PhraseData::AddHours:
|
||||||
|
case PhraseData::AddMinutes:
|
||||||
|
case PhraseData::AddSeconds:
|
||||||
|
int i = d->operand.toInt();
|
||||||
|
return QString("DATE(%1,'%2 %3')")
|
||||||
|
.arg(createConditionalPhrase(d->left),
|
||||||
|
(i < 0 ? "-" : "+") + QString::number(i),
|
||||||
|
dateTimePartName(op));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return SqlGeneratorBase::createConditionalPhrase(d);
|
||||||
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ public:
|
||||||
QString primaryKeyConstraint(const TableModel *table) const override;
|
QString primaryKeyConstraint(const TableModel *table) const override;
|
||||||
QStringList diff(TableModel *oldTable, TableModel *newTable) override;
|
QStringList diff(TableModel *oldTable, TableModel *newTable) override;
|
||||||
|
|
||||||
|
QString createConditionalPhrase(const PhraseData *d) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -61,9 +61,11 @@ int TableSetBase::save(Database *db, bool cleanUp)
|
||||||
|| t->status() == Table::Modified
|
|| t->status() == Table::Modified
|
||||||
|| t->status() == Table::Deleted){
|
|| t->status() == Table::Deleted){
|
||||||
rowsAffected += t->save(db);
|
rowsAffected += t->save(db);
|
||||||
#ifndef NUT_SHARED_POINTER
|
|
||||||
if(cleanUp)
|
if(cleanUp)
|
||||||
|
#ifndef NUT_SHARED_POINTER
|
||||||
t->deleteLater();
|
t->deleteLater();
|
||||||
|
#else
|
||||||
|
remove(t);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,6 @@ SUBDIRS += \
|
||||||
tst_quuid \
|
tst_quuid \
|
||||||
tst_generators \
|
tst_generators \
|
||||||
tst_upgrades \
|
tst_upgrades \
|
||||||
tst_json
|
tst_json \
|
||||||
|
tst_datetime
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
#include "db.h"
|
||||||
|
|
||||||
|
#include "sampletable.h"
|
||||||
|
|
||||||
|
DB::DB() : Nut::Database (),
|
||||||
|
m_sampleTables(new Nut::TableSet<SampleTable>(this))
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
#ifndef DB_H
|
||||||
|
#define DB_H
|
||||||
|
|
||||||
|
#include "database.h"
|
||||||
|
|
||||||
|
class SampleTable;
|
||||||
|
class DB : public Nut::Database
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
NUT_DB_VERSION(1)
|
||||||
|
|
||||||
|
NUT_DECLARE_TABLE(SampleTable, sampleTables)
|
||||||
|
|
||||||
|
public:
|
||||||
|
DB();
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(DB*)
|
||||||
|
|
||||||
|
#endif // DB_H
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include "sampletable.h"
|
||||||
|
|
||||||
|
SampleTable::SampleTable(QObject *parent) : Nut::Table (parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
#ifndef SAMPLETABLE_H
|
||||||
|
#define SAMPLETABLE_H
|
||||||
|
|
||||||
|
#include <QTime>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QDate>
|
||||||
|
|
||||||
|
#include "table.h"
|
||||||
|
|
||||||
|
class SampleTable : public Nut::Table
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
NUT_PRIMARY_AUTO_INCREMENT(id)
|
||||||
|
NUT_DECLARE_FIELD(int, id, id, setId)
|
||||||
|
|
||||||
|
NUT_DECLARE_FIELD(QDate, d, d, setD)
|
||||||
|
NUT_DECLARE_FIELD(QTime, t, t, setT)
|
||||||
|
NUT_DECLARE_FIELD(QDateTime, dt, dt, setDT)
|
||||||
|
|
||||||
|
public:
|
||||||
|
Q_INVOKABLE SampleTable(QObject *parent = Q_NULLPTR);
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(SampleTable*)
|
||||||
|
|
||||||
|
#endif // SAMPLETABLE_H
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
#include <QtTest>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QSqlError>
|
||||||
|
#include <QElapsedTimer>
|
||||||
|
|
||||||
|
#include "consts.h"
|
||||||
|
|
||||||
|
#include "tst_datetime.h"
|
||||||
|
#include "query.h"
|
||||||
|
#include "tableset.h"
|
||||||
|
#include "tablemodel.h"
|
||||||
|
#include "databasemodel.h"
|
||||||
|
|
||||||
|
#include "sampletable.h"
|
||||||
|
|
||||||
|
DateTimeTest::DateTimeTest(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
_baseDateTime = QDateTime::currentDateTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateTimeTest::initTestCase()
|
||||||
|
{
|
||||||
|
//register all entities with Qt-MetaType mechanism
|
||||||
|
REGISTER(SampleTable);
|
||||||
|
REGISTER(DB);
|
||||||
|
|
||||||
|
db.setDriver(DRIVER);
|
||||||
|
db.setHostName(HOST);
|
||||||
|
db.setDatabaseName(DATABASE);
|
||||||
|
db.setUserName(USERNAME);
|
||||||
|
db.setPassword(PASSWORD);
|
||||||
|
|
||||||
|
QTEST_ASSERT(db.open());
|
||||||
|
|
||||||
|
db.sampleTables()->query()->remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateTimeTest::date()
|
||||||
|
{
|
||||||
|
auto s = Nut::create<SampleTable>();
|
||||||
|
s->setD(_baseDateTime.addDays(10).date());
|
||||||
|
db.sampleTables()->append(s);
|
||||||
|
db.saveChanges();
|
||||||
|
|
||||||
|
auto q = db.sampleTables()->query()
|
||||||
|
->where(SampleTable::dField().addDays(9) < QDate::currentDate().addDays(10));
|
||||||
|
|
||||||
|
auto count = q->count();
|
||||||
|
qDebug() << q->sqlCommand();
|
||||||
|
QTEST_ASSERT(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DateTimeTest::cleanupTestCase()
|
||||||
|
{
|
||||||
|
db.sampleTables()->query()->remove();
|
||||||
|
db.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
QTEST_MAIN(DateTimeTest)
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef MAINTEST_H
|
||||||
|
#define MAINTEST_H
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/qglobal.h>
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QJsonArray>
|
||||||
|
#include <QJsonDocument>
|
||||||
|
#include <QJsonObject>
|
||||||
|
#ifdef QT_GUI_LIB
|
||||||
|
#include <QColor>
|
||||||
|
#include <QPolygonF>
|
||||||
|
#endif
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QUuid>
|
||||||
|
|
||||||
|
#include "db.h"
|
||||||
|
class DateTimeTest : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
DB db;
|
||||||
|
|
||||||
|
QDateTime _baseDateTime;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DateTimeTest(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void initTestCase();
|
||||||
|
void date();
|
||||||
|
void cleanupTestCase();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // MAINTEST_H
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
QT += testlib sql gui
|
||||||
|
|
||||||
|
TARGET = tst_datetime
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
|
CONFIG += warn_on c++11
|
||||||
|
|
||||||
|
include(../common/nut-lib.pri)
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
db.cpp \
|
||||||
|
sampletable.cpp \
|
||||||
|
tst_datetime.cpp
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
db.h \
|
||||||
|
sampletable.h \
|
||||||
|
tst_datetime.h
|
||||||
|
|
||||||
|
include($$PWD/../../ci-test-init.pri)
|
||||||
Loading…
Reference in New Issue