Compare commits
10 Commits
3a9f4c1234
...
2d950fb026
| Author | SHA1 | Date |
|---|---|---|
|
|
2d950fb026 | |
|
|
16d485b1ed | |
|
|
0de2161935 | |
|
|
48084f741b | |
|
|
52ec19ef1e | |
|
|
087d24e7b6 | |
|
|
8ee381d991 | |
|
|
7ca5d62cc9 | |
|
|
ba25bcb8c2 | |
|
|
4f341e07ac |
|
|
@ -1 +1 @@
|
||||||
set(QT_REPO_MODULE_VERSION "0.7.0")
|
set(QT_REPO_MODULE_VERSION "6.7.2")
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,16 @@
|
||||||
name: CI Build
|
name: CI Build
|
||||||
|
|
||||||
on:
|
on: [push]
|
||||||
push:
|
|
||||||
branches-ignore:
|
|
||||||
- "releases/**"
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
pull_request:
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
qt_version: [5.12.11, 5.15.2, 6.2.0]
|
qt_version: [5.15.2, 6.4.0]
|
||||||
platform: [ubuntu-20.04, windows-latest, macos-latest]
|
platform: [ubuntu-20.04, windows-latest, macos-latest]
|
||||||
include:
|
include:
|
||||||
- qt_version: 6.2.0
|
- qt_version: 6.4.0
|
||||||
additional_arguments: -D QT_DEFAULT_MAJOR_VERSION=6
|
additional_arguments: -D QT_DEFAULT_MAJOR_VERSION=6
|
||||||
build_cmake: true
|
build_cmake: true
|
||||||
- platform: ubuntu-20.04
|
- platform: ubuntu-20.04
|
||||||
|
|
@ -93,7 +85,7 @@ jobs:
|
||||||
cmake --build .
|
cmake --build .
|
||||||
|
|
||||||
- name: Seutp postgres
|
- name: Seutp postgres
|
||||||
if: false #contains(matrix.tests, 'posgtresql')
|
if: contains(matrix.tests, 'posgtresql')
|
||||||
uses: ikalnytskyi/action-setup-postgres@v1
|
uses: ikalnytskyi/action-setup-postgres@v1
|
||||||
|
|
||||||
- name: Setup sql server
|
- name: Setup sql server
|
||||||
|
|
@ -105,7 +97,7 @@ jobs:
|
||||||
show-log: true
|
show-log: true
|
||||||
|
|
||||||
- name: Check sql server
|
- name: Check sql server
|
||||||
if: false #contains(matrix.tests, 'mssql')
|
if: contains(matrix.tests, 'mssql')
|
||||||
run: sqlcmd -S localhost -U sa -P NUT_sa_PASS_1_??? -d tempdb -Q "SELECT @@version;"
|
run: sqlcmd -S localhost -U sa -P NUT_sa_PASS_1_??? -d tempdb -Q "SELECT @@version;"
|
||||||
|
|
||||||
- name: Run tests with sqlite
|
- name: Run tests with sqlite
|
||||||
|
|
@ -129,7 +121,7 @@ jobs:
|
||||||
${{ matrix.make }} run-tests
|
${{ matrix.make }} run-tests
|
||||||
|
|
||||||
- name: Run tests with mysql
|
- name: Run tests with mysql
|
||||||
if: contains(matrix.tests, 'mysql')
|
if: false #contains(matrix.tests, 'mysql')
|
||||||
#continue-on-error: true
|
#continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
sudo systemctl start mysql.service
|
sudo systemctl start mysql.service
|
||||||
|
|
@ -140,7 +132,7 @@ jobs:
|
||||||
${{ matrix.make }} run-tests
|
${{ matrix.make }} run-tests
|
||||||
|
|
||||||
- name: Run tests with sql server
|
- name: Run tests with sql server
|
||||||
if: contains(matrix.tests, 'mssql')
|
if: false #contains(matrix.tests, 'mssql')
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
run: |
|
run: |
|
||||||
rm tests/auto/common/test_params.h
|
rm tests/auto/common/test_params.h
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ cmake_minimum_required(VERSION 3.16)
|
||||||
set(CMAKE_AUTOMOC ON)
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
include(.cmake.conf)
|
include(.cmake.conf)
|
||||||
project(Nut
|
project(QtNut
|
||||||
VERSION "0.7.0"
|
VERSION "${QT_REPO_MODULE_VERSION}"
|
||||||
DESCRIPTION "Nut"
|
DESCRIPTION "Qt orm library"
|
||||||
HOMEPAGE_URL "https://github.com/HamedMasafi/Nut"
|
HOMEPAGE_URL "https://github.com/HamedMasafi/Nut"
|
||||||
LANGUAGES CXX C
|
LANGUAGES CXX C
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,17 @@ qt_internal_add_module(Nut
|
||||||
phrases/phrasedata.cpp phrases/phrasedata.h
|
phrases/phrasedata.cpp phrases/phrasedata.h
|
||||||
phrases/phrasedatalist.cpp phrases/phrasedatalist.h
|
phrases/phrasedatalist.cpp phrases/phrasedatalist.h
|
||||||
phrases/phraselist.cpp phrases/phraselist.h
|
phrases/phraselist.cpp phrases/phraselist.h
|
||||||
|
phrases/numericphrase.cpp phrases/numericphrase.h
|
||||||
types/dbgeography.cpp types/dbgeography.h
|
types/dbgeography.cpp types/dbgeography.h
|
||||||
|
|
||||||
|
NutGlobal
|
||||||
DEFINES
|
DEFINES
|
||||||
NUT_BUILD_LIB
|
NUT_BUILD_LIB
|
||||||
NUT_SHARED
|
NUT_SHARED
|
||||||
NUT_SHARED_POINTER
|
NUT_SHARED_POINTER
|
||||||
QT_DEPRECATED_WARNINGS
|
QT_DEPRECATED_WARNINGS
|
||||||
INCLUDE_DIRECTORIES
|
INCLUDE_DIRECTORIES
|
||||||
|
.
|
||||||
config
|
config
|
||||||
core
|
core
|
||||||
generators
|
generators
|
||||||
|
|
@ -59,6 +63,7 @@ qt_internal_add_module(Nut
|
||||||
Qt::Core
|
Qt::Core
|
||||||
Qt::Gui
|
Qt::Gui
|
||||||
Qt::Sql
|
Qt::Sql
|
||||||
|
GENERATE_CPP_EXPORTS
|
||||||
)
|
)
|
||||||
|
|
||||||
#### Keys ignored in scope 1:.:.:nut.pro:<TRUE>:
|
#### Keys ignored in scope 1:.:.:nut.pro:<TRUE>:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
#include "config/nut_global.h"
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include <QWeakPointer>
|
#include <QWeakPointer>
|
||||||
|
#include <QList>
|
||||||
|
#include <QMutableListIterator>
|
||||||
|
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
|
|
@ -57,19 +59,16 @@ int AbstractTableSet::save(Database *db)
|
||||||
masterModel = db->model().tableByClassName(
|
masterModel = db->model().tableByClassName(
|
||||||
QString::fromUtf8(data->table->metaObject()->className()));
|
QString::fromUtf8(data->table->metaObject()->className()));
|
||||||
|
|
||||||
QMutableListIterator<QWeakPointer<Table>> weaks(data->weakChildren);
|
//TODO: find a better replacement for QMutableListIterator
|
||||||
while (weaks.hasNext()) {
|
auto tmp = data->weakChildren;
|
||||||
auto &row = weaks.next();
|
data->weakChildren.clear();
|
||||||
|
for (auto &w: tmp) {
|
||||||
|
|
||||||
if (!row) {
|
if (!w)
|
||||||
weaks.remove();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
auto t = w.lock();
|
||||||
auto t = row.lock();
|
if (t.isNull())
|
||||||
if (t.isNull()) {
|
|
||||||
weaks.remove();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (data->table)
|
if (data->table)
|
||||||
t->setParentTable(data->table,
|
t->setParentTable(data->table,
|
||||||
|
|
@ -81,16 +80,15 @@ int AbstractTableSet::save(Database *db)
|
||||||
|| t->status() == Table::Deleted) {
|
|| t->status() == Table::Deleted) {
|
||||||
rowsAffected += t->save(db);
|
rowsAffected += t->save(db);
|
||||||
}
|
}
|
||||||
|
data->weakChildren << w;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMutableListIterator<QSharedPointer<Table>> childs(data->children);
|
auto tmp2 = data->children;
|
||||||
|
data->children.clear();
|
||||||
|
|
||||||
while (childs.hasNext()) {
|
for (auto &row : tmp2) {
|
||||||
auto &row = childs.next();
|
if (!row)
|
||||||
if (!row) {
|
|
||||||
childs.remove();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (data->table)
|
if (data->table)
|
||||||
row->setParentTable(data->table,
|
row->setParentTable(data->table,
|
||||||
|
|
@ -103,9 +101,9 @@ int AbstractTableSet::save(Database *db)
|
||||||
rowsAffected += row->save(db);
|
rowsAffected += row->save(db);
|
||||||
data->weakChildren.append(row.toWeakRef());
|
data->weakChildren.append(row.toWeakRef());
|
||||||
|
|
||||||
childs.remove();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
data->children << row;
|
||||||
}
|
}
|
||||||
|
|
||||||
// data->children.clear();
|
// data->children.clear();
|
||||||
|
|
|
||||||
|
|
@ -136,8 +136,10 @@ bool DatabasePrivate::updateDatabase()
|
||||||
|
|
||||||
QString databaseHistoryName = driver + QStringLiteral("\t") + databaseName + QStringLiteral("\t") + hostName;
|
QString databaseHistoryName = driver + QStringLiteral("\t") + databaseName + QStringLiteral("\t") + hostName;
|
||||||
|
|
||||||
if (updatedDatabases.contains(databaseHistoryName))
|
if (allTableMaps.contains(QString::fromUtf8(q->metaObject()->className()))) {
|
||||||
|
currentModel = allTableMaps[QString::fromUtf8(q->metaObject()->className())];
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!getCurrentSchema())
|
if (!getCurrentSchema())
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -300,6 +302,12 @@ bool DatabasePrivate::getCurrentSchema()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DatabasePrivate::isFirstOpen()
|
||||||
|
{
|
||||||
|
Q_Q(Database);
|
||||||
|
return !allTableMaps.contains(QString::fromUtf8(q->metaObject()->className()));
|
||||||
|
}
|
||||||
|
|
||||||
DatabaseModel DatabasePrivate::getLastSchema()
|
DatabaseModel DatabasePrivate::getLastSchema()
|
||||||
{
|
{
|
||||||
Row<ChangeLogTable> u = changeLogs->query()
|
Row<ChangeLogTable> u = changeLogs->query()
|
||||||
|
|
@ -555,10 +563,10 @@ bool Database::open(bool updateDatabase)
|
||||||
d->sqlGenerator = new SqliteGenerator(this);
|
d->sqlGenerator = new SqliteGenerator(this);
|
||||||
else if (d->driver == QStringLiteral("QODBC") || d->driver == QStringLiteral("QODBC3")) {
|
else if (d->driver == QStringLiteral("QODBC") || d->driver == QStringLiteral("QODBC3")) {
|
||||||
QString driverName = QString();
|
QString driverName = QString();
|
||||||
QStringList parts = d->databaseName.toLower().split(';');
|
QStringList parts = d->databaseName.toLower().split(QLatin1Char(';'));
|
||||||
for (auto &p: parts)
|
for (auto &p: parts)
|
||||||
if (p.trimmed().startsWith(QStringLiteral("driver=")))
|
if (p.trimmed().startsWith(QStringLiteral("driver=")))
|
||||||
driverName = p.split('=').at(1).toLower().trimmed();
|
driverName = p.split(QLatin1Char('=')).at(1).toLower().trimmed();
|
||||||
|
|
||||||
// if (driverName == "{sql server}")
|
// if (driverName == "{sql server}")
|
||||||
d->sqlGenerator = new SqlServerGenerator(this);
|
d->sqlGenerator = new SqlServerGenerator(this);
|
||||||
|
|
@ -607,7 +615,7 @@ int Database::saveChanges()
|
||||||
}
|
}
|
||||||
|
|
||||||
int rowsAffected = 0;
|
int rowsAffected = 0;
|
||||||
for (const auto &ts: qAsConst(d->tableSets))
|
for (const auto &ts: std::as_const(d->tableSets))
|
||||||
rowsAffected += ts->save(this);
|
rowsAffected += ts->save(this);
|
||||||
|
|
||||||
return rowsAffected;
|
return rowsAffected;
|
||||||
|
|
@ -616,7 +624,7 @@ int Database::saveChanges()
|
||||||
void Database::cleanUp()
|
void Database::cleanUp()
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
for (const auto &ts: qAsConst(d->tableSets))
|
for (const auto &ts: std::as_const(d->tableSets))
|
||||||
ts->clearChildren();
|
ts->clearChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ public:
|
||||||
|
|
||||||
QSet<AbstractTableSet *> tableSets;
|
QSet<AbstractTableSet *> tableSets;
|
||||||
|
|
||||||
|
bool isFirstOpen();
|
||||||
bool isDatabaseNew;
|
bool isDatabaseNew;
|
||||||
|
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
#define FOREIGNCONTAINER_H
|
#define FOREIGNCONTAINER_H
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
#include <QtNut/NutGlobal>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@
|
||||||
#include <QtSql/QSqlError>
|
#include <QtSql/QSqlError>
|
||||||
#include <QtSql/QSqlQueryModel>
|
#include <QtSql/QSqlQueryModel>
|
||||||
#include <QtSql/QSqlQuery>
|
#include <QtSql/QSqlQuery>
|
||||||
|
#include <QHashIterator>
|
||||||
|
|
||||||
#ifndef NUT_RAW_POINTER
|
#ifndef NUT_RAW_POINTER
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
|
|
@ -138,10 +139,10 @@ public:
|
||||||
QList<O> select(const std::function<O(const QSqlQuery &q)> allocator);
|
QList<O> select(const std::function<O(const QSqlQuery &q)> allocator);
|
||||||
|
|
||||||
int count();
|
int count();
|
||||||
QVariant max(const FieldPhrase<int> &f);
|
QVariant max(const AbstractFieldPhrase &f);
|
||||||
QVariant min(const FieldPhrase<int> &f);
|
QVariant min(const AbstractFieldPhrase &f);
|
||||||
QVariant sum(const FieldPhrase<int> &f);
|
QVariant sum(const AbstractFieldPhrase &f);
|
||||||
QVariant average(const FieldPhrase<int> &f);
|
QVariant average(const AbstractFieldPhrase &f);
|
||||||
|
|
||||||
|
|
||||||
//data mailpulation
|
//data mailpulation
|
||||||
|
|
@ -293,10 +294,7 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
for (int j = 0; j < levels.count(); ++j) {
|
for (int j = 0; j < levels.count(); ++j) {
|
||||||
LevelData &dt = levels[j];
|
LevelData &dt = levels[j];
|
||||||
|
|
||||||
QHashIterator<QString, QString> it(masters);
|
for (auto it = masters.constBegin(); it != masters.constEnd(); ++it) {
|
||||||
while (it.hasNext()) {
|
|
||||||
it.next();
|
|
||||||
|
|
||||||
if (dt.table->name() == it.key()) {
|
if (dt.table->name() == it.key()) {
|
||||||
data.masters.append(j);
|
data.masters.append(j);
|
||||||
data.masterFields.append(it.value());
|
data.masterFields.append(it.value());
|
||||||
|
|
@ -498,7 +496,7 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::count()
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const FieldPhrase<int> &f)
|
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const AbstractFieldPhrase &f)
|
||||||
{
|
{
|
||||||
if (!d->hasCustomCommand) {
|
if (!d->hasCustomCommand) {
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
|
|
@ -517,7 +515,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::max(const FieldPhrase<int> &f)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const FieldPhrase<int> &f)
|
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const AbstractFieldPhrase &f)
|
||||||
{
|
{
|
||||||
if (!d->hasCustomCommand) {
|
if (!d->hasCustomCommand) {
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
|
|
@ -536,7 +534,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::min(const FieldPhrase<int> &f)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::sum(const FieldPhrase<int> &f)
|
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::sum(const AbstractFieldPhrase &f)
|
||||||
{
|
{
|
||||||
if (!d->hasCustomCommand) {
|
if (!d->hasCustomCommand) {
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
|
|
@ -555,7 +553,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::sum(const FieldPhrase<int> &f)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const FieldPhrase<int> &f)
|
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const AbstractFieldPhrase &f)
|
||||||
{
|
{
|
||||||
if (!d->hasCustomCommand) {
|
if (!d->hasCustomCommand) {
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
|
|
@ -708,7 +706,7 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model)
|
||||||
int fieldIndex = 0;
|
int fieldIndex = 0;
|
||||||
|
|
||||||
if (d->fieldPhrase.data.count()) {
|
if (d->fieldPhrase.data.count()) {
|
||||||
for (const auto &pd : qAsConst(d->fieldPhrase.data)) {
|
for (const auto &pd : std::as_const(d->fieldPhrase.data)) {
|
||||||
QString displayName = dbModel.tableByClassName(QString::fromUtf8(pd->className))
|
QString displayName = dbModel.tableByClassName(QString::fromUtf8(pd->className))
|
||||||
->field(QString::fromUtf8(pd->fieldName))
|
->field(QString::fromUtf8(pd->fieldName))
|
||||||
->displayName;
|
->displayName;
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
#define SQLSERIALIZER_H
|
#define SQLSERIALIZER_H
|
||||||
|
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
#include <QtNut/NutGlobal>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,7 @@ void Table::setParentTableSet(AbstractTableSet *parent)
|
||||||
AbstractTableSet *Table::childTableSet(const QString &name) const
|
AbstractTableSet *Table::childTableSet(const QString &name) const
|
||||||
{
|
{
|
||||||
//Q_D(const Table);
|
//Q_D(const Table);
|
||||||
for (auto &t: qAsConst(d->childTableSets))
|
for (auto &t: std::as_const(d->childTableSets))
|
||||||
if (t->childClassName() == name)
|
if (t->childClassName() == name)
|
||||||
return t;
|
return t;
|
||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
|
|
@ -185,7 +185,7 @@ int Table::save(Database *db)
|
||||||
if(status() == Added && model->isPrimaryKeyAutoIncrement())
|
if(status() == Added && model->isPrimaryKeyAutoIncrement())
|
||||||
setProperty(model->primaryKey().toLatin1().data(), q.lastInsertId());
|
setProperty(model->primaryKey().toLatin1().data(), q.lastInsertId());
|
||||||
|
|
||||||
foreach(AbstractTableSet *ts, d->childTableSets)
|
for (auto &ts: std::as_const(d->childTableSets))
|
||||||
ts->save(db);
|
ts->save(db);
|
||||||
setStatus(FetchedFromDB);
|
setStatus(FetchedFromDB);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -610,7 +610,7 @@ QString AbstractSqlGenerator::selectCommand(const QString &tableName,
|
||||||
tables << rel->masterTable << rel->slaveTable;
|
tables << rel->masterTable << rel->slaveTable;
|
||||||
|
|
||||||
selectText = QString();
|
selectText = QString();
|
||||||
for (auto &t: qAsConst(tables)) {
|
for (auto &t: std::as_const(tables)) {
|
||||||
if (!selectText.isEmpty())
|
if (!selectText.isEmpty())
|
||||||
selectText.append(QStringLiteral(", "));
|
selectText.append(QStringLiteral(", "));
|
||||||
selectText.append(recordsPhrase(t));
|
selectText.append(recordsPhrase(t));
|
||||||
|
|
|
||||||
|
|
@ -287,6 +287,10 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
return QStringLiteral("CAST(strftime('%d', %1) AS INT)")
|
return QStringLiteral("CAST(strftime('%d', %1) AS INT)")
|
||||||
.arg(createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
||||||
|
case PhraseData::DatePartDayOfWeek:
|
||||||
|
return QStringLiteral("CAST(strftime('%w', %1) AS INT)")
|
||||||
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
||||||
case PhraseData::DatePartHour:
|
case PhraseData::DatePartHour:
|
||||||
return QStringLiteral("CAST(strftime('%H', %1) AS INT)")
|
return QStringLiteral("CAST(strftime('%H', %1) AS INT)")
|
||||||
.arg(createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
|
||||||
|
|
@ -266,6 +266,9 @@ QString SqlServerGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
|
|
||||||
if (d->type == PhraseData::WithoutOperand) {
|
if (d->type == PhraseData::WithoutOperand) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
case PhraseData::DatePartDayOfWeek:
|
||||||
|
return QStringLiteral("DATEPART(WEEKDAY, %1)")
|
||||||
|
.arg(createConditionalPhrase(d->left));
|
||||||
case PhraseData::DatePartYear:
|
case PhraseData::DatePartYear:
|
||||||
case PhraseData::DatePartMonth:
|
case PhraseData::DatePartMonth:
|
||||||
case PhraseData::DatePartDay:
|
case PhraseData::DatePartDay:
|
||||||
|
|
|
||||||
|
|
@ -227,12 +227,13 @@ DatabaseModel *DatabaseModel::modelByName(const QString &name)
|
||||||
|
|
||||||
void DatabaseModel::deleteAllModels()
|
void DatabaseModel::deleteAllModels()
|
||||||
{
|
{
|
||||||
QMapIterator<QString, DatabaseModel*> i(_models);
|
//TODO: recheck this
|
||||||
while (i.hasNext()) {
|
// QMapIterator<QString, DatabaseModel*> i(_models);
|
||||||
i.next();
|
// while (i.hasNext()) {
|
||||||
// cout << i.key() << ": " << i.value() << endl;
|
// i.next();
|
||||||
// qDeleteAll(i.value());
|
//// cout << i.key() << ": " << i.value() << endl;
|
||||||
}
|
//// qDeleteAll(i.value());
|
||||||
|
// }
|
||||||
// qDeleteAll(_models.values());
|
// qDeleteAll(_models.values());
|
||||||
_models.clear();
|
_models.clear();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,4 @@
|
||||||
#include <QtNut/fieldphrase_qstring.h>
|
#include <QtNut/fieldphrase_qstring.h>
|
||||||
#include <QtNut/fieldphrase_bool.h>
|
#include <QtNut/fieldphrase_bool.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
|
||||||
QT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // PHRASE_H
|
#endif // PHRASE_H
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
#include <QtNut/assignmentphraselist.h>
|
#include <QtNut/assignmentphraselist.h>
|
||||||
#include <QtNut/NutGlobal>
|
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,10 @@ ConditionalPhrase FieldPhrase<QDate>::day() {
|
||||||
return ConditionalPhrase(this, PhraseData::DatePartDay);
|
return ConditionalPhrase(this, PhraseData::DatePartDay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConditionalPhrase FieldPhrase<QDate>::dayOfWeek() {
|
||||||
|
return ConditionalPhrase(this, PhraseData::DatePartDayOfWeek);
|
||||||
|
}
|
||||||
|
|
||||||
FieldPhrase<QTime>::FieldPhrase(const char *className, const char *s) :
|
FieldPhrase<QTime>::FieldPhrase(const char *className, const char *s) :
|
||||||
AbstractFieldPhrase(className, s)
|
AbstractFieldPhrase(className, s)
|
||||||
{}
|
{}
|
||||||
|
|
@ -125,6 +129,10 @@ ConditionalPhrase FieldPhrase<QDateTime>::day() {
|
||||||
return ConditionalPhrase(this, PhraseData::DatePartDay);
|
return ConditionalPhrase(this, PhraseData::DatePartDay);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ConditionalPhrase FieldPhrase<QDateTime>::dayOfWeek() {
|
||||||
|
return ConditionalPhrase(this, PhraseData::DatePartDayOfWeek);
|
||||||
|
}
|
||||||
|
|
||||||
ConditionalPhrase FieldPhrase<QDateTime>::hour() {
|
ConditionalPhrase FieldPhrase<QDateTime>::hour() {
|
||||||
return ConditionalPhrase(this, PhraseData::DatePartHour);
|
return ConditionalPhrase(this, PhraseData::DatePartHour);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,8 @@ public:
|
||||||
ConditionalPhrase year();
|
ConditionalPhrase year();
|
||||||
ConditionalPhrase month();
|
ConditionalPhrase month();
|
||||||
ConditionalPhrase day();
|
ConditionalPhrase day();
|
||||||
|
|
||||||
|
ConditionalPhrase dayOfWeek();
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -115,6 +117,8 @@ public:
|
||||||
ConditionalPhrase month();
|
ConditionalPhrase month();
|
||||||
ConditionalPhrase day();
|
ConditionalPhrase day();
|
||||||
|
|
||||||
|
ConditionalPhrase dayOfWeek();
|
||||||
|
|
||||||
ConditionalPhrase hour();
|
ConditionalPhrase hour();
|
||||||
ConditionalPhrase minute();
|
ConditionalPhrase minute();
|
||||||
ConditionalPhrase second();
|
ConditionalPhrase second();
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,8 @@ public:
|
||||||
DatePartHour,
|
DatePartHour,
|
||||||
DatePartMinute,
|
DatePartMinute,
|
||||||
DatePartSecond,
|
DatePartSecond,
|
||||||
DatePartMilisecond
|
DatePartMilisecond,
|
||||||
|
DatePartDayOfWeek
|
||||||
// // special types
|
// // special types
|
||||||
// Distance
|
// Distance
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@
|
||||||
);
|
);
|
||||||
%classnames = (
|
%classnames = (
|
||||||
"nut_global.h" => "NutGlobal"
|
"nut_global.h" => "NutGlobal"
|
||||||
|
"numericphrase.h" => "NumericFieldPhrase"
|
||||||
);
|
);
|
||||||
$publicclassregexp = ".+";
|
$publicclassregexp = ".+";
|
||||||
|
|
|
||||||
|
|
@ -324,7 +324,29 @@ void BasicTest::emptyDatabase()
|
||||||
// auto commentsCount = db.comments()->query().remove();
|
// auto commentsCount = db.comments()->query().remove();
|
||||||
// auto postsCount = db.posts()->query().remove();
|
// auto postsCount = db.posts()->query().remove();
|
||||||
// QTEST_ASSERT(postsCount == 3);
|
// QTEST_ASSERT(postsCount == 3);
|
||||||
// QTEST_ASSERT(commentsCount == 6);
|
// QTEST_ASSERT(commentsCount == 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BasicTest::multipleOpen()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
WeblogDatabase database;
|
||||||
|
database.setDriver(DRIVER);
|
||||||
|
database.setHostName(HOST);
|
||||||
|
database.setDatabaseName(DATABASE);
|
||||||
|
database.setUserName(USERNAME);
|
||||||
|
database.setPassword(PASSWORD);
|
||||||
|
|
||||||
|
bool ok = database.open();
|
||||||
|
QVERIFY(ok);
|
||||||
|
|
||||||
|
auto q = database.posts()->query()
|
||||||
|
.where(Post::idField() == postId)
|
||||||
|
.orderBy(Post::idField())
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
QTEST_ASSERT(q.count() > 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicTest::cleanupTestCase()
|
void BasicTest::cleanupTestCase()
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ private Q_SLOTS:
|
||||||
void selectWithInvalidRelation();
|
void selectWithInvalidRelation();
|
||||||
void modifyPost();
|
void modifyPost();
|
||||||
void emptyDatabase();
|
void emptyDatabase();
|
||||||
|
void multipleOpen();
|
||||||
|
|
||||||
void cleanupTestCase();
|
void cleanupTestCase();
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ void Upgrades::version2()
|
||||||
{
|
{
|
||||||
DB2 db;
|
DB2 db;
|
||||||
initDb(db);
|
initDb(db);
|
||||||
QTEST_ASSERT(db.open());
|
QVERIFY(db.open());
|
||||||
|
|
||||||
auto t = Nut::create<Table2>();
|
auto t = Nut::create<Table2>();
|
||||||
t->setStr("0");
|
t->setStr("0");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue