sqlite passed tst_datetime

This commit is contained in:
Hamed Masafi 2019-07-07 12:20:49 +04:30
parent f02e409ee2
commit 3cee4dae4f
7 changed files with 195 additions and 22 deletions

View File

@ -788,12 +788,24 @@ void SqlGeneratorBase::removeTableNames(QString &command)
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";
case PhraseData::AddYears:
case PhraseData::AddYearsDateTime:
return "YEAR";
case PhraseData::AddMonths:
case PhraseData::AddMonthsDateTime:
return "MONTH";
case PhraseData::AddDays:
case PhraseData::AddDaysDateTime:
return "DAY";
case PhraseData::AddHours:
case PhraseData::AddHoursDateTime:
return "HOUR";
case PhraseData::AddMinutes:
case PhraseData::AddMinutesDateTime:
return "MINUTE";
case PhraseData::AddSeconds:
case PhraseData::AddSecondsDateTime:
return "SECOND";
}
return QString();
}

View File

@ -219,22 +219,73 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
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:
case PhraseData::AddDays: {
int i = d->operand.toInt();
return QString("DATE(%1,'%2 %3')")
.arg(createConditionalPhrase(d->left),
(i < 0 ? "-" : "+") + QString::number(i),
(i < 0 ? "" : "+") + QString::number(i),
dateTimePartName(op));
break;
}
case PhraseData::AddHours:
case PhraseData::AddMinutes:
case PhraseData::AddSeconds: {
int i = d->operand.toInt();
return QString("TIME(%1,'%2 %3')")
.arg(createConditionalPhrase(d->left),
(i < 0 ? "" : "+") + QString::number(i),
dateTimePartName(op));
break;
}
case PhraseData::AddYearsDateTime:
case PhraseData::AddMonthsDateTime:
case PhraseData::AddDaysDateTime:
case PhraseData::AddHoursDateTime:
case PhraseData::AddMinutesDateTime:
case PhraseData::AddSecondsDateTime: {
int i = d->operand.toInt();
return QString("DATETIME(%1,'%2 %3')")
.arg(createConditionalPhrase(d->left),
(i < 0 ? "" : "+") + QString::number(i),
dateTimePartName(op));
break;
}
}
}
return SqlGeneratorBase::createConditionalPhrase(d);
}
QString SqliteGenerator::escapeValue(const QVariant &v) const
{
if (v.type() == QVariant::Time)
return "'" + v.toTime().toString("HH:mm:ss") + "'";
if (v.type() == QVariant::Date)
return "'" + v.toDate().toString("yyyy-MM-dd") + "'";
if (v.type() == QVariant::DateTime)
return "'" + v.toDateTime().toString("yyyy-MM-dd HH:mm:ss") + "'";
return SqlGeneratorBase::escapeValue(v);
}
QVariant SqliteGenerator::unescapeValue(const QMetaType::Type &type, const QVariant &dbValue)
{
if (type == QMetaType::QDateTime)
return dbValue.toDateTime();
if (type == QMetaType::QTime)
return dbValue.toTime();
if (type == QMetaType::QDate)
return dbValue.toDate();
return SqlGeneratorBase::unescapeValue(type, dbValue);
}
NUT_END_NAMESPACE

View File

@ -42,6 +42,9 @@ public:
QStringList diff(TableModel *oldTable, TableModel *newTable) override;
QString createConditionalPhrase(const PhraseData *d) const override;
QString escapeValue(const QVariant &v) const override;
QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue) override;
};
NUT_END_NAMESPACE

View File

@ -102,32 +102,45 @@ public:
ConditionalPhrase addYears(int val) {
if (!is_valid_template<T, QDate>())
return ConditionalPhrase();
if (std::is_same<T, QDateTime>::value)
return ConditionalPhrase(this, PhraseData::AddYearsDateTime, val);
return ConditionalPhrase(this, PhraseData::AddYears, val);
}
ConditionalPhrase addMonths(int val) {
if (!is_valid_template<T, QDate>())
return ConditionalPhrase();
if (std::is_same<T, QDateTime>::value)
return ConditionalPhrase(this, PhraseData::AddMonthsDateTime, val);
return ConditionalPhrase(this, PhraseData::AddMonths, val);
}
ConditionalPhrase addDays(int val) {
if (!is_valid_template<T, QDate>())
return ConditionalPhrase();
if (std::is_same<T, QDateTime>::value)
return ConditionalPhrase(this, PhraseData::AddDaysDateTime, val);
return ConditionalPhrase(this, PhraseData::AddDays, val);
}
ConditionalPhrase addHours(int val) {
if (!is_valid_template<T, QTime>())
return ConditionalPhrase();
if (std::is_same<T, QDateTime>::value)
return ConditionalPhrase(this, PhraseData::AddHoursDateTime, val);
return ConditionalPhrase(this, PhraseData::AddHours, val);
}
ConditionalPhrase addMinutes(int val) {
if (!is_valid_template<T, QTime>())
return ConditionalPhrase();
if (std::is_same<T, QDateTime>::value)
return ConditionalPhrase(this, PhraseData::AddMinutesDateTime, val);
return ConditionalPhrase(this, PhraseData::AddMinutes, val);
}
ConditionalPhrase addSeconds(int val) {
if (!is_valid_template<T, QTime>())
return ConditionalPhrase();
if (std::is_same<T, QDateTime>::value)
return ConditionalPhrase(this, PhraseData::AddSecondsDateTime, val);
return ConditionalPhrase(this, PhraseData::AddSeconds, val);
}

View File

@ -64,6 +64,14 @@ public:
AddMinutes,
AddSeconds,
// sqlite need to know works with qdate, qtime or qdatetime
AddYearsDateTime,
AddMonthsDateTime,
AddDaysDateTime,
AddHoursDateTime,
AddMinutesDateTime,
AddSecondsDateTime,
DatePartYear,
DatePartMonth,
DatePartDay,

View File

@ -35,19 +35,103 @@ void DateTimeTest::initTestCase()
db.sampleTables()->query()->remove();
}
void DateTimeTest::date()
#define TEST_DATE(date, command, n) \
do { \
auto s = Nut::create<SampleTable>(); \
s->setD(date); \
db.sampleTables()->append(s); \
db.saveChanges(); \
auto count = db.sampleTables()->query() \
->where(SampleTable::dField().command(n) == date.command(n)) \
->count(); \
QTEST_ASSERT(count); \
} while (false)
#define TEST_TIME(time, command, n, num) \
do { \
auto s = Nut::create<SampleTable>(); \
s->setT(time); \
db.sampleTables()->append(s); \
db.saveChanges(); \
auto count = db.sampleTables()->query() \
->where(SampleTable::tField().command(n) == time.addSecs(num)) \
->count(); \
QTEST_ASSERT(count); \
} while (false)
#define TEST_DATE2(datetime, command, n) \
do { \
auto s = Nut::create<SampleTable>(); \
s->setDT(datetime); \
db.sampleTables()->append(s); \
db.saveChanges(); \
auto count = db.sampleTables()->query() \
->where(SampleTable::dtField().command(n) == datetime.command(n)); \
->count(); \
QTEST_ASSERT(count); \
} while (false)
#define TEST_TIME2(datetime, command, n, num) \
do { \
auto s = Nut::create<SampleTable>(); \
s->setDT(datetime); \
db.sampleTables()->append(s); \
db.saveChanges(); \
auto count = db.sampleTables()->query() \
->where(SampleTable::dtField().command(n) == datetime.addSecs(num)); \
->count(); \
QTEST_ASSERT(count); \
} while (false)
#define MINUTE(m) m * 60
#define HOUR(h) MINUTE(h) * 60
void DateTimeTest::dateAdd()
{
auto s = Nut::create<SampleTable>();
s->setD(_baseDateTime.addDays(10).date());
db.sampleTables()->append(s);
db.saveChanges();
QDate d = QDate::currentDate();
auto q = db.sampleTables()->query()
->where(SampleTable::dField().addDays(9) < QDate::currentDate().addDays(10));
TEST_DATE(d, addYears, 10);
TEST_DATE(d, addMonths, 10);
TEST_DATE(d, addDays, 10);
auto count = q->count();
qDebug() << q->sqlCommand();
QTEST_ASSERT(count);
TEST_DATE(d, addYears, -10);
TEST_DATE(d, addMonths, -10);
TEST_DATE(d, addDays, -10);
}
void DateTimeTest::timeAdd()
{
QTime t = QTime::currentTime();
TEST_TIME(t, addHours, 10, HOUR(10));
TEST_TIME(t, addMinutes, 10, MINUTE(10));
TEST_TIME(t, addSeconds, 10, 10);
TEST_TIME(t, addHours, -10, HOUR(-10));
TEST_TIME(t, addMinutes, -10, MINUTE(-10));
TEST_TIME(t, addSeconds, -10, -10);
}
void DateTimeTest::dateTimeAdd()
{
QDateTime dt = QDateTime::currentDateTime();
TEST_DATE2(dt, addYears, 10);
TEST_DATE2(dt, addMonths, 10);
TEST_DATE2(dt, addDays, 10);
TEST_DATE2(dt, addYears, -10);
TEST_DATE2(dt, addMonths, -10);
TEST_DATE2(dt, addDays, -10);
TEST_TIME2(dt, addHours, 10, HOUR(10));
TEST_TIME2(dt, addMinutes, 10, MINUTE(10));
TEST_TIME2(dt, addSeconds, 10, 10);
TEST_TIME2(dt, addHours, -10, HOUR(-10));
TEST_TIME2(dt, addMinutes, -10, MINUTE(-10));
TEST_TIME2(dt, addSeconds, -10, -10);
}
void DateTimeTest::cleanupTestCase()

View File

@ -30,7 +30,9 @@ signals:
private slots:
void initTestCase();
void date();
void dateAdd();
void timeAdd();
void dateTimeAdd();
void cleanupTestCase();
};