make master identical with dev
This commit is contained in:
commit
8b8a3c37a9
|
|
@ -9,6 +9,7 @@ jobs:
|
||||||
matrix:
|
matrix:
|
||||||
version:
|
version:
|
||||||
- 5.15.0
|
- 5.15.0
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
- gcc_64
|
- gcc_64
|
||||||
- android
|
- android
|
||||||
|
|
@ -43,8 +44,6 @@ jobs:
|
||||||
os: windows-latest
|
os: windows-latest
|
||||||
- platform: clang_64
|
- platform: clang_64
|
||||||
os: macos-latest
|
os: macos-latest
|
||||||
- platform: ios
|
|
||||||
os: macos-latest
|
|
||||||
|
|
||||||
runs-on: ${{matrix.os}}
|
runs-on: ${{matrix.os}}
|
||||||
steps:
|
steps:
|
||||||
|
|
@ -62,11 +61,16 @@ jobs:
|
||||||
run: |
|
run: |
|
||||||
qmake CONFIG+=install_ok QT_PLATFORM=${{matrix.platform}} "QT_TOOL_PATH=${{steps.qt.outputs.qtdir}}/Tools" nut.pro
|
qmake CONFIG+=install_ok QT_PLATFORM=${{matrix.platform}} "QT_TOOL_PATH=${{steps.qt.outputs.qtdir}}/Tools" nut.pro
|
||||||
${{steps.qt.outputs.make}} qmake_all
|
${{steps.qt.outputs.make}} qmake_all
|
||||||
- name: make lib
|
- name: make module
|
||||||
run: |
|
run: |
|
||||||
${{steps.qt.outputs.make}}
|
${{steps.qt.outputs.make}}
|
||||||
${{steps.qt.outputs.make}} INSTALL_ROOT="${{steps.qt.outputs.installdir}}" install
|
${{steps.qt.outputs.make}} INSTALL_ROOT="${{steps.qt.outputs.installdir}}" install
|
||||||
- name: upload lib to releases
|
- name: make tests
|
||||||
|
if: steps.qt.outputs.tests == 'true'
|
||||||
|
run: |
|
||||||
|
${{steps.qt.outputs.make}} all
|
||||||
|
${{steps.qt.outputs.make}} ${{steps.qt.outputs.testflags}} run-tests
|
||||||
|
- name: upload module to releases
|
||||||
uses: Skycoder42/action-upload-release@master
|
uses: Skycoder42/action-upload-release@master
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ Makefile*
|
||||||
*.qmlproject.user.*
|
*.qmlproject.user.*
|
||||||
|
|
||||||
build
|
build
|
||||||
|
build2
|
||||||
|
|
||||||
# KDE show hidden folder marker
|
# KDE show hidden folder marker
|
||||||
.directory
|
.directory
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
[submodule "3rdparty/serializer"]
|
[submodule "src/nut/3rdparty/serializer"]
|
||||||
path = 3rdparty/serializer
|
path = src/nut/3rdparty/serializer
|
||||||
url = https://github.com/HamedMasafi/Serializer.git
|
url = https://github.com/HamedMasafi/Serializer.git
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
load(qt_build_config)
|
||||||
|
|
||||||
|
CONFIG += warning_clean exceptions qt_module_build c++17
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS QT_ASCII_CAST_WARNINGS
|
||||||
|
|
||||||
|
MODULE_VERSION = 0.6.0
|
||||||
|
|
||||||
|
# had to be added because std::visit only works on macos 10.14 and above
|
||||||
|
# remove again once Qt raises the value to 10.14!
|
||||||
|
QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.14
|
||||||
|
QMAKE_IOS_DEPLOYMENT_TARGET = 12.0
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 0e794d6317595d077e95e8a06f1f3a8c92543b05
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"title": "QtNut",
|
||||||
|
"description": "Advanced, Powerful and easy to use ORM for Qt5.",
|
||||||
|
"modules": [ "QtNut" ],
|
||||||
|
"dependencies": [],
|
||||||
|
"excludes": [],
|
||||||
|
"license": {
|
||||||
|
"name": "LGPL-3",
|
||||||
|
"path": "LICENSE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,23 +4,23 @@ In *shared pointer* mode results of queries is QList<QSharedPointer<T>> and in *
|
||||||
|
|
||||||
Almost in every case shared pointer mode is better, But nut support regular mode for backward comptability.
|
Almost in every case shared pointer mode is better, But nut support regular mode for backward comptability.
|
||||||
|
|
||||||
To compiling in *shared pointer* define **NUT_SHARED_POINTER** macro
|
By default _Nut_ compiles in shared pointer mode, to switch to ols raw pointer mode you must define **NUT_RAW_POINTER** macro
|
||||||
|
|
||||||
Nut has template alias
|
Nut has template alias
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#ifdef NUT_SHARED_POINTER
|
#ifdef NUT_RAW_POINTER
|
||||||
template <typename T>
|
|
||||||
using RowList = QList<QSharedPointer<T>>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using Row = QSharedPointer<T>;
|
|
||||||
#else
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using RowList = QList<T*>;
|
using RowList = QList<T*>;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
using Row = T*;
|
using Row = T*;
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
using RowList = QList<QSharedPointer<T>>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using Row = QSharedPointer<T>;
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -36,16 +36,16 @@ For the integration of your source, you can use these aliases.
|
||||||
Ans also Nut::create<T>() method are defined for two mode
|
Ans also Nut::create<T>() method are defined for two mode
|
||||||
|
|
||||||
```cpp
|
```cpp
|
||||||
#ifdef NUT_SHARED_POINTER
|
#ifdef NUT_RAW_POINTER
|
||||||
template<class T>
|
|
||||||
inline Row<T> create(QObject *parent) {
|
|
||||||
return QSharedPointer<T>(new T(parent));
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Row<T> create() {
|
inline Row<T> create() {
|
||||||
return new T;
|
return new T;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
template<class T>
|
||||||
|
inline Row<T> create(QObject *parent) {
|
||||||
|
return QSharedPointer<T>(new T(parent));
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -54,6 +54,6 @@ So you can use the Nut::create function without considering in what way the libr
|
||||||
auto post = Nut::create<Post>();
|
auto post = Nut::create<Post>();
|
||||||
```
|
```
|
||||||
|
|
||||||
In above example if *NUT_SHARED_POINTER* is defined *post* is *QSharedPointer<Post>* else is *Post\**
|
In above example if *NUT_RAW_POINTER* is defined *post* is *Post\** else is *QSharedPointer<Post>*
|
||||||
|
|
||||||
I recommand use *NUT_SHARED_POINTER* always!
|
I recommand use shared pointer mode (default) always!
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/database.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/types/dbgeography.h"
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
#include "../src/table.h"
|
|
||||||
#include "../src/database.h"
|
|
||||||
#include "../src/sqlmodel.h"
|
|
||||||
#include "../src/tableset.h"
|
|
||||||
#include "../src/tablemodel.h"
|
|
||||||
#include "../src/query.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/query.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/sqlmodel.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/table.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/tablemodel.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/tableset.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/database.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/types/dbgeography.h"
|
|
||||||
|
|
@ -1,42 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
src_dir="src"
|
|
||||||
namespace_name="nut"
|
|
||||||
|
|
||||||
#ns=$(echo $namespace_name|awk '{print tolower($0)}')
|
|
||||||
Ns="Nut"
|
|
||||||
NS=$(echo $namespace_name|awk '{print toupper($0)}')
|
|
||||||
|
|
||||||
|
|
||||||
create_sub_folder=true
|
|
||||||
|
|
||||||
exec 3< <(egrep -o "class\s${NS}_EXPORT\s(\S+)" "../$src_dir" -R 2>&1)
|
|
||||||
|
|
||||||
pattern="\.\.\/$src_dir\/([a-z]+)\.h\:class\s${NS}_EXPORT\s(\w+)"
|
|
||||||
|
|
||||||
echo "" > "$Ns"
|
|
||||||
echo "" > "$ns.h"
|
|
||||||
|
|
||||||
if [[ -z create_sub_folder ]]; then
|
|
||||||
mkdir -p $Ns
|
|
||||||
fi
|
|
||||||
|
|
||||||
while read line; do
|
|
||||||
if [[ $line =~ $pattern ]]; then
|
|
||||||
header=${BASH_REMATCH[1]}
|
|
||||||
class=${BASH_REMATCH[2]}
|
|
||||||
|
|
||||||
echo "#include \"../$src_dir/$header.h\"" > $class
|
|
||||||
echo "#include \"../$src_dir/$header.h\"" > "$header.h"
|
|
||||||
|
|
||||||
if [[ -z create_sub_folder ]]; then
|
|
||||||
echo "#include \"../$src_dir/$header.h\"" > "$Ns/$class"
|
|
||||||
echo "#include \"../$src_dir/$header.h\"" > "$Ns/$header.h"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "#include \"../$src_dir/$header.h\"" >> "$Ns"
|
|
||||||
echo "#include \"../$src_dir/$header.h\"" >> "$ns.h"
|
|
||||||
fi
|
|
||||||
echo $Ns
|
|
||||||
done <&3
|
|
||||||
exec 3<&-
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
|
|
||||||
#include "../src/table.h"
|
|
||||||
#include "../src/database.h"
|
|
||||||
#include "../src/sqlmodel.h"
|
|
||||||
#include "../src/tableset.h"
|
|
||||||
#include "../src/tablemodel.h"
|
|
||||||
#include "../src/query.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/query.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/sqlmodel.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/table.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/tablemodel.h"
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include "../src/tableset.h"
|
|
||||||
81
nut.pri
81
nut.pri
|
|
@ -1,81 +0,0 @@
|
||||||
QT += core sql
|
|
||||||
|
|
||||||
CONFIG += c++11
|
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/include
|
|
||||||
DEFINES += NUT_SHARED_POINTER
|
|
||||||
|
|
||||||
!exists(3rdparty/serializer/src/src.pri) {
|
|
||||||
error("Please do git submodule update --init --recursive in the Nut directory")
|
|
||||||
}
|
|
||||||
|
|
||||||
include(3rdparty/serializer/src/src.pri)
|
|
||||||
|
|
||||||
HEADERS += \
|
|
||||||
$$PWD/src/generators/sqlgeneratorbase_p.h \
|
|
||||||
$$PWD/src/generators/postgresqlgenerator.h \
|
|
||||||
$$PWD/src/generators/mysqlgenerator.h \
|
|
||||||
$$PWD/src/generators/sqlitegenerator.h \
|
|
||||||
$$PWD/src/generators/sqlservergenerator.h \
|
|
||||||
$$PWD/src/types/dbgeography.h \
|
|
||||||
$$PWD/src/tableset.h \
|
|
||||||
$$PWD/src/defines_p.h \
|
|
||||||
$$PWD/src/defines.h \
|
|
||||||
$$PWD/src/query.h \
|
|
||||||
$$PWD/src/databasemodel.h \
|
|
||||||
$$PWD/src/changelogtable.h \
|
|
||||||
$$PWD/src/tablesetbase_p.h \
|
|
||||||
$$PWD/src/querybase_p.h \
|
|
||||||
$$PWD/src/tablemodel.h \
|
|
||||||
$$PWD/src/query_p.h \
|
|
||||||
$$PWD/src/table.h \
|
|
||||||
$$PWD/src/database.h \
|
|
||||||
$$PWD/src/database_p.h \
|
|
||||||
$$PWD/src/serializableobject.h \
|
|
||||||
$$PWD/src/sqlmodel.h \
|
|
||||||
$$PWD/src/sqlmodel_p.h \
|
|
||||||
$$PWD/src/phrase.h \
|
|
||||||
$$PWD/src/tuple.h \
|
|
||||||
$$PWD/src/phrases/conditionalphrase.h \
|
|
||||||
$$PWD/src/phrases/abstractfieldphrase.h \
|
|
||||||
$$PWD/src/phrases/fieldphrase.h \
|
|
||||||
$$PWD/src/phrases/phraselist.h \
|
|
||||||
$$PWD/src/phrases/assignmentphraselist.h \
|
|
||||||
$$PWD/src/phrases/phrasedatalist.h \
|
|
||||||
$$PWD/src/phrases/phrasedata.h \
|
|
||||||
$$PWD/src/phrases/assignmentphrase.h \
|
|
||||||
$$PWD/src/phrases/numericphrase.h \
|
|
||||||
$$PWD/src/phrases/datephrase.h \
|
|
||||||
$$PWD/src/bulkinserter.h
|
|
||||||
|
|
||||||
SOURCES += \
|
|
||||||
$$PWD/src/generators/sqlgeneratorbase.cpp \
|
|
||||||
$$PWD/src/generators/postgresqlgenerator.cpp \
|
|
||||||
$$PWD/src/generators/mysqlgenerator.cpp \
|
|
||||||
$$PWD/src/generators/sqlitegenerator.cpp \
|
|
||||||
$$PWD/src/generators/sqlservergenerator.cpp \
|
|
||||||
$$PWD/src/types/dbgeography.cpp \
|
|
||||||
$$PWD/src/tableset.cpp \
|
|
||||||
$$PWD/src/query.cpp \
|
|
||||||
$$PWD/src/databasemodel.cpp \
|
|
||||||
$$PWD/src/tablesetbase.cpp \
|
|
||||||
$$PWD/src/changelogtable.cpp \
|
|
||||||
$$PWD/src/querybase.cpp \
|
|
||||||
$$PWD/src/tablemodel.cpp \
|
|
||||||
$$PWD/src/table.cpp \
|
|
||||||
$$PWD/src/database.cpp \
|
|
||||||
$$PWD/src/serializableobject.cpp \
|
|
||||||
$$PWD/src/sqlmodel.cpp \
|
|
||||||
$$PWD/src/phrase.cpp \
|
|
||||||
$$PWD/src/tuple.cpp \
|
|
||||||
$$PWD/src/phrases/conditionalphrase.cpp \
|
|
||||||
$$PWD/src/phrases/abstractfieldphrase.cpp \
|
|
||||||
$$PWD/src/phrases/fieldphrase.cpp \
|
|
||||||
$$PWD/src/phrases/phraselist.cpp \
|
|
||||||
$$PWD/src/phrases/assignmentphraselist.cpp \
|
|
||||||
$$PWD/src/phrases/phrasedatalist.cpp \
|
|
||||||
$$PWD/src/phrases/phrasedata.cpp \
|
|
||||||
$$PWD/src/phrases/assignmentphrase.cpp \
|
|
||||||
$$PWD/src/phrases/numericphrase.cpp \
|
|
||||||
$$PWD/src/phrases/datephrase.cpp \
|
|
||||||
$$PWD/src/bulkinserter.cpp
|
|
||||||
14
nut.pro
14
nut.pro
|
|
@ -1,6 +1,10 @@
|
||||||
TEMPLATE = subdirs
|
load(qt_parts)
|
||||||
CONFIG += ordered
|
|
||||||
SUBDIRS += \
|
|
||||||
src \
|
|
||||||
test
|
|
||||||
|
|
||||||
|
runtests.target = run-tests
|
||||||
|
runtests.CONFIG = recursive
|
||||||
|
runtests.recurse_target = run-tests
|
||||||
|
runtests.recurse += sub_tests sub_src
|
||||||
|
QMAKE_EXTRA_TARGETS += runtests
|
||||||
|
|
||||||
|
DISTFILES += .qmake.conf \
|
||||||
|
sync.profile
|
||||||
|
|
|
||||||
53
nut.qbs
53
nut.qbs
|
|
@ -1,53 +0,0 @@
|
||||||
import qbs
|
|
||||||
|
|
||||||
Project {
|
|
||||||
// StaticLibrary {
|
|
||||||
// name: "nut_static"
|
|
||||||
// files: [
|
|
||||||
// "src/*.h",
|
|
||||||
// "src/*.cpp",
|
|
||||||
// "src/generators/*.h",
|
|
||||||
// "src/generators/*.cpp"
|
|
||||||
// ]
|
|
||||||
// Depends { name: 'cpp' }
|
|
||||||
// Depends { name: "Qt.core" }
|
|
||||||
// Depends { name: "Qt.sql" }
|
|
||||||
// Group { qbs.install: true; fileTagsFilter: product.type;}
|
|
||||||
|
|
||||||
// Export {
|
|
||||||
// Depends { name: "cpp" }
|
|
||||||
// Depends { name: "Qt.core" }
|
|
||||||
// Depends { name: "Qt.sql" }
|
|
||||||
// cpp.includePaths: [
|
|
||||||
// product.sourceDirectory + "/src",
|
|
||||||
// product.sourceDirectory + "/include"
|
|
||||||
// ]
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
DynamicLibrary {
|
|
||||||
name: "nut"
|
|
||||||
files: [
|
|
||||||
"src/*.h",
|
|
||||||
"src/*.cpp",
|
|
||||||
"src/generators/*.h",
|
|
||||||
"src/generators/*.cpp"
|
|
||||||
]
|
|
||||||
|
|
||||||
Depends { name: 'cpp' }
|
|
||||||
Depends { name: "Qt.core" }
|
|
||||||
Depends { name: "Qt.sql" }
|
|
||||||
|
|
||||||
Group { qbs.install: true; fileTagsFilter: product.type;}
|
|
||||||
|
|
||||||
Export {
|
|
||||||
Depends { name: "cpp" }
|
|
||||||
Depends { name: "Qt.core" }
|
|
||||||
Depends { name: "Qt.sql" }
|
|
||||||
cpp.includePaths: [
|
|
||||||
product.sourceDirectory + "/src",
|
|
||||||
product.sourceDirectory + "/include"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
24
nut.qdocconf
24
nut.qdocconf
|
|
@ -1,24 +0,0 @@
|
||||||
project = Nut
|
|
||||||
description = Advanced, Powerful and easy to use ORM for Qt5
|
|
||||||
version = 0.1
|
|
||||||
|
|
||||||
outputdir = doc
|
|
||||||
|
|
||||||
source += src/query.cpp
|
|
||||||
headerdirs += src
|
|
||||||
sourcedirs += src
|
|
||||||
exampledirs = .
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
qhp.projects = Nut
|
|
||||||
|
|
||||||
qhp.qtestclass.file = nut.qhp
|
|
||||||
qhp.qtestclass.namespace = org.kaj.nut.0.1
|
|
||||||
qhp.qtestclass.virtualFolder = nut
|
|
||||||
qhp.qtestclass.indexTitle = nut
|
|
||||||
qhp.qtestclass.indexRoot =
|
|
||||||
|
|
||||||
qhp.qtestclass.filterAttributes = nut 0.1 qtrefdoc
|
|
||||||
qhp.qtestclass.customFilters.Qt.name = qtestclass 0.1
|
|
||||||
qhp.qtestclass.customFilters.Qt.filterAttributes = qtestclass 0.1
|
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
QMAKE_CXX.QT_COMPILER_STDCXX = 201402L
|
||||||
|
QMAKE_CXX.QMAKE_GCC_MAJOR_VERSION = 10
|
||||||
|
QMAKE_CXX.QMAKE_GCC_MINOR_VERSION = 2
|
||||||
|
QMAKE_CXX.QMAKE_GCC_PATCH_VERSION = 1
|
||||||
|
QMAKE_CXX.COMPILER_MACROS = \
|
||||||
|
QT_COMPILER_STDCXX \
|
||||||
|
QMAKE_GCC_MAJOR_VERSION \
|
||||||
|
QMAKE_GCC_MINOR_VERSION \
|
||||||
|
QMAKE_GCC_PATCH_VERSION
|
||||||
|
QMAKE_CXX.INCDIRS = \
|
||||||
|
/usr/include/c++/10 \
|
||||||
|
/usr/include/c++/10/x86_64-redhat-linux \
|
||||||
|
/usr/include/c++/10/backward \
|
||||||
|
/usr/lib/gcc/x86_64-redhat-linux/10/include \
|
||||||
|
/usr/local/include \
|
||||||
|
/usr/include
|
||||||
|
QMAKE_CXX.LIBDIRS = \
|
||||||
|
/usr/lib/gcc/x86_64-redhat-linux/10 \
|
||||||
|
/usr/lib64 \
|
||||||
|
/lib64 \
|
||||||
|
/usr/lib \
|
||||||
|
/lib
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
#include "bulkinserter.h"
|
|
||||||
#include "phrases/phraselist.h"
|
|
||||||
#include "database.h"
|
|
||||||
#include "generators/sqlgeneratorbase_p.h"
|
|
||||||
#include "databasemodel.h"
|
|
||||||
|
|
||||||
#include <QDebug>
|
|
||||||
|
|
||||||
Nut::BulkInserter::BulkInserter(Nut::Database *db, QString &className)
|
|
||||||
: _database(db), _fieldCount(0)
|
|
||||||
{
|
|
||||||
foreach (TableModel *m, db->model())
|
|
||||||
if (m->className() == className)
|
|
||||||
_className = m->name();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Nut::BulkInserter::setFields(const Nut::PhraseList &ph)
|
|
||||||
{
|
|
||||||
_fields = ph;
|
|
||||||
_fieldCount = static_cast<size_t>(ph.data.count());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Nut::BulkInserter::insert(std::initializer_list<QVariant> vars)
|
|
||||||
{
|
|
||||||
if (vars.size() != _fieldCount) {
|
|
||||||
qInfo("Number of rows mistake");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantList list;
|
|
||||||
std::initializer_list<QVariant>::iterator it;
|
|
||||||
for (it = vars.begin(); it != vars.end(); ++it)
|
|
||||||
list.append(*it);
|
|
||||||
variants.append(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Nut::BulkInserter::apply()
|
|
||||||
{
|
|
||||||
auto sql = _database->sqlGenerator()->insertBulk(_className, _fields, variants);
|
|
||||||
QSqlQuery q = _database->exec(sql);
|
|
||||||
return q.numRowsAffected();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 37eafb2414575ea2873698e77b95ba8fcfeddba7
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/nut_config.h \
|
||||||
|
$$PWD/nut_consts.h \
|
||||||
|
$$PWD/nut_global.h \
|
||||||
|
$$PWD/nut_macros.h \
|
||||||
|
$$PWD/nut_namespace.h
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
#ifndef NUT_CONFIG_H
|
||||||
|
#define NUT_CONFIG_H
|
||||||
|
|
||||||
|
#if defined(NUT_SHARED) || !defined(NUT_STATIC)
|
||||||
|
# ifdef NUT_STATIC
|
||||||
|
# error "Both NUT_SHARED and NUT_STATIC defined, please make up your mind"
|
||||||
|
# endif
|
||||||
|
# ifndef NUT_SHARED
|
||||||
|
# define NUT_SHARED
|
||||||
|
# endif
|
||||||
|
# if defined(NUT_BUILD_LIB)
|
||||||
|
# define NUT_EXPORT Q_DECL_EXPORT
|
||||||
|
# else
|
||||||
|
# define NUT_EXPORT Q_DECL_IMPORT
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define NUT_EXPORT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // NUT_CONFIG_H
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef DEFINES_P_H
|
#ifndef NUT_CONSTS_H
|
||||||
#define DEFINES_P_H
|
#define NUT_CONSTS_H
|
||||||
|
|
||||||
#define __NAME "name"
|
#define __NAME "name"
|
||||||
#define __TYPE "type"
|
#define __TYPE "type"
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
#define __nut_DEFAULT_VALUE "def"
|
#define __nut_DEFAULT_VALUE "def"
|
||||||
#define __nut_NOT_NULL "notnull"
|
#define __nut_NOT_NULL "notnull"
|
||||||
|
|
||||||
#define __nut_FOREIGN_KEY "foreign_key"
|
#define __nut_FOREIGN_KEY "foreign_key"
|
||||||
#define __nut_NEW "new"
|
#define __nut_NEW "new"
|
||||||
#define __nut_REMOVE "remove"
|
#define __nut_REMOVE "remove"
|
||||||
#define __nut_CHANGE "change"
|
#define __nut_CHANGE "change"
|
||||||
|
|
@ -56,4 +56,4 @@
|
||||||
# define NUT_WRAP_NAMESPACE(x) x
|
# define NUT_WRAP_NAMESPACE(x) x
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // DEFINES_P_H
|
#endif // NUT_CONSTS_H
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
#ifndef NUT_GLOBAL_H
|
||||||
|
#define NUT_GLOBAL_H
|
||||||
|
|
||||||
|
#define NUT_NAMESPACE Nut
|
||||||
|
|
||||||
|
#include <QtNut/nut_config.h>
|
||||||
|
#include <QtNut/nut_consts.h>
|
||||||
|
#include <QtNut/nut_macros.h>
|
||||||
|
#include <QtNut/nut_macros.h>
|
||||||
|
#include <QtNut/nut_namespace.h>
|
||||||
|
|
||||||
|
#endif // NUT_GLOBAL_H
|
||||||
|
|
@ -1,51 +1,6 @@
|
||||||
/**************************************************************************
|
#ifndef NUT_MACROS_H
|
||||||
**
|
#define NUT_MACROS_H
|
||||||
** This file is part of Nut project.
|
|
||||||
** https://github.com/HamedMasafi/Nut
|
|
||||||
**
|
|
||||||
** Nut is free software: you can redistribute it and/or modify
|
|
||||||
** it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
** the Free Software Foundation, either version 3 of the License, or
|
|
||||||
** (at your option) any later version.
|
|
||||||
**
|
|
||||||
** Nut is distributed in the hope that it will be useful,
|
|
||||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
** GNU Lesser General Public License for more details.
|
|
||||||
**
|
|
||||||
** You should have received a copy of the GNU Lesser General Public License
|
|
||||||
** along with Nut. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
**
|
|
||||||
**************************************************************************/
|
|
||||||
|
|
||||||
#ifndef SYNTAX_DEFINES_H
|
|
||||||
#define SYNTAX_DEFINES_H
|
|
||||||
|
|
||||||
#define NUT_NAMESPACE Nut
|
|
||||||
|
|
||||||
#include "defines_p.h"
|
|
||||||
#include "qglobal.h"
|
|
||||||
|
|
||||||
#include <QString>
|
|
||||||
#include <QStringList>
|
|
||||||
#include <QVariant>
|
|
||||||
#include <QMetaClassInfo>
|
|
||||||
|
|
||||||
#if defined(NUT_SHARED) || !defined(NUT_STATIC)
|
|
||||||
# ifdef NUT_STATIC
|
|
||||||
# error "Both NUT_SHARED and NUT_STATIC defined, please make up your mind"
|
|
||||||
# endif
|
|
||||||
# ifndef NUT_SHARED
|
|
||||||
# define NUT_SHARED
|
|
||||||
# endif
|
|
||||||
# if defined(NUT_BUILD_LIB)
|
|
||||||
# define NUT_EXPORT Q_DECL_EXPORT
|
|
||||||
# else
|
|
||||||
# define NUT_EXPORT Q_DECL_IMPORT
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# define NUT_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NUT_INFO(type, name, value) \
|
#define NUT_INFO(type, name, value) \
|
||||||
Q_CLASSINFO(__nut_NAME_PERFIX type #name #value, \
|
Q_CLASSINFO(__nut_NAME_PERFIX type #name #value, \
|
||||||
|
|
@ -73,6 +28,17 @@
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//Table
|
//Table
|
||||||
|
#define NUT_FIELD(type, name) \
|
||||||
|
private: \
|
||||||
|
NUT_INFO(__nut_FIELD, name, 0) \
|
||||||
|
public: \
|
||||||
|
static NUT_WRAP_NAMESPACE(FieldPhrase<type>)& name ## Field(){ \
|
||||||
|
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = \
|
||||||
|
NUT_WRAP_NAMESPACE(FieldPhrase<type>) \
|
||||||
|
(staticMetaObject.className(), #name); \
|
||||||
|
return f; \
|
||||||
|
}
|
||||||
|
|
||||||
#define NUT_DECLARE_FIELD(type, name, read, write) \
|
#define NUT_DECLARE_FIELD(type, name, read, write) \
|
||||||
Q_PROPERTY(type name READ read WRITE write) \
|
Q_PROPERTY(type name READ read WRITE write) \
|
||||||
NUT_INFO(__nut_FIELD, name, 0) \
|
NUT_INFO(__nut_FIELD, name, 0) \
|
||||||
|
|
@ -89,59 +55,59 @@ public: \
|
||||||
} \
|
} \
|
||||||
void write(type name){ \
|
void write(type name){ \
|
||||||
m_##name = name; \
|
m_##name = name; \
|
||||||
propertyChanged(#name); \
|
propertyChanged(QString::fromUtf8(#name)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUT_FOREIGN_KEY(type, keytype, name, read, write) \
|
#define NUT_FOREIGN_KEY(type, keytype, name, read, write) \
|
||||||
Q_PROPERTY(Nut::Row<type> name READ read WRITE write) \
|
Q_PROPERTY(Nut::Row<type> name READ read WRITE write) \
|
||||||
NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \
|
NUT_DECLARE_FIELD(keytype, name##Id, read##Id, write##Id) \
|
||||||
NUT_INFO(__nut_FOREIGN_KEY, name, type) \
|
NUT_INFO(__nut_FOREIGN_KEY, name, type) \
|
||||||
Nut::Row<type> m_##name; \
|
Nut::Row<type> m_##name; \
|
||||||
public slots: \
|
public Q_SLOTS: \
|
||||||
Nut::Row<type> read() const { return m_##name ; } \
|
Nut::Row<type> read() const { return m_##name ; } \
|
||||||
Q_INVOKABLE void write(Nut::Row<type> name){ \
|
Q_INVOKABLE void write(Nut::Row<type> name){ \
|
||||||
m_##name = name; \
|
m_##name = name; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUT_FOREIGN_KEY_DECLARE(type, keytype, name, read, write) \
|
#define NUT_FOREIGN_KEY_DECLARE(type, keytype, name, read, write) \
|
||||||
NUT_INFO(__nut_FIELD, name##Id, 0) \
|
NUT_INFO(__nut_FIELD, name##Id, 0) \
|
||||||
NUT_INFO(__nut_FOREIGN_KEY, name, type) \
|
NUT_INFO(__nut_FOREIGN_KEY, name, type) \
|
||||||
Nut::Row<type> m_##name; \
|
Nut::Row<type> m_##name; \
|
||||||
keytype m_##name##Id; \
|
keytype m_##name##Id; \
|
||||||
Q_PROPERTY(Nut::Row<type> name READ read WRITE write) \
|
Q_PROPERTY(Nut::Row<type> name READ read WRITE write) \
|
||||||
Q_PROPERTY(keytype name##Id READ read##Id WRITE write##Id) \
|
Q_PROPERTY(keytype name##Id READ read##Id WRITE write##Id) \
|
||||||
public: \
|
public: \
|
||||||
Nut::Row<type> read() const; \
|
Nut::Row<type> read() const; \
|
||||||
keytype read##Id() const; \
|
keytype read##Id() const; \
|
||||||
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>)& name##Id ## Field(){ \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>)& name##Id ## Field(){ \
|
||||||
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) f = \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) f = \
|
||||||
NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) \
|
NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) \
|
||||||
(staticMetaObject.className(), #name); \
|
(staticMetaObject.className(), #name "Id"); \
|
||||||
return f; \
|
return f; \
|
||||||
} \
|
} \
|
||||||
public slots: \
|
public : \
|
||||||
void write(Nut::Row<type> name); \
|
Q_INVOKABLE void write(Nut::Row<type> name); \
|
||||||
|
Q_INVOKABLE void write(Nut::Row<Nut::Table> name); \
|
||||||
void write##Id(keytype name##Id);
|
void write##Id(keytype name##Id);
|
||||||
|
|
||||||
#define NUT_FOREIGN_KEY_IMPLEMENT(class, type, keytype, name, read, write) \
|
#define NUT_FOREIGN_KEY_IMPLEMENT(class, type, keytype, name, read, write) \
|
||||||
\
|
Nut::Row<type> class::read() const { return m_##name ; } \
|
||||||
Nut::Row<type> class::read() const { return m_##name ; } \
|
void class::write(Nut::Row<type> name){ \
|
||||||
void class::write(Nut::Row<type> name){ \
|
propertyChanged(QStringLiteral(QT_STRINGIFY2(name##Id))); \
|
||||||
propertyChanged(QT_STRINGIFY2(name##Id)); \
|
|
||||||
m_##name = name; \
|
m_##name = name; \
|
||||||
m_##name##Id = name->primaryValue().value<keytype>(); \
|
m_##name##Id = name->primaryValue().value<keytype>(); \
|
||||||
} \
|
|
||||||
\
|
|
||||||
keytype class::read##Id() const{ \
|
|
||||||
if (m_##name) \
|
|
||||||
return m_##name->primaryValue().value<keytype>(); \
|
|
||||||
return m_##name##Id; \
|
|
||||||
} \
|
} \
|
||||||
void class::write##Id(keytype name##Id){ \
|
void class::write(Nut::Row<Nut::Table> name){ \
|
||||||
propertyChanged(QT_STRINGIFY2(name##Id)); \
|
write(qSharedPointerDynamicCast<type>(name)); \
|
||||||
m_##name##Id = name##Id; \
|
} keytype class::read##Id() const{ \
|
||||||
m_##name = nullptr; \
|
if (m_##name) \
|
||||||
propertyChanged(QT_STRINGIFY2(name##Id)); \
|
return m_##name->primaryValue().value<keytype>(); \
|
||||||
|
return m_##name##Id; \
|
||||||
|
} \
|
||||||
|
void class::write##Id(keytype name##Id){ \
|
||||||
|
m_##name##Id = name##Id; \
|
||||||
|
m_##name = nullptr; \
|
||||||
|
propertyChanged(QStringLiteral(QT_STRINGIFY2(name##Id))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -154,22 +120,22 @@ public slots: \
|
||||||
|
|
||||||
#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \
|
#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \
|
||||||
type *class::n##Table(){ \
|
type *class::n##Table(){ \
|
||||||
static auto f = new type(); \
|
static auto f = new type(); \
|
||||||
return f; \
|
return f; \
|
||||||
} \
|
} \
|
||||||
NUT_WRAP_NAMESPACE(TableSet)<type> *class::n(){ \
|
NUT_WRAP_NAMESPACE(TableSet)<type> *class::n(){ \
|
||||||
return m_##n; \
|
return m_##n; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NUT_FIELD(name) NUT_INFO(__nut_FIELD, name, 0)
|
//#define NUT_FIELD(name) NUT_INFO(__nut_FIELD, name, 0)
|
||||||
#define NUT_PRIMARY_KEY(x) NUT_INFO(__nut_PRIMARY_KEY, x, 0) \
|
#define NUT_PRIMARY_KEY(x) NUT_INFO(__nut_PRIMARY_KEY, x, 0) \
|
||||||
public: \
|
public: \
|
||||||
QVariant primaryValue() const override { \
|
QVariant primaryValue() const override { \
|
||||||
return property(#x); \
|
return property(#x); \
|
||||||
} \
|
} \
|
||||||
void setPrimaryValue(const QVariant &value) override { \
|
void setPrimaryValue(const QVariant &value) override { \
|
||||||
setProperty(#x, value); \
|
setProperty(#x, value); \
|
||||||
} \
|
} \
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -183,132 +149,4 @@ public slots: \
|
||||||
#define NUT_NOT_NULL(x) NUT_INFO(__nut_NOT_NULL, x, 1)
|
#define NUT_NOT_NULL(x) NUT_INFO(__nut_NOT_NULL, x, 1)
|
||||||
#define NUT_INDEX(name, field, order)
|
#define NUT_INDEX(name, field, order)
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
#endif // NUT_MACROS_H
|
||||||
|
|
||||||
inline bool nutClassInfo(const QMetaClassInfo &classInfo,
|
|
||||||
QString &type, QString &name, QVariant &value)
|
|
||||||
{
|
|
||||||
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QStringList parts = QString(classInfo.value()).split("\n");
|
|
||||||
if (parts.count() != 3)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
type = parts[0];
|
|
||||||
name = parts[1];
|
|
||||||
value = QVariant::fromValue(parts[2]);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool nutClassInfoString(const QMetaClassInfo &classInfo,
|
|
||||||
QString &type, QString &name, QString &value)
|
|
||||||
{
|
|
||||||
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QStringList parts = QString(classInfo.value()).split("\n");
|
|
||||||
if (parts.count() != 3)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
type = parts[0];
|
|
||||||
name = parts[1];
|
|
||||||
value = parts[2];
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool nutClassInfoBool(const QMetaClassInfo &classInfo,
|
|
||||||
QString &type, QString &name, bool &value)
|
|
||||||
{
|
|
||||||
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QStringList parts = QString(classInfo.value()).split("\n");
|
|
||||||
if (parts.count() != 3)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QString buffer = parts[2].toLower();
|
|
||||||
if (buffer != "true" && buffer != "false")
|
|
||||||
return false;
|
|
||||||
|
|
||||||
type = parts[0];
|
|
||||||
name = parts[1];
|
|
||||||
value = (buffer == "true");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool nutClassInfoInt(const QMetaClassInfo &classInfo,
|
|
||||||
QString &type, QString &name, bool &value)
|
|
||||||
{
|
|
||||||
if (!QString(classInfo.name()).startsWith(__nut_NAME_PERFIX))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
QStringList parts = QString(classInfo.value()).split("\n");
|
|
||||||
if (parts.count() != 3)
|
|
||||||
return false;
|
|
||||||
bool ok;
|
|
||||||
type = parts[0];
|
|
||||||
name = parts[1];
|
|
||||||
value = parts[2].toInt(&ok);
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NUT_SHARED_POINTER
|
|
||||||
template <class T>
|
|
||||||
using RowList = QList<QSharedPointer<T>>;
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
using RowSet = QSet<QSharedPointer<T>>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using Row = QSharedPointer<T>;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline Row<T> create() {
|
|
||||||
return QSharedPointer<T>(new T);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline Row<T> create(QObject *parent) {
|
|
||||||
return QSharedPointer<T>(new T(parent));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline Row<T> createFrom(T *row) {
|
|
||||||
return QSharedPointer<T>(row);
|
|
||||||
}
|
|
||||||
template<class T>
|
|
||||||
inline Row<T> createFrom(const QSharedPointer<T> row) {
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
template <typename T>
|
|
||||||
using RowList = QList<T*>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using RowSet = QSet<T*>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using Row = T*;
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline Row<T> create() {
|
|
||||||
return new T;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline T *get(const Row<T> row) {
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
inline T *get(const QSharedPointer<T> row) {
|
|
||||||
return row.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // SYNTAX_DEFINES_H
|
|
||||||
|
|
@ -0,0 +1,142 @@
|
||||||
|
#ifndef NUT_NAMESPACE_H
|
||||||
|
#define NUT_NAMESPACE_H
|
||||||
|
|
||||||
|
#ifndef NUT_GLOBAL_H
|
||||||
|
# error "Do not include nut_namespace.h header directly!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//avoid ide warnings
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
#include <QtCore/QString>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
#include <QtCore/QMetaClassInfo>
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
inline bool nutClassInfo(const QMetaClassInfo &classInfo,
|
||||||
|
QString &type, QString &name, QVariant &value)
|
||||||
|
{
|
||||||
|
if (!QString::fromUtf8(classInfo.name()).startsWith(QStringLiteral(__nut_NAME_PERFIX)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QStringList parts = QString::fromUtf8(classInfo.value()).split(QStringLiteral("\n"));
|
||||||
|
if (parts.count() != 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
type = parts[0];
|
||||||
|
name = parts[1];
|
||||||
|
value = QVariant::fromValue(parts[2]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool nutClassInfoString(const QMetaClassInfo &classInfo,
|
||||||
|
QString &type, QString &name, QString &value)
|
||||||
|
{
|
||||||
|
if (!QString::fromUtf8(classInfo.name()).startsWith(QStringLiteral(__nut_NAME_PERFIX)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QStringList parts = QString::fromUtf8(classInfo.value()).split(QStringLiteral("\n"));
|
||||||
|
if (parts.count() != 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
type = parts[0];
|
||||||
|
name = parts[1];
|
||||||
|
value = parts[2];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool nutClassInfoBool(const QMetaClassInfo &classInfo,
|
||||||
|
QString &type, QString &name, bool &value)
|
||||||
|
{
|
||||||
|
if (!QString::fromUtf8(classInfo.name()).startsWith(QStringLiteral(__nut_NAME_PERFIX)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QStringList parts = QString::fromUtf8(classInfo.value()).split(QStringLiteral("\n"));
|
||||||
|
if (parts.count() != 3)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QString buffer = parts[2].toLower();
|
||||||
|
if (buffer != QStringLiteral("true") && buffer != QStringLiteral("false"))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
type = parts[0];
|
||||||
|
name = parts[1];
|
||||||
|
value = (buffer == QStringLiteral("true"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool nutClassInfoInt(const QMetaClassInfo &classInfo,
|
||||||
|
QString &type, QString &name, bool &value)
|
||||||
|
{
|
||||||
|
if (!QString::fromUtf8(classInfo.name()).startsWith(QStringLiteral(__nut_NAME_PERFIX)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
QStringList parts = QString::fromUtf8(classInfo.value()).split(QStringLiteral("\n"));
|
||||||
|
if (parts.count() != 3)
|
||||||
|
return false;
|
||||||
|
bool ok;
|
||||||
|
type = parts[0];
|
||||||
|
name = parts[1];
|
||||||
|
value = parts[2].toInt(&ok);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef NUT_RAW_POINTER
|
||||||
|
template <typename T>
|
||||||
|
using RowList = QList<T*>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using RowSet = QSet<T*>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using Row = T*;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline Row<T> create() {
|
||||||
|
return new T;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline T *get(const Row<T> row) {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline T *get(const QSharedPointer<T> row) {
|
||||||
|
return row.data();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <class T>
|
||||||
|
using RowList = QList<QSharedPointer<T>>;
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
using RowSet = QSet<QSharedPointer<T>>;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
using Row = QSharedPointer<T>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline Row<T> create() {
|
||||||
|
return QSharedPointer<T>(new T);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline Row<T> create(QObject *parent) {
|
||||||
|
return QSharedPointer<T>(new T(parent));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline Row<T> createFrom(T *row) {
|
||||||
|
return QSharedPointer<T>(row);
|
||||||
|
}
|
||||||
|
template<class T>
|
||||||
|
inline Row<T> createFrom(const QSharedPointer<T> row) {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // NUT_NAMESPACE_H
|
||||||
|
|
@ -20,53 +20,53 @@
|
||||||
|
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "tablesetbase_p.h"
|
#include "abstracttableset.h"
|
||||||
#include "databasemodel.h"
|
#include "databasemodel.h"
|
||||||
#include "tablesetbasedata.h"
|
#include "abstracttablesetdata.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
TableSetBase::TableSetBase(Database *parent) : QObject(parent),
|
AbstractTableSet::AbstractTableSet(Database *parent) : QObject(parent),
|
||||||
data(new TableSetBaseData(parent))
|
data(new AbstractTableSetData(parent))
|
||||||
{
|
{
|
||||||
parent->add(this);
|
parent->add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TableSetBase::TableSetBase(Table *parent) : QObject(parent),
|
AbstractTableSet::AbstractTableSet(Table *parent) : QObject(parent),
|
||||||
data(new TableSetBaseData(parent))
|
data(new AbstractTableSetData(parent))
|
||||||
{
|
{
|
||||||
parent->add(this);
|
parent->add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TableSetBase::~TableSetBase()
|
AbstractTableSet::~AbstractTableSet()
|
||||||
{
|
{
|
||||||
foreach (Row<Table> t, data->childs)
|
Q_FOREACH (Row<Table> t, data->childs)
|
||||||
if (t)
|
if (t)
|
||||||
t->setParentTableSet(nullptr);
|
t->setParentTableSet(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TableSetBase::save(Database *db, bool cleanUp)
|
int AbstractTableSet::save(Database *db, bool cleanUp)
|
||||||
{
|
{
|
||||||
int rowsAffected = 0;
|
int rowsAffected = 0;
|
||||||
TableModel *masterModel = nullptr;
|
TableModel *masterModel = nullptr;
|
||||||
if (data->table)
|
if (data->table)
|
||||||
masterModel = db->model().tableByClassName(data->table->metaObject()->className());
|
masterModel = db->model().tableByClassName(QString::fromUtf8(data->table->metaObject()->className()));
|
||||||
|
|
||||||
foreach (Row<Table> t, data->childs) {
|
Q_FOREACH (Row<Table> t, data->childs) {
|
||||||
if (data->table)
|
if (data->table)
|
||||||
t->setParentTable(data->table,
|
t->setParentTable(data->table,
|
||||||
masterModel,
|
masterModel,
|
||||||
db->model().tableByClassName(t->metaObject()->className()));
|
db->model().tableByClassName(QString::fromUtf8(t->metaObject()->className())));
|
||||||
|
|
||||||
if (t->status() == Table::Added
|
if (t->status() == Table::Added
|
||||||
|| t->status() == Table::Modified
|
|| t->status() == Table::Modified
|
||||||
|| t->status() == Table::Deleted) {
|
|| t->status() == Table::Deleted) {
|
||||||
rowsAffected += t->save(db);
|
rowsAffected += t->save(db);
|
||||||
if (cleanUp)
|
if (cleanUp)
|
||||||
#ifdef NUT_SHARED_POINTER
|
#ifdef NUT_RAW_POINTER
|
||||||
remove(t);
|
|
||||||
#else
|
|
||||||
t->deleteLater();
|
t->deleteLater();
|
||||||
|
#else
|
||||||
|
remove(t);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -77,42 +77,47 @@ int TableSetBase::save(Database *db, bool cleanUp)
|
||||||
return rowsAffected;
|
return rowsAffected;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableSetBase::clearChilds()
|
void AbstractTableSet::clearChilds()
|
||||||
{
|
{
|
||||||
#ifndef NUT_SHARED_POINTER
|
#ifdef NUT_RAW_POINTER
|
||||||
foreach (Table *t, data->childs)
|
Q_FOREACH (Table *t, data->childs)
|
||||||
t->deleteLater();
|
t->deleteLater();
|
||||||
#endif
|
#endif
|
||||||
data->childs.clear();
|
data->childs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableSetBase::add(Row<Table> t)
|
void AbstractTableSet::add(Row<Table> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.append(t);
|
data->childs.append(t);
|
||||||
t->setParentTableSet(this);
|
t->setParentTableSet(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableSetBase::remove(Row<Table> t)
|
void AbstractTableSet::remove(Row<Table> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.removeAll(t);
|
data->childs.removeAll(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TableSetBase::childClassName() const
|
QString AbstractTableSet::childClassName() const
|
||||||
{
|
{
|
||||||
return data->childClassName;
|
return data->childClassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
Database *TableSetBase::database() const
|
Database *AbstractTableSet::database() const
|
||||||
{
|
{
|
||||||
return data->database;
|
return data->database;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TableSetBase::setDatabase(Database *database)
|
void AbstractTableSet::setDatabase(Database *database)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->database = database;
|
data->database = database;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AbstractTableSet::size() const
|
||||||
|
{
|
||||||
|
return data->childs.size();
|
||||||
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -18,28 +18,28 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef TABLESETBASE_H
|
#ifndef NUT_ABSTRACTTABLESET_H
|
||||||
#define TABLESETBASE_H
|
#define NUT_ABSTRACTTABLESET_H
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtCore/QSet>
|
#include <QtCore/QSet>
|
||||||
#include <QExplicitlySharedDataPointer>
|
#include <QtCore/QExplicitlySharedDataPointer>
|
||||||
|
|
||||||
#include "defines.h"
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Table;
|
class Table;
|
||||||
class Database;
|
class Database;
|
||||||
class TableSetBaseData;
|
class AbstractTableSetData;
|
||||||
class NUT_EXPORT TableSetBase : public QObject
|
class NUT_EXPORT AbstractTableSet : public QObject
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TableSetBase(Database *parent);
|
explicit AbstractTableSet(Database *parent);
|
||||||
explicit TableSetBase(Table *parent);
|
explicit AbstractTableSet(Table *parent);
|
||||||
virtual ~TableSetBase();
|
virtual ~AbstractTableSet();
|
||||||
|
|
||||||
virtual int save(Database *db, bool cleanUp = false);
|
virtual int save(Database *db, bool cleanUp = false);
|
||||||
void clearChilds();
|
void clearChilds();
|
||||||
|
|
@ -48,8 +48,10 @@ public:
|
||||||
Database *database() const;
|
Database *database() const;
|
||||||
void setDatabase(Database *database);
|
void setDatabase(Database *database);
|
||||||
|
|
||||||
|
int size() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QExplicitlySharedDataPointer<TableSetBaseData> data;
|
QExplicitlySharedDataPointer<AbstractTableSetData> data;
|
||||||
|
|
||||||
public://TODO: change this to private
|
public://TODO: change this to private
|
||||||
// void add(Table* t);
|
// void add(Table* t);
|
||||||
|
|
@ -64,4 +66,4 @@ public://TODO: change this to private
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // TABLESETBASE_H
|
#endif // NUT_ABSTRACTTABLESET_H
|
||||||
|
|
@ -18,24 +18,25 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef TABLESETBASEDATA_H
|
#ifndef NUT_ABSTRACTTABLESETDATA_H
|
||||||
#define TABLESETBASEDATA_H
|
#define NUT_ABSTRACTTABLESETDATA_H
|
||||||
|
|
||||||
#include <QSharedData>
|
#include <QtCore/QSharedData>
|
||||||
#include "defines.h"
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Table;
|
class Table;
|
||||||
class Database;
|
class Database;
|
||||||
class TableSetBaseData : public QSharedData
|
class AbstractTableSetData : public QSharedData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
TableSetBaseData(Database *parent) :
|
AbstractTableSetData(Database *parent) :
|
||||||
database(parent), table(nullptr)
|
database(parent), table(nullptr)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
TableSetBaseData(Table *parent) :
|
AbstractTableSetData(Table *parent) :
|
||||||
database(nullptr), table(parent)
|
database(nullptr), table(parent)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -50,4 +51,4 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // TABLESETBASEDATA_H
|
#endif // NUT_ABSTRACTTABLESETDATA_H
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include "bulkinserter.h"
|
||||||
|
#include "bulkinserter_p.h"
|
||||||
|
|
||||||
|
#include "phrases/phraselist.h"
|
||||||
|
#include "database.h"
|
||||||
|
#include "abstractsqlgenerator.h"
|
||||||
|
#include "databasemodel.h"
|
||||||
|
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
BulkInserterPrivate::BulkInserterPrivate(Database *db)
|
||||||
|
: database(db), fieldCount(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
BulkInserter::BulkInserter(Database *db, QString &className)
|
||||||
|
: d_ptr(new BulkInserterPrivate(db))
|
||||||
|
{
|
||||||
|
Q_D(BulkInserter);
|
||||||
|
|
||||||
|
Q_FOREACH (TableModel *m, db->model())
|
||||||
|
if (m->className() == className)
|
||||||
|
d->className = m->name();
|
||||||
|
}
|
||||||
|
|
||||||
|
BulkInserter::BulkInserter(const BulkInserter &other)
|
||||||
|
{
|
||||||
|
d_ptr = other.d_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
BulkInserter::BulkInserter(BulkInserter &&other)
|
||||||
|
{
|
||||||
|
d_ptr = other.d_ptr;
|
||||||
|
other.d_ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BulkInserter::setFields(const PhraseList &ph)
|
||||||
|
{
|
||||||
|
Q_D(BulkInserter);
|
||||||
|
d->fields = ph;
|
||||||
|
d->fieldCount = static_cast<size_t>(ph.data.count());
|
||||||
|
}
|
||||||
|
|
||||||
|
void BulkInserter::insert(std::initializer_list<QVariant> vars)
|
||||||
|
{
|
||||||
|
Q_D(BulkInserter);
|
||||||
|
|
||||||
|
if (vars.size() != d->fieldCount) {
|
||||||
|
qInfo("Number of rows mistake");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariantList list;
|
||||||
|
std::initializer_list<QVariant>::iterator it;
|
||||||
|
for (it = vars.begin(); it != vars.end(); ++it)
|
||||||
|
list.append(*it);
|
||||||
|
d->variants.append(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
int BulkInserter::apply()
|
||||||
|
{
|
||||||
|
Q_D(BulkInserter);
|
||||||
|
auto sql = d->database->sqlGenerator()->insertBulk(d->className,
|
||||||
|
d->fields,
|
||||||
|
d->variants);
|
||||||
|
QSqlQuery q = d->database->exec(sql);
|
||||||
|
return q.numRowsAffected();
|
||||||
|
}
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -2,25 +2,26 @@
|
||||||
#define BULKINSERTER_H
|
#define BULKINSERTER_H
|
||||||
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include "defines.h"
|
#include <QtNut/phraselist.h>
|
||||||
#include "phrases/phraselist.h"
|
#include <QtNut/fieldphrase.h>
|
||||||
#include "phrases/fieldphrase.h"
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class PhraseList;
|
class PhraseList;
|
||||||
class Database;
|
class Database;
|
||||||
|
class BulkInserterPrivate;
|
||||||
class NUT_EXPORT BulkInserter
|
class NUT_EXPORT BulkInserter
|
||||||
{
|
{
|
||||||
Database *_database;
|
Q_DECLARE_PRIVATE(BulkInserter);
|
||||||
QString _className;
|
|
||||||
Nut::PhraseList _fields;
|
|
||||||
QList<QVariantList> variants;
|
|
||||||
size_t _fieldCount;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BulkInserter(Database *db, QString &className);
|
BulkInserter(Database *db, QString &className);
|
||||||
|
BulkInserter(const BulkInserter &other);
|
||||||
|
BulkInserter(BulkInserter &&other);
|
||||||
|
|
||||||
void setFields(const PhraseList &ph);
|
void setFields(const PhraseList &ph);
|
||||||
|
|
||||||
void insert(std::initializer_list<QVariant> vars);
|
void insert(std::initializer_list<QVariant> vars);
|
||||||
|
|
@ -29,6 +30,9 @@ public:
|
||||||
insert({args...});
|
insert({args...});
|
||||||
}
|
}
|
||||||
int apply();
|
int apply();
|
||||||
|
|
||||||
|
private:
|
||||||
|
BulkInserterPrivate *d_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef BULKINSERTER_P_H
|
||||||
|
#define BULKINSERTER_P_H
|
||||||
|
|
||||||
|
#include <QtNut/phraselist.h>
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class Database;
|
||||||
|
class BulkInserterPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BulkInserterPrivate(Database *db);
|
||||||
|
|
||||||
|
Database *database;
|
||||||
|
QString className;
|
||||||
|
PhraseList fields;
|
||||||
|
QList<QVariantList> variants;
|
||||||
|
size_t fieldCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // BULKINSERTER_P_H
|
||||||
|
|
@ -22,7 +22,7 @@
|
||||||
#define CHANGELOGTABLE_H
|
#define CHANGELOGTABLE_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include "table.h"
|
#include <QtNut/table.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/abstracttableset.h \
|
||||||
|
$$PWD/abstracttablesetdata.h \
|
||||||
|
$$PWD/bulkinserter.h \
|
||||||
|
$$PWD/bulkinserter_p.h \
|
||||||
|
$$PWD/changelogtable.h \
|
||||||
|
$$PWD/database.h \
|
||||||
|
$$PWD/database_p.h \
|
||||||
|
$$PWD/foreigncontainer.h \
|
||||||
|
$$PWD/propertysignalmapper.h \
|
||||||
|
$$PWD/query.h \
|
||||||
|
$$PWD/table.h \
|
||||||
|
$$PWD/table_p.h \
|
||||||
|
$$PWD/tableset.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/abstracttableset.cpp \
|
||||||
|
$$PWD/bulkinserter.cpp \
|
||||||
|
$$PWD/changelogtable.cpp \
|
||||||
|
$$PWD/database.cpp \
|
||||||
|
$$PWD/foreigncontainer.cpp \
|
||||||
|
$$PWD/propertysignalmapper.cpp \
|
||||||
|
$$PWD/query.cpp \
|
||||||
|
$$PWD/table.cpp \
|
||||||
|
$$PWD/tableset.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -33,12 +33,12 @@
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "tableset.h"
|
#include "tableset.h"
|
||||||
#include "database_p.h"
|
#include "database_p.h"
|
||||||
#include "defines.h"
|
#include "config/nut_global.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
#include "generators/postgresqlgenerator.h"
|
#include "postgresqlgenerator.h"
|
||||||
#include "generators/mysqlgenerator.h"
|
#include "mysqlgenerator.h"
|
||||||
#include "generators/sqlitegenerator.h"
|
#include "sqlitegenerator.h"
|
||||||
#include "generators/sqlservergenerator.h"
|
#include "sqlservergenerator.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
#include "changelogtable.h"
|
#include "changelogtable.h"
|
||||||
|
|
||||||
|
|
@ -66,7 +66,7 @@ bool DatabasePrivate::open(bool update)
|
||||||
return true;
|
return true;
|
||||||
Q_Q(Database);
|
Q_Q(Database);
|
||||||
// if (update)
|
// if (update)
|
||||||
connectionName = q->metaObject()->className()
|
connectionName = QString::fromUtf8(q->metaObject()->className())
|
||||||
+ QString::number(DatabasePrivate::lastId);
|
+ QString::number(DatabasePrivate::lastId);
|
||||||
|
|
||||||
db = QSqlDatabase::addDatabase(driver, connectionName);
|
db = QSqlDatabase::addDatabase(driver, connectionName);
|
||||||
|
|
@ -77,7 +77,7 @@ bool DatabasePrivate::open(bool update)
|
||||||
db.setUserName(userName);
|
db.setUserName(userName);
|
||||||
db.setPassword(password);
|
db.setPassword(password);
|
||||||
|
|
||||||
if (driver.startsWith("qsqlite", Qt::CaseInsensitive)
|
if (driver.startsWith(QStringLiteral("qsqlite"), Qt::CaseInsensitive)
|
||||||
&& !QFile::exists(databaseName)) {
|
&& !QFile::exists(databaseName)) {
|
||||||
//Force to execute update database
|
//Force to execute update database
|
||||||
isDatabaseNew = true;
|
isDatabaseNew = true;
|
||||||
|
|
@ -89,18 +89,20 @@ bool DatabasePrivate::open(bool update)
|
||||||
qWarning("Could not connect to database, error = %s",
|
qWarning("Could not connect to database, error = %s",
|
||||||
db.lastError().text().toLocal8Bit().data());
|
db.lastError().text().toLocal8Bit().data());
|
||||||
|
|
||||||
if (db.lastError().text().contains("database \"" + databaseName
|
if (db.lastError().text().contains(QStringLiteral("database \"")
|
||||||
+ "\" does not exist")
|
+ databaseName
|
||||||
|| db.lastError().text().contains("Cannot open database")
|
+ QStringLiteral("\" does not exist"))
|
||||||
|| db.lastError().text().contains("Unknown database '"
|
|| db.lastError().text().contains(QStringLiteral("Cannot open database"))
|
||||||
+ databaseName + "'")) {
|
|| db.lastError().text().contains(QStringLiteral("Unknown database '")
|
||||||
|
+ databaseName
|
||||||
|
+ QStringLiteral("'"))) {
|
||||||
|
|
||||||
db.close();
|
db.close();
|
||||||
db.setDatabaseName(sqlGenerator->masterDatabaseName(databaseName));
|
db.setDatabaseName(sqlGenerator->masterDatabaseName(databaseName));
|
||||||
ok = db.open();
|
ok = db.open();
|
||||||
qDebug("Creating database");
|
qDebug("Creating database");
|
||||||
if (ok) {
|
if (ok) {
|
||||||
db.exec("CREATE DATABASE " + databaseName);
|
db.exec(QStringLiteral("CREATE DATABASE ") + databaseName);
|
||||||
db.close();
|
db.close();
|
||||||
|
|
||||||
if (db.lastError().type() != QSqlError::NoError) {
|
if (db.lastError().type() != QSqlError::NoError) {
|
||||||
|
|
@ -142,8 +144,8 @@ bool DatabasePrivate::updateDatabase()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (TableModel *tm, current) {
|
Q_FOREACH (TableModel *tm, current) {
|
||||||
foreach (FieldModel *fm, tm->fields()) {
|
Q_FOREACH (FieldModel *fm, tm->fields()) {
|
||||||
if (sqlGenerator->fieldType(fm).isEmpty()) {
|
if (sqlGenerator->fieldType(fm).isEmpty()) {
|
||||||
qWarning("The type (%s) is not supported for field %s::%s",
|
qWarning("The type (%s) is not supported for field %s::%s",
|
||||||
QMetaType::typeName(fm->type),
|
QMetaType::typeName(fm->type),
|
||||||
|
|
@ -161,7 +163,7 @@ bool DatabasePrivate::updateDatabase()
|
||||||
QStringList sql = sqlGenerator->diff(last, current);
|
QStringList sql = sqlGenerator->diff(last, current);
|
||||||
|
|
||||||
db.transaction();
|
db.transaction();
|
||||||
foreach (QString s, sql) {
|
Q_FOREACH (QString s, sql) {
|
||||||
db.exec(s);
|
db.exec(s);
|
||||||
|
|
||||||
if (db.lastError().type() != QSqlError::NoError) {
|
if (db.lastError().type() != QSqlError::NoError) {
|
||||||
|
|
@ -193,8 +195,8 @@ bool DatabasePrivate::getCurrectSchema()
|
||||||
Q_Q(Database);
|
Q_Q(Database);
|
||||||
|
|
||||||
//is not first instanicate of this class
|
//is not first instanicate of this class
|
||||||
if (allTableMaps.contains(q->metaObject()->className())) {
|
if (allTableMaps.contains(QString::fromUtf8(q->metaObject()->className()))) {
|
||||||
currentModel = allTableMaps[q->metaObject()->className()];
|
currentModel = allTableMaps[QString::fromUtf8(q->metaObject()->className())];
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,9 +207,9 @@ bool DatabasePrivate::getCurrectSchema()
|
||||||
int changeLogTypeId = qRegisterMetaType<ChangeLogTable*>();
|
int changeLogTypeId = qRegisterMetaType<ChangeLogTable*>();
|
||||||
|
|
||||||
currentModel.append(
|
currentModel.append(
|
||||||
new TableModel(changeLogTypeId, __CHANGE_LOG_TABLE_NAME));
|
new TableModel(changeLogTypeId, QStringLiteral(__CHANGE_LOG_TABLE_NAME)));
|
||||||
tables.insert(ChangeLogTable::staticMetaObject.className(),
|
tables.insert(QString::fromUtf8(ChangeLogTable::staticMetaObject.className()),
|
||||||
__CHANGE_LOG_TABLE_NAME);
|
QStringLiteral(__CHANGE_LOG_TABLE_NAME));
|
||||||
|
|
||||||
changeLogs = new TableSet<ChangeLogTable>(q);
|
changeLogs = new TableSet<ChangeLogTable>(q);
|
||||||
|
|
||||||
|
|
@ -219,11 +221,11 @@ bool DatabasePrivate::getCurrectSchema()
|
||||||
if (!nutClassInfoString(q->metaObject()->classInfo(i),
|
if (!nutClassInfoString(q->metaObject()->classInfo(i),
|
||||||
type, name, value)) {
|
type, name, value)) {
|
||||||
|
|
||||||
errorMessage = QString("No valid table in %1")
|
errorMessage = QStringLiteral("No valid table in ")
|
||||||
.arg(q->metaObject()->classInfo(i).value());
|
+ QString::fromUtf8(q->metaObject()->classInfo(i).value());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (type == __nut_TABLE) {
|
if (type == QStringLiteral(__nut_TABLE)) {
|
||||||
//name: table class name
|
//name: table class name
|
||||||
//value: table variable name (table name in db)
|
//value: table variable name (table name in db)
|
||||||
tables.insert(name, value);
|
tables.insert(name, value);
|
||||||
|
|
@ -237,7 +239,7 @@ bool DatabasePrivate::getCurrectSchema()
|
||||||
currentModel.append(sch);
|
currentModel.append(sch);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == __nut_DB_VERSION) {
|
if (type == QStringLiteral(__nut_DB_VERSION)) {
|
||||||
bool ok;
|
bool ok;
|
||||||
int version = value.toInt(&ok);
|
int version = value.toInt(&ok);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
|
|
@ -250,15 +252,15 @@ bool DatabasePrivate::getCurrectSchema()
|
||||||
QMetaProperty tableProperty = q->metaObject()->property(i);
|
QMetaProperty tableProperty = q->metaObject()->property(i);
|
||||||
int typeId = QMetaType::type(tableProperty.typeName());
|
int typeId = QMetaType::type(tableProperty.typeName());
|
||||||
|
|
||||||
if (tables.values().contains(tableProperty.name())
|
if (tables.values().contains(QString::fromUtf8(tableProperty.name()))
|
||||||
&& (unsigned)typeId >= QVariant::UserType) {
|
&& (unsigned)typeId >= QVariant::UserType) {
|
||||||
TableModel *sch = new TableModel(typeId, tableProperty.name());
|
TableModel *sch = new TableModel(typeId, QString::fromUtf8(tableProperty.name()));
|
||||||
currentModel.append(sch);
|
currentModel.append(sch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (TableModel *table, currentModel) {
|
Q_FOREACH (TableModel *table, currentModel) {
|
||||||
foreach (FieldModel *f, table->fields()) {
|
Q_FOREACH (FieldModel *f, table->fields()) {
|
||||||
if (f->isPrimaryKey && ! sqlGenerator->supportPrimaryKey(f->type))
|
if (f->isPrimaryKey && ! sqlGenerator->supportPrimaryKey(f->type))
|
||||||
qFatal("The field of type %s does not support as primary key",
|
qFatal("The field of type %s does not support as primary key",
|
||||||
qPrintable(f->typeName));
|
qPrintable(f->typeName));
|
||||||
|
|
@ -268,31 +270,33 @@ bool DatabasePrivate::getCurrectSchema()
|
||||||
qPrintable(f->typeName));
|
qPrintable(f->typeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (RelationModel *fk, table->foreignKeys())
|
Q_FOREACH (RelationModel *fk, table->foreignKeys())
|
||||||
fk->masterTable = currentModel.tableByClassName(fk->masterClassName);
|
fk->masterTable = currentModel.tableByClassName(fk->masterClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
allTableMaps.insert(q->metaObject()->className(), currentModel);
|
allTableMaps.insert(QString::fromUtf8(q->metaObject()->className()), currentModel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseModel DatabasePrivate::getLastSchema()
|
DatabaseModel DatabasePrivate::getLastSchema()
|
||||||
{
|
{
|
||||||
Row<ChangeLogTable> u = changeLogs->query()
|
Row<ChangeLogTable> u = changeLogs->query()
|
||||||
->orderBy(!ChangeLogTable::idField())
|
.orderBy(!ChangeLogTable::idField())
|
||||||
->first();
|
.first();
|
||||||
|
|
||||||
// DatabaseModel ret(q->metaObject()->className());
|
|
||||||
|
|
||||||
if (u) {
|
if (u) {
|
||||||
QJsonParseError e;
|
QJsonParseError e;
|
||||||
QJsonObject json
|
QJsonObject json = QJsonDocument::fromJson(u->data()
|
||||||
= QJsonDocument::fromJson(u->data().replace("\\\"", "\"").toUtf8(), &e).object();
|
.replace(QStringLiteral("\\\""),
|
||||||
|
QStringLiteral("\""))
|
||||||
|
.toUtf8(),
|
||||||
|
&e)
|
||||||
|
.object();
|
||||||
|
|
||||||
DatabaseModel ret = json;
|
DatabaseModel ret = json;
|
||||||
return ret;
|
return ret;
|
||||||
/*
|
/*
|
||||||
foreach (QString key, json.keys()) {
|
Q_FOREACH (QString key, json.keys()) {
|
||||||
TableModel *sch = new TableModel(json.value(key).toObject(), key);
|
TableModel *sch = new TableModel(json.value(key).toObject(), key);
|
||||||
ret.append(sch);
|
ret.append(sch);
|
||||||
}*/
|
}*/
|
||||||
|
|
@ -306,7 +310,7 @@ DatabaseModel DatabasePrivate::getLastSchema()
|
||||||
// QJsonObject json =
|
// QJsonObject json =
|
||||||
// QJsonDocument::fromJson(query.value("data").toByteArray()).object();
|
// QJsonDocument::fromJson(query.value("data").toByteArray()).object();
|
||||||
|
|
||||||
// foreach (QString key, json.keys()) {
|
// Q_FOREACH (QString key, json.keys()) {
|
||||||
// TableModel *sch = new TableModel(json.value(key).toObject(),
|
// TableModel *sch = new TableModel(json.value(key).toObject(),
|
||||||
// key);
|
// key);
|
||||||
// ret.append(sch);
|
// ret.append(sch);
|
||||||
|
|
@ -322,7 +326,7 @@ bool DatabasePrivate::putModelToDatabase()
|
||||||
/*current.remove(__CHANGE_LOG_TABLE_NAME)*/;
|
/*current.remove(__CHANGE_LOG_TABLE_NAME)*/;
|
||||||
|
|
||||||
auto changeLog = create<ChangeLogTable>();
|
auto changeLog = create<ChangeLogTable>();
|
||||||
changeLog->setData(QJsonDocument(current.toJson()).toJson(QJsonDocument::Compact));
|
changeLog->setData(QString::fromUtf8(QJsonDocument(current.toJson()).toJson(QJsonDocument::Compact)));
|
||||||
changeLog->setVersion(current.version());
|
changeLog->setVersion(current.version());
|
||||||
changeLogs->append(changeLog);
|
changeLogs->append(changeLog);
|
||||||
q->saveChanges(true);
|
q->saveChanges(true);
|
||||||
|
|
@ -344,9 +348,11 @@ bool DatabasePrivate::putModelToDatabase()
|
||||||
void DatabasePrivate::createChangeLogs()
|
void DatabasePrivate::createChangeLogs()
|
||||||
{
|
{
|
||||||
// currentModel.model("change_log")
|
// currentModel.model("change_log")
|
||||||
QStringList diff = sqlGenerator->diff(nullptr, currentModel.tableByName("__change_log"));
|
QStringList diff = sqlGenerator->diff(nullptr,
|
||||||
|
currentModel.tableByName(
|
||||||
|
QStringLiteral("__change_log")));
|
||||||
|
|
||||||
foreach (QString s, diff)
|
Q_FOREACH (QString s, diff)
|
||||||
db.exec(s);
|
db.exec(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -358,7 +364,6 @@ void DatabasePrivate::createChangeLogs()
|
||||||
Database::Database(QObject *parent)
|
Database::Database(QObject *parent)
|
||||||
: QObject(parent), d_ptr(new DatabasePrivate(this))
|
: QObject(parent), d_ptr(new DatabasePrivate(this))
|
||||||
{
|
{
|
||||||
// _d = new QSharedDataPointer<DatabasePrivate>(new DatabasePrivate(this));
|
|
||||||
DatabasePrivate::lastId++;
|
DatabasePrivate::lastId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -366,7 +371,6 @@ Database::Database(const Database &other)
|
||||||
: QObject(other.parent()), d_ptr(new DatabasePrivate(this))
|
: QObject(other.parent()), d_ptr(new DatabasePrivate(this))
|
||||||
{
|
{
|
||||||
DatabasePrivate::lastId++;
|
DatabasePrivate::lastId++;
|
||||||
// _d = other._d;
|
|
||||||
|
|
||||||
setDriver(other.driver());
|
setDriver(other.driver());
|
||||||
setHostName(other.hostName());
|
setHostName(other.hostName());
|
||||||
|
|
@ -381,7 +385,7 @@ Database::Database(const QSqlDatabase &other)
|
||||||
//TODO: make a polish here
|
//TODO: make a polish here
|
||||||
DatabasePrivate::lastId++;
|
DatabasePrivate::lastId++;
|
||||||
|
|
||||||
// setDriver(other.driver());
|
setDriver(other.driverName());
|
||||||
setHostName(other.hostName());
|
setHostName(other.hostName());
|
||||||
setPort(other.port());
|
setPort(other.port());
|
||||||
setDatabaseName(other.databaseName());
|
setDatabaseName(other.databaseName());
|
||||||
|
|
@ -390,6 +394,12 @@ Database::Database(const QSqlDatabase &other)
|
||||||
qRegisterMetaType<ChangeLogTable*>();
|
qRegisterMetaType<ChangeLogTable*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Database::Database(Database &&other)
|
||||||
|
{
|
||||||
|
d_ptr = other.d_ptr;
|
||||||
|
other.d_ptr = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
Database::~Database()
|
Database::~Database()
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
|
|
@ -506,7 +516,7 @@ void Database::setDriver(QString driver)
|
||||||
d->driver = driver.toUpper();
|
d->driver = driver.toUpper();
|
||||||
}
|
}
|
||||||
|
|
||||||
SqlGeneratorBase *Database::sqlGenerator() const
|
AbstractSqlGenerator *Database::sqlGenerator() const
|
||||||
{
|
{
|
||||||
Q_D(const Database);
|
Q_D(const Database);
|
||||||
return d->sqlGenerator;
|
return d->sqlGenerator;
|
||||||
|
|
@ -545,17 +555,17 @@ bool Database::open(bool updateDatabase)
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
|
|
||||||
if (d->driver == "QPSQL" || d->driver == "QPSQL7")
|
if (d->driver == QStringLiteral("QPSQL") || d->driver == QStringLiteral("QPSQL7"))
|
||||||
d->sqlGenerator = new PostgreSqlGenerator(this);
|
d->sqlGenerator = new PostgreSqlGenerator(this);
|
||||||
else if (d->driver == "QMYSQL" || d->driver == "QMYSQL3")
|
else if (d->driver == QStringLiteral("QMYSQL") || d->driver == QStringLiteral("QMYSQL3"))
|
||||||
d->sqlGenerator = new MySqlGenerator(this);
|
d->sqlGenerator = new MySqlGenerator(this);
|
||||||
else if (d->driver == "QSQLITE" || d->driver == "QSQLITE3")
|
else if (d->driver == QStringLiteral("QSQLITE") || d->driver == QStringLiteral("QSQLITE3"))
|
||||||
d->sqlGenerator = new SqliteGenerator(this);
|
d->sqlGenerator = new SqliteGenerator(this);
|
||||||
else if (d->driver == "QODBC" || d->driver == "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(';');
|
||||||
foreach (QString p, parts)
|
Q_FOREACH (QString p, parts)
|
||||||
if (p.trimmed().startsWith("driver="))
|
if (p.trimmed().startsWith(QStringLiteral("driver=")))
|
||||||
driverName = p.split('=').at(1).toLower().trimmed();
|
driverName = p.split('=').at(1).toLower().trimmed();
|
||||||
|
|
||||||
// if (driverName == "{sql server}")
|
// if (driverName == "{sql server}")
|
||||||
|
|
@ -589,7 +599,7 @@ QSqlQuery Database::exec(const QString &sql)
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::add(TableSetBase *t)
|
void Database::add(AbstractTableSet *t)
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
d->tableSets.insert(t);
|
d->tableSets.insert(t);
|
||||||
|
|
@ -605,7 +615,7 @@ int Database::saveChanges(bool cleanUp)
|
||||||
}
|
}
|
||||||
|
|
||||||
int rowsAffected = 0;
|
int rowsAffected = 0;
|
||||||
foreach (TableSetBase *ts, d->tableSets)
|
Q_FOREACH (AbstractTableSet *ts, d->tableSets)
|
||||||
rowsAffected += ts->save(this, cleanUp);
|
rowsAffected += ts->save(this, cleanUp);
|
||||||
|
|
||||||
return rowsAffected;
|
return rowsAffected;
|
||||||
|
|
@ -614,7 +624,7 @@ int Database::saveChanges(bool cleanUp)
|
||||||
void Database::cleanUp()
|
void Database::cleanUp()
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
foreach (TableSetBase *ts, d->tableSets)
|
Q_FOREACH (AbstractTableSet *ts, d->tableSets)
|
||||||
ts->clearChilds();
|
ts->clearChilds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -23,18 +23,18 @@
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
|
#include <QtCore/QSharedDataPointer>
|
||||||
#include <QtSql/QSqlDatabase>
|
#include <QtSql/QSqlDatabase>
|
||||||
#include <QSharedDataPointer>
|
|
||||||
|
|
||||||
#include "defines.h"
|
#include <QtNut/nut_global.h>
|
||||||
#include "tableset.h"
|
#include <QtNut/tableset.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class DatabaseModel;
|
class DatabaseModel;
|
||||||
class DatabasePrivate;
|
class DatabasePrivate;
|
||||||
class TableSetBase;
|
class AbstractTableSet;
|
||||||
class SqlGeneratorBase;
|
class AbstractSqlGenerator;
|
||||||
class ChangeLogTable;
|
class ChangeLogTable;
|
||||||
class NUT_EXPORT Database : public QObject
|
class NUT_EXPORT Database : public QObject
|
||||||
{
|
{
|
||||||
|
|
@ -48,6 +48,7 @@ public:
|
||||||
explicit Database(QObject *parent = nullptr);
|
explicit Database(QObject *parent = nullptr);
|
||||||
explicit Database(const Database &other);
|
explicit Database(const Database &other);
|
||||||
explicit Database(const QSqlDatabase &other);
|
explicit Database(const QSqlDatabase &other);
|
||||||
|
explicit Database(Database &&other);
|
||||||
~Database();
|
~Database();
|
||||||
|
|
||||||
bool open();
|
bool open();
|
||||||
|
|
@ -70,7 +71,7 @@ public:
|
||||||
DatabaseModel model() const;
|
DatabaseModel model() const;
|
||||||
QString tableName(QString className);
|
QString tableName(QString className);
|
||||||
|
|
||||||
SqlGeneratorBase *sqlGenerator() const;
|
AbstractSqlGenerator *sqlGenerator() const;
|
||||||
QSqlDatabase database();
|
QSqlDatabase database();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
@ -78,7 +79,7 @@ protected:
|
||||||
virtual void databaseCreated();
|
virtual void databaseCreated();
|
||||||
virtual void databaseUpdated(int oldVersion, int newVersion);
|
virtual void databaseUpdated(int oldVersion, int newVersion);
|
||||||
|
|
||||||
public slots:
|
public Q_SLOTS:
|
||||||
void setDatabaseName(QString databaseName);
|
void setDatabaseName(QString databaseName);
|
||||||
void setHostName(QString hostName);
|
void setHostName(QString hostName);
|
||||||
void setPort(int port);
|
void setPort(int port);
|
||||||
|
|
@ -88,9 +89,9 @@ public slots:
|
||||||
void setDriver(QString driver);
|
void setDriver(QString driver);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void add(TableSetBase *);
|
void add(AbstractTableSet *);
|
||||||
|
|
||||||
friend class TableSetBase;
|
friend class AbstractTableSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -21,16 +21,16 @@
|
||||||
#ifndef DATABASE_P_H
|
#ifndef DATABASE_P_H
|
||||||
#define DATABASE_P_H
|
#define DATABASE_P_H
|
||||||
|
|
||||||
#include "database.h"
|
#include <QtCore/QDebug>
|
||||||
#include "databasemodel.h"
|
#include <QtCore/QSharedData>
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QtNut/database.h>
|
||||||
#include <QSharedData>
|
#include <QtNut/databasemodel.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class ChangeLogTable;
|
class ChangeLogTable;
|
||||||
class NUT_EXPORT DatabasePrivate //: public QSharedData
|
class NUT_EXPORT DatabasePrivate
|
||||||
{
|
{
|
||||||
Database *q_ptr;
|
Database *q_ptr;
|
||||||
Q_DECLARE_PUBLIC(Database)
|
Q_DECLARE_PUBLIC(Database)
|
||||||
|
|
@ -56,7 +56,7 @@ public:
|
||||||
QString connectionName;
|
QString connectionName;
|
||||||
QString driver;
|
QString driver;
|
||||||
|
|
||||||
SqlGeneratorBase *sqlGenerator;
|
AbstractSqlGenerator *sqlGenerator;
|
||||||
DatabaseModel currentModel;
|
DatabaseModel currentModel;
|
||||||
|
|
||||||
TableSet<ChangeLogTable> *changeLogs;
|
TableSet<ChangeLogTable> *changeLogs;
|
||||||
|
|
@ -64,7 +64,7 @@ public:
|
||||||
static QMap<QString, DatabaseModel> allTableMaps;
|
static QMap<QString, DatabaseModel> allTableMaps;
|
||||||
static qulonglong lastId;
|
static qulonglong lastId;
|
||||||
|
|
||||||
QSet<TableSetBase *> tableSets;
|
QSet<AbstractTableSet *> tableSets;
|
||||||
|
|
||||||
bool isDatabaseNew;
|
bool isDatabaseNew;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include "foreigncontainer.h"
|
||||||
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
#ifndef FOREIGNCONTAINER_H
|
||||||
|
#define FOREIGNCONTAINER_H
|
||||||
|
|
||||||
|
template<class _OBJECT, typename _KEY>
|
||||||
|
class ForeignContainer
|
||||||
|
{
|
||||||
|
_OBJECT *_object{nullptr};
|
||||||
|
_KEY _key;
|
||||||
|
enum StorageType {
|
||||||
|
Key,
|
||||||
|
ClassValue
|
||||||
|
};
|
||||||
|
StorageType storageType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ForeignContainer()
|
||||||
|
{}
|
||||||
|
|
||||||
|
ForeignContainer<_OBJECT, _KEY> operator =(const _KEY &key)
|
||||||
|
{
|
||||||
|
this->_key = key;
|
||||||
|
this->_object = nullptr;
|
||||||
|
this->storageType = Key;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ForeignContainer<_OBJECT, _KEY> operator =(const _OBJECT *value)
|
||||||
|
{
|
||||||
|
this->_object = value;
|
||||||
|
this->storageType = ClassValue;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
_KEY key()
|
||||||
|
{
|
||||||
|
if (this->storageType == Key)
|
||||||
|
return _key;
|
||||||
|
else
|
||||||
|
return _object->primaryValue().template value<_KEY>();
|
||||||
|
}
|
||||||
|
|
||||||
|
_OBJECT *object()
|
||||||
|
{
|
||||||
|
return _object;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator _KEY()
|
||||||
|
{
|
||||||
|
return key();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator _OBJECT()
|
||||||
|
{
|
||||||
|
return object();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FOREIGNCONTAINER_H
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Nut project.
|
||||||
|
** https://github.com/HamedMasafi/Nut
|
||||||
|
**
|
||||||
|
** Nut is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Nut is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU Lesser General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU Lesser General Public License
|
||||||
|
** along with Nut. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "propertysignalmapper.h"
|
||||||
|
#include "table.h"
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
QMap<QString, PropertySignalMapper::ClassData*> PropertySignalMapper::_data;
|
||||||
|
|
||||||
|
void PropertySignalMapper::map(Table *obj)
|
||||||
|
{
|
||||||
|
if (obj->_is_signals_mapped)
|
||||||
|
return;
|
||||||
|
ClassData *d;
|
||||||
|
const QMetaObject *mo = obj->metaObject();
|
||||||
|
auto className = QString::fromUtf8(mo->className());
|
||||||
|
|
||||||
|
if (_data.contains(className)) {
|
||||||
|
d = _data.value(className);
|
||||||
|
|
||||||
|
for (auto &p: d->properties)
|
||||||
|
QObject::connect(obj, p.notifySignal(), obj, d->propertyChanged);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
d = new ClassData;
|
||||||
|
d->propertyChanged = mo->method(mo->indexOfSlot("propertyChanged()"));
|
||||||
|
|
||||||
|
for (int i = 0; i < mo->propertyCount(); ++i) {
|
||||||
|
QMetaProperty p = mo->property(i);
|
||||||
|
if (!strcmp(p.name(), "objectName"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (p.hasNotifySignal()) {
|
||||||
|
d->signalMaps.insert(QLatin1String(p.notifySignal().name()),
|
||||||
|
QLatin1String(p.name()));
|
||||||
|
d->properties.append(p);
|
||||||
|
QObject::connect(obj, p.notifySignal(), obj, d->propertyChanged);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_data.insert(className, d);
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->_is_signals_mapped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString PropertySignalMapper::changedProperty(QObject *obj, int senderSignalIndex)
|
||||||
|
{
|
||||||
|
return _data.value(QString::fromUtf8(obj->metaObject()->className()))
|
||||||
|
->signalMaps.value(
|
||||||
|
QString::fromUtf8(obj->metaObject()->method(senderSignalIndex).name())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -18,37 +18,32 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef QUERYBASE_H
|
#ifndef PROPERTYSIGNALMAPPER_H
|
||||||
#define QUERYBASE_H
|
#define PROPERTYSIGNALMAPPER_H
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtNut/nut_global.h>
|
||||||
#include <QtCore/qglobal.h>
|
|
||||||
#include <QtCore/QExplicitlySharedDataPointer>
|
|
||||||
|
|
||||||
#include "defines.h"
|
#include <QMetaMethod>
|
||||||
#include "query_p.h"
|
#include <QMetaProperty>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
//TODO: remove this class
|
|
||||||
class Table;
|
class Table;
|
||||||
class TableSetBase;
|
class PropertySignalMapper
|
||||||
class NUT_EXPORT QueryBase : public QObject
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
struct ClassData
|
||||||
|
{
|
||||||
protected:
|
QMetaMethod propertyChanged;
|
||||||
QExplicitlySharedDataPointer<QueryPrivate> d;
|
QList<QMetaProperty> properties;
|
||||||
|
QMap<QString, QString> signalMaps;
|
||||||
|
};
|
||||||
|
static QMap<QString, ClassData*> _data;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit QueryBase(QObject *parent = nullptr);
|
static void map(Table *obj);
|
||||||
|
static QString changedProperty(QObject *obj, int senderSignalIndex);
|
||||||
protected:
|
|
||||||
// void addTableToSet(TableSetBase *set, Table *table);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QUERYBASE_H
|
#endif // PROPERTYSIGNALMAPPER_H
|
||||||
|
|
@ -22,17 +22,6 @@
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QueryPrivate::QueryPrivate(QueryBase *parent) : q_ptr(parent),
|
|
||||||
database(nullptr), tableSet(nullptr), skip(-1), take(-1)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QueryPrivate::~QueryPrivate()
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \class Query
|
* \class Query
|
||||||
* \brief This class hold a query. A query can be used for getting database rows, editing or deleting without row fetching.
|
* \brief This class hold a query. A query can be used for getting database rows, editing or deleting without row fetching.
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef QUERY_H
|
#ifndef NUT_QUERY_H
|
||||||
#define QUERY_H
|
#define NUT_QUERY_H
|
||||||
|
|
||||||
#include <QtCore/QVariant>
|
#include <QtCore/QVariant>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
@ -31,54 +31,93 @@
|
||||||
#include <QtSql/QSqlQueryModel>
|
#include <QtSql/QSqlQueryModel>
|
||||||
#include <QtSql/QSqlQuery>
|
#include <QtSql/QSqlQuery>
|
||||||
|
|
||||||
#ifdef NUT_SHARED_POINTER
|
#ifndef NUT_RAW_POINTER
|
||||||
#include <QtCore/QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "table.h"
|
#include <QtNut/table.h>
|
||||||
#include "query_p.h"
|
#include <QtNut/database.h>
|
||||||
#include "database.h"
|
#include <QtNut/databasemodel.h>
|
||||||
#include "databasemodel.h"
|
#include <QtNut/abstracttableset.h>
|
||||||
#include "tablesetbase_p.h"
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
#include "generators/sqlgeneratorbase_p.h"
|
#include <QtNut/phrase.h>
|
||||||
#include "querybase_p.h"
|
#include <QtNut/tablemodel.h>
|
||||||
#include "phrase.h"
|
#include <QtNut/sqlmodel.h>
|
||||||
#include "tablemodel.h"
|
|
||||||
#include "sqlmodel.h"
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template <class T>
|
struct NUT_EXPORT QueryData {
|
||||||
class Query : public QueryBase
|
QString sql;
|
||||||
{
|
QString className;
|
||||||
QueryPrivate *d_ptr;
|
QString tableName;
|
||||||
Q_DECLARE_PRIVATE(Query)
|
QString select;
|
||||||
|
Database *database;
|
||||||
|
AbstractTableSet *tableSet;
|
||||||
|
QStringList joins;
|
||||||
|
QList<RelationModel*> relations;
|
||||||
|
int skip;
|
||||||
|
int take;
|
||||||
|
PhraseList orderPhrase, fieldPhrase;
|
||||||
|
ConditionalPhrase wherePhrase;
|
||||||
|
|
||||||
bool m_autoDelete;
|
QueryData *clone() {
|
||||||
|
auto r = new QueryData;
|
||||||
|
r->sql = sql;
|
||||||
|
r->className = className;
|
||||||
|
r->tableName = tableName;
|
||||||
|
r->select = select;
|
||||||
|
r->database = database;
|
||||||
|
r->tableSet = tableSet;
|
||||||
|
r->joins = joins;
|
||||||
|
r->relations = relations;
|
||||||
|
r->skip = skip;
|
||||||
|
r->take = take;
|
||||||
|
r->orderPhrase = orderPhrase;
|
||||||
|
r->fieldPhrase = fieldPhrase;
|
||||||
|
r->wherePhrase = wherePhrase;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryData() : skip(0), take(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
QueryData(Database *db) : database(db), skip(0), take(0)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class Query
|
||||||
|
{
|
||||||
|
QueryData *d;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Query(Database *database, TableSetBase *tableSet, bool autoDelete);
|
explicit Query(Database *database, AbstractTableSet *tableSet);
|
||||||
|
Query (const Query<T> &other);
|
||||||
|
Query (Query<T> &&other);
|
||||||
|
|
||||||
~Query();
|
~Query();
|
||||||
|
|
||||||
|
Query<T>& operator=(const Query<T> &q);
|
||||||
|
|
||||||
//ddl
|
//ddl
|
||||||
|
|
||||||
Query<T> *join(const QString &className);
|
Query<T> &join(const QString &className);
|
||||||
Query<T> *join(Table *c);
|
Query<T> &join(Table *c);
|
||||||
|
|
||||||
template<class TABLE>
|
template<class TABLE>
|
||||||
Query<T> *join()
|
Query<T> &join()
|
||||||
{
|
{
|
||||||
join(TABLE::staticMetaObject.className());
|
join(TABLE::staticMetaObject.className());
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query<T> *orderBy(QString fieldName, QString type);
|
// Query<T> &orderBy(QString fieldName, QString type);
|
||||||
Query<T> *skip(int n);
|
Query<T> &skip(int n);
|
||||||
Query<T> *take(int n);
|
Query<T> &take(int n);
|
||||||
Query<T> *fields(const PhraseList &ph);
|
Query<T> &fields(const PhraseList &ph);
|
||||||
Query<T> *orderBy(const PhraseList &ph);
|
Query<T> &orderBy(const PhraseList &ph);
|
||||||
Query<T> *where(const ConditionalPhrase &ph);
|
Query<T> &where(const ConditionalPhrase &ph);
|
||||||
Query<T> *setWhere(const ConditionalPhrase &ph);
|
Query<T> &setWhere(const ConditionalPhrase &ph);
|
||||||
|
|
||||||
//data selecting
|
//data selecting
|
||||||
Row<T> first();
|
Row<T> first();
|
||||||
|
|
@ -95,11 +134,10 @@ public:
|
||||||
QVariant sum(const FieldPhrase<int> &f);
|
QVariant sum(const FieldPhrase<int> &f);
|
||||||
QVariant average(const FieldPhrase<int> &f);
|
QVariant average(const FieldPhrase<int> &f);
|
||||||
|
|
||||||
QVariant insert(const AssignmentPhraseList &p);
|
|
||||||
|
|
||||||
//data mailpulation
|
//data mailpulation
|
||||||
int update(const AssignmentPhraseList &ph);
|
int update(const AssignmentPhraseList &ph);
|
||||||
// int insert(const AssignmentPhraseList &ph);
|
QVariant insert(const AssignmentPhraseList &p);
|
||||||
int remove();
|
int remove();
|
||||||
|
|
||||||
QSqlQueryModel *toModel();
|
QSqlQueryModel *toModel();
|
||||||
|
|
@ -114,16 +152,17 @@ template<typename T>
|
||||||
template<typename O>
|
template<typename O>
|
||||||
Q_OUTOFLINE_TEMPLATE QList<O> Query<T>::select(const std::function<O (const QSqlQuery &)> allocator)
|
Q_OUTOFLINE_TEMPLATE QList<O> Query<T>::select(const std::function<O (const QSqlQuery &)> allocator)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
QList<O> ret;
|
QList<O> ret;
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
d->tableName,
|
AbstractSqlGenerator::SingleField,
|
||||||
SqlGeneratorBase::SingleField, "*",
|
QStringLiteral("*"),
|
||||||
d->wherePhrase,
|
d->wherePhrase,
|
||||||
d->relations,
|
d->relations,
|
||||||
d->skip, d->take);
|
d->skip,
|
||||||
|
d->take);
|
||||||
|
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
|
|
@ -132,47 +171,66 @@ Q_OUTOFLINE_TEMPLATE QList<O> Query<T>::select(const std::function<O (const QSql
|
||||||
ret.append(obj);
|
ret.append(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_autoDelete)
|
|
||||||
deleteLater();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
//template <typename T>
|
//template <typename T>
|
||||||
//inline Query<T> *createQuery(TableSet<T> *tableSet)
|
//inline Query<T> &createQuery(TableSet<T> *tableSet)
|
||||||
//{
|
//{
|
||||||
// return tableSet->query();
|
// return tableSet->query();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, TableSetBase *tableSet,
|
Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, AbstractTableSet *tableSet)
|
||||||
bool autoDelete)
|
: d(new QueryData(database))
|
||||||
: QueryBase(database), d_ptr(new QueryPrivate(this)),
|
|
||||||
m_autoDelete(autoDelete)
|
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->database = database;
|
d->database = database;
|
||||||
d->tableSet = tableSet;
|
d->tableSet = tableSet;
|
||||||
d->className = T::staticMetaObject.className();
|
d->className = QString::fromUtf8(T::staticMetaObject.className());
|
||||||
d->tableName =
|
d->tableName =
|
||||||
d->database->model()
|
d->database->model()
|
||||||
.tableByClassName(d->className)
|
.tableByClassName(d->className)
|
||||||
->name();
|
->name();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE Query<T>::Query(const Query<T> &other) {
|
||||||
|
d = other.d->clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE Query<T>::Query(Query<T> &&other) {
|
||||||
|
d = std::move(other.d);
|
||||||
|
other.d = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
|
Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::operator=(const Query<T> &q)
|
||||||
|
{
|
||||||
|
if (this != &q)
|
||||||
|
{
|
||||||
|
QueryData *p = q.d ? q.d->clone() : nullptr;
|
||||||
|
delete d;
|
||||||
|
d = p;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
RowList<T> returnList;
|
RowList<T> returnList;
|
||||||
d->select = "*";
|
d->select = QStringLiteral("*");
|
||||||
|
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase,
|
d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase,
|
||||||
|
|
@ -186,7 +244,7 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
|
|
||||||
QSet<TableModel*> relatedTables;
|
QSet<TableModel*> relatedTables;
|
||||||
relatedTables << d->database->model().tableByName(d->tableName);
|
relatedTables << d->database->model().tableByName(d->tableName);
|
||||||
foreach (RelationModel *rel, d->relations)
|
Q_FOREACH (RelationModel *rel, d->relations)
|
||||||
relatedTables << rel->slaveTable << rel->masterTable;
|
relatedTables << rel->slaveTable << rel->masterTable;
|
||||||
|
|
||||||
struct LevelData{
|
struct LevelData{
|
||||||
|
|
@ -207,11 +265,13 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
|
|
||||||
LevelData data;
|
LevelData data;
|
||||||
data.table = table;
|
data.table = table;
|
||||||
data.keyFiledname = data.table->name() + "." + data.table->primaryKey();
|
data.keyFiledname = data.table->name()
|
||||||
|
+ QStringLiteral(".")
|
||||||
|
+ data.table->primaryKey();
|
||||||
data.lastKeyValue = QVariant();
|
data.lastKeyValue = QVariant();
|
||||||
|
|
||||||
QHash<QString, QString> masters;
|
QHash<QString, QString> masters;
|
||||||
foreach (RelationModel *rel, d->relations)
|
Q_FOREACH (RelationModel *rel, d->relations)
|
||||||
if (rel->slaveTable->name() == table->name())
|
if (rel->slaveTable->name() == table->name())
|
||||||
masters.insert(rel->masterTable->name(), rel->localProperty);
|
masters.insert(rel->masterTable->name(), rel->localProperty);
|
||||||
|
|
||||||
|
|
@ -241,7 +301,7 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
if (!importedTables.count()) {
|
if (!importedTables.count()) {
|
||||||
LevelData data;
|
LevelData data;
|
||||||
data.table = d->database->model().tableByName(d->tableName);
|
data.table = d->database->model().tableByName(d->tableName);
|
||||||
data.keyFiledname = d->tableName + "." + data.table->primaryKey();
|
data.keyFiledname = d->tableName + QStringLiteral(".") + data.table->primaryKey();
|
||||||
data.lastKeyValue = QVariant();
|
data.lastKeyValue = QVariant();
|
||||||
|
|
||||||
levels.append(data);
|
levels.append(data);
|
||||||
|
|
@ -277,7 +337,7 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if master if current table has processed
|
// check if master if current table has processed
|
||||||
foreach (int m, data.masters)
|
Q_FOREACH (int m, data.masters)
|
||||||
if (!checked[m]) {
|
if (!checked[m]) {
|
||||||
// qDebug() << "row is checked";
|
// qDebug() << "row is checked";
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -290,11 +350,14 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
//create table row
|
//create table row
|
||||||
Row<Table> row;
|
Row<Table> row;
|
||||||
if (data.table->className() == d->className) {
|
if (data.table->className() == d->className) {
|
||||||
row = Nut::create<T>();
|
Row<T> tmpRow = Nut::create<T>();
|
||||||
#ifdef NUT_SHARED_POINTER
|
row = tmpRow.template objectCast<Table>();
|
||||||
returnList.append(row.objectCast<T>());
|
|
||||||
#else
|
row->init();
|
||||||
|
#ifdef NUT_RAW_POINTER
|
||||||
returnList.append(dynamic_cast<T*>(table));
|
returnList.append(dynamic_cast<T*>(table));
|
||||||
|
#else
|
||||||
|
returnList.append(tmpRow);
|
||||||
#endif
|
#endif
|
||||||
d->tableSet->add(row);
|
d->tableSet->add(row);
|
||||||
|
|
||||||
|
|
@ -311,21 +374,36 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<FieldModel*> childFields = data.table->fields();
|
QList<FieldModel*> childFields = data.table->fields();
|
||||||
foreach (FieldModel *field, childFields)
|
Q_FOREACH (FieldModel *field, childFields)
|
||||||
row->setProperty(field->name.toLatin1().data(),
|
row->setProperty(field->name.toLatin1().data(),
|
||||||
d->database->sqlGenerator()->unescapeValue(
|
d->database->sqlGenerator()->unescapeValue(
|
||||||
field->type,
|
field->type,
|
||||||
q.value(data.table->name() + "." + field->name)));
|
q.value(data.table->name() + QStringLiteral(".") + field->name)));
|
||||||
|
|
||||||
for (int i = 0; i < data.masters.count(); ++i) {
|
for (int i = 0; i < data.masters.count(); ++i) {
|
||||||
int master = data.masters[i];
|
int master = data.masters[i];
|
||||||
auto tableset = levels[master].lastRow.data()->childTableSet(
|
auto tableset = levels[master].lastRow.data()->childTableSet(
|
||||||
data.table->className());
|
data.table->className());
|
||||||
tableset->add(row);
|
if (tableset)
|
||||||
|
tableset->add(row);
|
||||||
|
|
||||||
|
//set key
|
||||||
|
{
|
||||||
|
QString setterName = data.masterFields[master];
|
||||||
|
setterName[0] = setterName[0].toUpper();
|
||||||
|
setterName.prepend(QStringLiteral("set"));
|
||||||
|
|
||||||
|
bool ok = row->metaObject()->invokeMethod(row.data(),
|
||||||
|
setterName.toStdString().c_str(),
|
||||||
|
Qt::DirectConnection,
|
||||||
|
Q_ARG(Nut::Row<Nut::Table>,
|
||||||
|
levels[master].lastRow));
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
row->setStatus(Table::FetchedFromDB);
|
row->setStatus(Table::FetchedFromDB);
|
||||||
row->setParent(this);
|
// row->setParent(this);
|
||||||
row->clear();
|
row->clear();
|
||||||
|
|
||||||
//set last created row
|
//set last created row
|
||||||
|
|
@ -333,10 +411,6 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
} //while
|
} //while
|
||||||
} // while
|
} // while
|
||||||
|
|
||||||
#ifndef NUT_SHARED_POINTER
|
|
||||||
if (m_autoDelete)
|
|
||||||
deleteLater();
|
|
||||||
#endif
|
|
||||||
return returnList;
|
return returnList;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -345,13 +419,13 @@ template <typename T>
|
||||||
template <typename F>
|
template <typename F>
|
||||||
Q_OUTOFLINE_TEMPLATE QList<F> Query<T>::select(const FieldPhrase<F> f)
|
Q_OUTOFLINE_TEMPLATE QList<F> Query<T>::select(const FieldPhrase<F> f)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
QList<F> ret;
|
QList<F> ret;
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
SqlGeneratorBase::SingleField, f.data->toString(),
|
AbstractSqlGenerator::SingleField, f.data->toString(),
|
||||||
d->wherePhrase,
|
d->wherePhrase,
|
||||||
d->relations,
|
d->relations,
|
||||||
d->skip, d->take);
|
d->skip, d->take);
|
||||||
|
|
@ -363,8 +437,6 @@ Q_OUTOFLINE_TEMPLATE QList<F> Query<T>::select(const FieldPhrase<F> f)
|
||||||
ret.append(v.value<F>());
|
ret.append(v.value<F>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_autoDelete)
|
|
||||||
deleteLater();
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -383,13 +455,13 @@ Q_OUTOFLINE_TEMPLATE Row<T> Query<T>::first()
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE int Query<T>::count()
|
Q_OUTOFLINE_TEMPLATE int Query<T>::count()
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->select = "COUNT(*)";
|
d->select = QStringLiteral("COUNT(*)");
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
SqlGeneratorBase::Count,
|
AbstractSqlGenerator::Count,
|
||||||
QStringLiteral("*"),
|
QStringLiteral("*"),
|
||||||
d->wherePhrase,
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
|
|
@ -403,12 +475,12 @@ 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 FieldPhrase<int> &f)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
SqlGeneratorBase::Max, f.data->toString(),
|
AbstractSqlGenerator::Max, f.data->toString(),
|
||||||
d->wherePhrase,
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
@ -421,12 +493,12 @@ 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 FieldPhrase<int> &f)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
SqlGeneratorBase::Min, f.data->toString(),
|
AbstractSqlGenerator::Min, f.data->toString(),
|
||||||
d->wherePhrase,
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
@ -439,12 +511,12 @@ 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 FieldPhrase<int> &f)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
SqlGeneratorBase::Sum, f.data->toString(),
|
AbstractSqlGenerator::Sum, f.data->toString(),
|
||||||
d->wherePhrase,
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
@ -457,12 +529,12 @@ 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 FieldPhrase<int> &f)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
d->joins.prepend(d->tableName);
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
SqlGeneratorBase::Average, f.data->toString(),
|
AbstractSqlGenerator::Average, f.data->toString(),
|
||||||
d->wherePhrase,
|
d->wherePhrase,
|
||||||
d->relations);
|
d->relations);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
@ -475,7 +547,7 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::average(const FieldPhrase<int> &f)
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::insert(const AssignmentPhraseList &p)
|
Q_OUTOFLINE_TEMPLATE QVariant Query<T>::insert(const AssignmentPhraseList &p)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
d->sql = d->database->sqlGenerator()
|
d->sql = d->database->sqlGenerator()
|
||||||
->insertCommand(d->tableName, p);
|
->insertCommand(d->tableName, p);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
@ -484,9 +556,9 @@ Q_OUTOFLINE_TEMPLATE QVariant Query<T>::insert(const AssignmentPhraseList &p)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(const QString &className)
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::join(const QString &className)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
RelationModel *rel = d->database->model()
|
RelationModel *rel = d->database->model()
|
||||||
.relationByClassNames(d->className, className);
|
.relationByClassNames(d->className, className);
|
||||||
|
|
@ -497,85 +569,85 @@ Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(const QString &className)
|
||||||
if (!rel) {
|
if (!rel) {
|
||||||
qDebug() << "No relation between" << d->className
|
qDebug() << "No relation between" << d->className
|
||||||
<< "and" << className;
|
<< "and" << className;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->relations.append(rel);
|
d->relations.append(rel);
|
||||||
d->joins.append(className);
|
d->joins.append(className);
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::join(Table *c)
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::join(Table *c)
|
||||||
{
|
{
|
||||||
join(c->metaObject()->className());
|
join(c->metaObject()->className());
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::where(const ConditionalPhrase &ph)
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::where(const ConditionalPhrase &ph)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
if (d->wherePhrase.data)
|
if (d->wherePhrase.data)
|
||||||
d->wherePhrase = d->wherePhrase && ph;
|
d->wherePhrase = d->wherePhrase && ph;
|
||||||
else
|
else
|
||||||
d->wherePhrase = ph;
|
d->wherePhrase = ph;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::setWhere(const ConditionalPhrase &ph)
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::setWhere(const ConditionalPhrase &ph)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
d->wherePhrase = ph;
|
d->wherePhrase = ph;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::skip(int n)
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::skip(int n)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
d->skip = n;
|
d->skip = n;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::take(int n)
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::take(int n)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
d->take = n;
|
d->take = n;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::fields(const PhraseList &ph)
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::fields(const PhraseList &ph)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
d->fieldPhrase = ph;
|
d->fieldPhrase = ph;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//template <class T>
|
//template <class T>
|
||||||
//Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(QString fieldName,
|
//Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::orderBy(QString fieldName,
|
||||||
// QString type)
|
// QString type)
|
||||||
//{
|
//{
|
||||||
// Q_D(Query);
|
// //Q_D(AbstractQuery);
|
||||||
// d->orderPhrases.append(fieldName, type);
|
// d->orderPhrases.append(fieldName, type);
|
||||||
// return this;
|
// return *this;
|
||||||
//}
|
//}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *Query<T>::orderBy(const PhraseList &ph)
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::orderBy(const PhraseList &ph)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
d->orderPhrase = ph;
|
d->orderPhrase = ph;
|
||||||
return this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
|
Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->sql = d->database->sqlGenerator()->updateCommand(
|
d->sql = d->database->sqlGenerator()->updateCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
|
|
@ -584,22 +656,18 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
|
||||||
|
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (m_autoDelete)
|
|
||||||
deleteLater();
|
|
||||||
return q.numRowsAffected();
|
return q.numRowsAffected();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
|
Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->sql = d->database->sqlGenerator()->deleteCommand(
|
d->sql = d->database->sqlGenerator()->deleteCommand(
|
||||||
d->tableName, d->wherePhrase);
|
d->tableName, d->wherePhrase);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (m_autoDelete)
|
|
||||||
deleteLater();
|
|
||||||
return q.numRowsAffected();
|
return q.numRowsAffected();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -614,7 +682,7 @@ Q_OUTOFLINE_TEMPLATE QSqlQueryModel *Query<T>::toModel()
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model)
|
Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
|
|
@ -628,9 +696,11 @@ 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()) {
|
||||||
foreach (const PhraseData *pd, d->fieldPhrase.data) {
|
Q_FOREACH (const PhraseData *pd, d->fieldPhrase.data) {
|
||||||
QString displayName = dbModel.tableByClassName(pd->className)
|
QString displayName = dbModel
|
||||||
->field(pd->fieldName)->displayName;
|
.tableByClassName(QString::fromUtf8(pd->className))
|
||||||
|
->field(QString::fromUtf8(pd->fieldName))
|
||||||
|
->displayName;
|
||||||
|
|
||||||
model->setHeaderData(fieldIndex++,
|
model->setHeaderData(fieldIndex++,
|
||||||
Qt::Horizontal,
|
Qt::Horizontal,
|
||||||
|
|
@ -638,7 +708,7 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TableModel *tbl = d->database->model().tableByName(d->tableName);
|
TableModel *tbl = d->database->model().tableByName(d->tableName);
|
||||||
foreach (FieldModel *f, tbl->fields()) {
|
Q_FOREACH (FieldModel *f, tbl->fields()) {
|
||||||
model->setHeaderData(fieldIndex++,
|
model->setHeaderData(fieldIndex++,
|
||||||
Qt::Horizontal,
|
Qt::Horizontal,
|
||||||
f->displayName);
|
f->displayName);
|
||||||
|
|
@ -649,7 +719,7 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(QSqlQueryModel *model)
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(SqlModel *model)
|
Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(SqlModel *model)
|
||||||
{
|
{
|
||||||
Q_D(Query);
|
//Q_D(AbstractQuery);
|
||||||
|
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
|
|
@ -665,7 +735,7 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(SqlModel *model)
|
||||||
int fieldIndex = 0;
|
int fieldIndex = 0;
|
||||||
|
|
||||||
if (d->fieldPhrase.data.count()) {
|
if (d->fieldPhrase.data.count()) {
|
||||||
foreach (const PhraseData *pd, d->fieldPhrase.data) {
|
Q_FOREACH (const PhraseData *pd, d->fieldPhrase.data) {
|
||||||
QString displayName = dbModel.tableByClassName(pd->className)
|
QString displayName = dbModel.tableByClassName(pd->className)
|
||||||
->field(pd->fieldName)->displayName;
|
->field(pd->fieldName)->displayName;
|
||||||
|
|
||||||
|
|
@ -675,7 +745,7 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(SqlModel *model)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TableModel *tbl = d->database->model().tableByName(d->tableName);
|
TableModel *tbl = d->database->model().tableByName(d->tableName);
|
||||||
foreach (FieldModel *f, tbl->fields()) {
|
Q_FOREACH (FieldModel *f, tbl->fields()) {
|
||||||
model->setHeaderData(fieldIndex++,
|
model->setHeaderData(fieldIndex++,
|
||||||
Qt::Horizontal,
|
Qt::Horizontal,
|
||||||
f->displayName);
|
f->displayName);
|
||||||
|
|
@ -686,7 +756,7 @@ Q_OUTOFLINE_TEMPLATE void Query<T>::toModel(SqlModel *model)
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
|
Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
|
||||||
{
|
{
|
||||||
Q_D(const Query);
|
//Q_D(const AbstractQuery);
|
||||||
return d->sql;
|
return d->sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -701,4 +771,4 @@ Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QUERY_H
|
#endif // NUT_QUERY_H
|
||||||
|
|
@ -18,16 +18,17 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include <QMetaMethod>
|
#include <QtCore/QMetaMethod>
|
||||||
#include <QVariant>
|
#include <QtCore/QVariant>
|
||||||
#include <QSqlQuery>
|
#include <QtSql/QSqlQuery>
|
||||||
|
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "table_p.h"
|
#include "table_p.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "databasemodel.h"
|
#include "databasemodel.h"
|
||||||
#include "generators/sqlgeneratorbase_p.h"
|
#include "abstractsqlgenerator.h"
|
||||||
#include "tablesetbase_p.h"
|
#include "abstracttableset.h"
|
||||||
|
#include "propertysignalmapper.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -43,6 +44,10 @@ NUT_BEGIN_NAMESPACE
|
||||||
* This should be fixed to v1.2
|
* This should be fixed to v1.2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \class Table
|
||||||
|
* \brief Base class for all tables
|
||||||
|
*/
|
||||||
Table::Table(QObject *parent) : QObject(parent),
|
Table::Table(QObject *parent) : QObject(parent),
|
||||||
d(new TablePrivate)
|
d(new TablePrivate)
|
||||||
{ }
|
{ }
|
||||||
|
|
@ -55,7 +60,7 @@ Table::~Table()
|
||||||
// d->parentTableSet->remove(this);
|
// d->parentTableSet->remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::add(TableSetBase *t)
|
void Table::add(AbstractTableSet *t)
|
||||||
{
|
{
|
||||||
//Q_D(Table);
|
//Q_D(Table);
|
||||||
d->childTableSets.insert(t);
|
d->childTableSets.insert(t);
|
||||||
|
|
@ -91,7 +96,7 @@ void Table::propertyChanged(const QString &propName)
|
||||||
// if (!d->model)
|
// if (!d->model)
|
||||||
// qFatal ("model for class '%s' not found", qPrintable(metaObject()->className()));
|
// qFatal ("model for class '%s' not found", qPrintable(metaObject()->className()));
|
||||||
|
|
||||||
// foreach (FieldModel *f, d->model->fields())
|
// Q_FOREACH (FieldModel *f, d->model->fields())
|
||||||
// if(f->isPrimaryKey && propName == f->name && f->isAutoIncrement)
|
// if(f->isPrimaryKey && propName == f->name && f->isAutoIncrement)
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
|
|
@ -127,13 +132,13 @@ bool Table::setParentTable(Table *master, TableModel *masterModel, TableModel *m
|
||||||
//Q_D(Table);
|
//Q_D(Table);
|
||||||
d.detach();
|
d.detach();
|
||||||
|
|
||||||
QString masterClassName = master->metaObject()->className();
|
QString masterClassName = QString::fromUtf8(master->metaObject()->className());
|
||||||
d->refreshModel();
|
d->refreshModel();
|
||||||
|
|
||||||
// if (!d->model)
|
// if (!d->model)
|
||||||
// d->model = TableModel::findByClassName(metaObject()->className());
|
// d->model = TableModel::findByClassName(metaObject()->className());
|
||||||
|
|
||||||
foreach (RelationModel *r, model->foreignKeys())
|
Q_FOREACH (RelationModel *r, model->foreignKeys())
|
||||||
if(r->masterClassName == masterClassName)
|
if(r->masterClassName == masterClassName)
|
||||||
{
|
{
|
||||||
setProperty(QString(r->localColumn).toLatin1().data(),
|
setProperty(QString(r->localColumn).toLatin1().data(),
|
||||||
|
|
@ -145,13 +150,24 @@ bool Table::setParentTable(Table *master, TableModel *masterModel, TableModel *m
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
TableSetBase *Table::parentTableSet() const
|
void Table::propertyChanged()
|
||||||
|
{
|
||||||
|
auto pname = PropertySignalMapper::changedProperty(this, senderSignalIndex());
|
||||||
|
propertyChanged(pname);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Table::init()
|
||||||
|
{
|
||||||
|
PropertySignalMapper::map(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractTableSet *Table::parentTableSet() const
|
||||||
{
|
{
|
||||||
//Q_D(const Table);
|
//Q_D(const Table);
|
||||||
return d->parentTableSet;
|
return d->parentTableSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Table::setParentTableSet(TableSetBase *parent)
|
void Table::setParentTableSet(AbstractTableSet *parent)
|
||||||
{
|
{
|
||||||
//Q_D(Table);
|
//Q_D(Table);
|
||||||
d->parentTableSet = parent;
|
d->parentTableSet = parent;
|
||||||
|
|
@ -160,10 +176,10 @@ void Table::setParentTableSet(TableSetBase *parent)
|
||||||
// d->parentTableSet->add(this);
|
// d->parentTableSet->add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TableSetBase *Table::childTableSet(const QString &name) const
|
AbstractTableSet *Table::childTableSet(const QString &name) const
|
||||||
{
|
{
|
||||||
//Q_D(const Table);
|
//Q_D(const Table);
|
||||||
foreach (TableSetBase *t, d->childTableSets)
|
Q_FOREACH (AbstractTableSet *t, d->childTableSets)
|
||||||
if (t->childClassName() == name)
|
if (t->childClassName() == name)
|
||||||
return t;
|
return t;
|
||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
|
|
@ -173,13 +189,13 @@ int Table::save(Database *db)
|
||||||
{
|
{
|
||||||
//Q_D(Table);
|
//Q_D(Table);
|
||||||
|
|
||||||
QSqlQuery q = db->exec(db->sqlGenerator()->saveRecord(this, db->tableName(metaObject()->className())));
|
QSqlQuery q = db->exec(db->sqlGenerator()->saveRecord(this, db->tableName(QString::fromUtf8(metaObject()->className()))));
|
||||||
|
|
||||||
auto model = db->model().tableByClassName(metaObject()->className());
|
auto model = db->model().tableByClassName(QString::fromUtf8(metaObject()->className()));
|
||||||
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(TableSetBase *ts, d->childTableSets)
|
foreach(AbstractTableSet *ts, d->childTableSets)
|
||||||
ts->save(db);
|
ts->save(db);
|
||||||
setStatus(FetchedFromDB);
|
setStatus(FetchedFromDB);
|
||||||
|
|
||||||
|
|
@ -25,14 +25,14 @@
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtCore/QSet>
|
#include <QtCore/QSet>
|
||||||
|
|
||||||
#include "tablemodel.h"
|
#include <QtNut/nut_global.h>
|
||||||
#include "defines.h"
|
#include <QtNut/tablemodel.h>
|
||||||
#include "phrase.h"
|
#include <QtNut/phrase.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
class TableSetBase;
|
class AbstractTableSet;
|
||||||
class TableModel;
|
class TableModel;
|
||||||
class TablePrivate;
|
class TablePrivate;
|
||||||
class NUT_EXPORT Table : public QObject
|
class NUT_EXPORT Table : public QObject
|
||||||
|
|
@ -61,39 +61,44 @@ public:
|
||||||
Status status() const;
|
Status status() const;
|
||||||
void setStatus(const Status &status);
|
void setStatus(const Status &status);
|
||||||
|
|
||||||
TableSetBase *parentTableSet() const;
|
AbstractTableSet *parentTableSet() const;
|
||||||
void setParentTableSet(TableSetBase *parentTableSet);
|
void setParentTableSet(AbstractTableSet *parentTableSet);
|
||||||
|
|
||||||
TableSetBase *childTableSet(const QString &name) const;
|
AbstractTableSet *childTableSet(const QString &name) const;
|
||||||
|
|
||||||
QSet<QString> changedProperties() const;
|
QSet<QString> changedProperties() const;
|
||||||
|
|
||||||
bool setParentTable(Table *master, TableModel *masterModel, TableModel *model);
|
bool setParentTable(Table *master, TableModel *masterModel, TableModel *model);
|
||||||
signals:
|
Q_SIGNALS:
|
||||||
|
|
||||||
public slots:
|
public Q_SLOTS:
|
||||||
|
void propertyChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
void init();
|
||||||
void propertyChanged(const QString &propName);
|
void propertyChanged(const QString &propName);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool _is_signals_mapped{false};
|
||||||
|
|
||||||
void setModel(TableModel *model);
|
void setModel(TableModel *model);
|
||||||
// TableModel *myModel;
|
// TableModel *myModel;
|
||||||
// Status _status;
|
// Status _status;
|
||||||
// QSet<QString> _changedProperties;
|
// QSet<QString> _changedProperties;
|
||||||
//TODO: is this removable?
|
//TODO: is this removable?
|
||||||
// TableSetBase *_parentTableSet;
|
// AbstractTableSet *_parentTableSet;
|
||||||
|
|
||||||
// QSet<TableSetBase*> childTableSets;
|
// QSet<AbstractTableSet*> childTableSets;
|
||||||
void clear();
|
void clear();
|
||||||
void add(TableSetBase *);
|
void add(AbstractTableSet *);
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
friend class Query;
|
friend class Query;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
friend class TableSet;
|
friend class TableSet;
|
||||||
friend class TableSetBase;
|
friend class AbstractTableSet;
|
||||||
|
friend class PropertySignalMapper;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
#ifndef TABLEPRIVATE_H
|
#ifndef TABLEPRIVATE_H
|
||||||
#define TABLEPRIVATE_H
|
#define TABLEPRIVATE_H
|
||||||
|
|
||||||
#include "defines.h"
|
|
||||||
|
|
||||||
#include <QtCore/QSet>
|
#include <QtCore/QSet>
|
||||||
#include <QSharedData>
|
#include <QtCore/QSharedData>
|
||||||
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
#include <QtNut/table.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class TableModel;
|
class TableModel;
|
||||||
class Table;
|
class Table;
|
||||||
class TableSetBase;
|
class AbstractTableSet;
|
||||||
class TablePrivate : public QSharedData {
|
class TablePrivate : public QSharedData {
|
||||||
Table *q_ptr;
|
Table *q_ptr;
|
||||||
Q_DECLARE_PUBLIC(Table)
|
Q_DECLARE_PUBLIC(Table)
|
||||||
|
|
@ -22,8 +23,8 @@ public:
|
||||||
TableModel *model;
|
TableModel *model;
|
||||||
Table::Status status;
|
Table::Status status;
|
||||||
QSet<QString> changedProperties;
|
QSet<QString> changedProperties;
|
||||||
TableSetBase *parentTableSet;
|
AbstractTableSet *parentTableSet;
|
||||||
QSet<TableSetBase*> childTableSets;
|
QSet<AbstractTableSet*> childTableSets;
|
||||||
|
|
||||||
void refreshModel();
|
void refreshModel();
|
||||||
};
|
};
|
||||||
|
|
@ -25,14 +25,15 @@
|
||||||
#include <QtCore/QMetaMethod>
|
#include <QtCore/QMetaMethod>
|
||||||
#include <QtCore/QMetaType>
|
#include <QtCore/QMetaType>
|
||||||
#include <QtCore/QVariant>
|
#include <QtCore/QVariant>
|
||||||
#include <QtSql/QSqlQuery>
|
#include <QtCore/QSharedPointer>
|
||||||
#include <QSharedPointer>
|
|
||||||
|
|
||||||
#include "tablesetbase_p.h"
|
#include <QtSql/QSqlQuery>
|
||||||
#include "table.h"
|
|
||||||
#include "bulkinserter.h"
|
#include <QtNut/abstracttableset.h>
|
||||||
#include "databasemodel.h"
|
#include <QtNut/table.h>
|
||||||
#include "tablesetbasedata.h"
|
#include <QtNut/bulkinserter.h>
|
||||||
|
#include <QtNut/databasemodel.h>
|
||||||
|
#include <QtNut/abstracttablesetdata.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -43,7 +44,7 @@ class BulkInserter;
|
||||||
class Database;
|
class Database;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
class TableSet : public TableSetBase
|
class TableSet : public AbstractTableSet
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef T value_type;
|
typedef T value_type;
|
||||||
|
|
@ -53,6 +54,10 @@ public:
|
||||||
explicit TableSet(Database *parent);
|
explicit TableSet(Database *parent);
|
||||||
explicit TableSet(Table *parent);
|
explicit TableSet(Table *parent);
|
||||||
|
|
||||||
|
#ifndef NUT_RAW_POINTER
|
||||||
|
void append(T *t);
|
||||||
|
void append(QList<T*> t);
|
||||||
|
#endif
|
||||||
void append(Row<T> t);
|
void append(Row<T> t);
|
||||||
void append(RowList<T> t);
|
void append(RowList<T> t);
|
||||||
void remove(Row<T> t);
|
void remove(Row<T> t);
|
||||||
|
|
@ -62,35 +67,32 @@ public:
|
||||||
Row<T> at(int i) const;
|
Row<T> at(int i) const;
|
||||||
Row<T> operator[](int i) const;
|
Row<T> operator[](int i) const;
|
||||||
|
|
||||||
Query<T> *query(bool autoDelete = true);
|
Query<T> query();
|
||||||
BulkInserter *bulkInserter();
|
BulkInserter bulkInserter();
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE TableSet<T>::TableSet(Database *parent) : TableSetBase(parent)
|
Q_OUTOFLINE_TEMPLATE TableSet<T>::TableSet(Database *parent) : AbstractTableSet(parent)
|
||||||
{
|
{
|
||||||
data->childClassName = T::staticMetaObject.className();
|
data->childClassName = QString::fromUtf8(T::staticMetaObject.className());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE TableSet<T>::TableSet(Table *parent) : TableSetBase(parent)
|
Q_OUTOFLINE_TEMPLATE TableSet<T>::TableSet(Table *parent) : AbstractTableSet(parent)
|
||||||
{
|
{
|
||||||
data->childClassName = T::staticMetaObject.className();
|
data->childClassName = QString::fromUtf8(T::staticMetaObject.className());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T> *TableSet<T>::query(bool autoDelete)
|
Q_OUTOFLINE_TEMPLATE Query<T> TableSet<T>::query()
|
||||||
{
|
{
|
||||||
Query<T> *q = new Query<T>(data->database, this, autoDelete);
|
return Query<T>(data->database, this);
|
||||||
|
|
||||||
return q;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE BulkInserter *TableSet<T>::bulkInserter()
|
Q_OUTOFLINE_TEMPLATE BulkInserter TableSet<T>::bulkInserter()
|
||||||
{
|
{
|
||||||
BulkInserter *bi = new BulkInserter(data->database, data->childClassName);
|
return BulkInserter(data->database, data->childClassName);
|
||||||
return bi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
@ -102,10 +104,10 @@ Q_OUTOFLINE_TEMPLATE int TableSet<T>::length() const
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Row<T> TableSet<T>::at(int i) const
|
Q_OUTOFLINE_TEMPLATE Row<T> TableSet<T>::at(int i) const
|
||||||
{
|
{
|
||||||
#ifdef NUT_SHARED_POINTER
|
#ifdef NUT_RAW_POINTER
|
||||||
return data->childs.at(i).template objectCast<T>();
|
|
||||||
#else
|
|
||||||
return reinterpret_cast<T*>(data->childs.at(i));
|
return reinterpret_cast<T*>(data->childs.at(i));
|
||||||
|
#else
|
||||||
|
return data->childs.at(i).template objectCast<T>();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,6 +117,21 @@ Q_OUTOFLINE_TEMPLATE Row<T> TableSet<T>::operator[](int i) const
|
||||||
return at(i);
|
return at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NUT_RAW_POINTER
|
||||||
|
template<class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(T *t)
|
||||||
|
{
|
||||||
|
append(QSharedPointer<T>(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(QList<T*> t)
|
||||||
|
{
|
||||||
|
for (auto &table: t)
|
||||||
|
append(table);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
||||||
{
|
{
|
||||||
|
|
@ -134,7 +151,7 @@ Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(RowList<T> t)
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(RowList<T> t)
|
||||||
{
|
{
|
||||||
foreach (Row<T> i, t)
|
Q_FOREACH (Row<T> i, t)
|
||||||
append(i);
|
append(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +168,7 @@ Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(Row<T> t)
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(RowList<T> t)
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(RowList<T> t)
|
||||||
{
|
{
|
||||||
foreach (Row<T> i, t)
|
Q_FOREACH (Row<T> i, t)
|
||||||
remove(i);
|
remove(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -18,14 +18,14 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef SQLGENERATORBASE_H
|
#ifndef NUT_ABSTRACTSQLGENERATOR_H
|
||||||
#define SQLGENERATORBASE_H
|
#define NUT_ABSTRACTSQLGENERATOR_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtCore/QStringList>
|
#include <QtCore/QStringList>
|
||||||
#include "../phrase.h"
|
|
||||||
//#include "../wherephrase.h"
|
#include <QtNut/phrase.h>
|
||||||
|
|
||||||
class SqlSerializer;
|
class SqlSerializer;
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ class DatabaseModel;
|
||||||
class TableModel;
|
class TableModel;
|
||||||
class Database;
|
class Database;
|
||||||
struct RelationModel;
|
struct RelationModel;
|
||||||
class NUT_EXPORT SqlGeneratorBase : public QObject
|
class NUT_EXPORT AbstractSqlGenerator : public QObject
|
||||||
{
|
{
|
||||||
// Q_OBJECT
|
// Q_OBJECT
|
||||||
|
|
||||||
|
|
@ -65,8 +65,8 @@ public:
|
||||||
Sum
|
Sum
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit SqlGeneratorBase(Database *parent);
|
explicit AbstractSqlGenerator(Database *parent);
|
||||||
virtual ~SqlGeneratorBase() = default;
|
virtual ~AbstractSqlGenerator() = default;
|
||||||
|
|
||||||
virtual bool supportPrimaryKey(const QMetaType::Type &type) {
|
virtual bool supportPrimaryKey(const QMetaType::Type &type) {
|
||||||
Q_UNUSED(type)
|
Q_UNUSED(type)
|
||||||
|
|
@ -168,4 +168,4 @@ protected:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // SQLGENERATORBASE_H
|
#endif // NUT_ABSTRACTSQLGENERATOR_H
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/abstractsqlgenerator.h \
|
||||||
|
$$PWD/postgresqlgenerator.h \
|
||||||
|
$$PWD/mysqlgenerator.h \
|
||||||
|
$$PWD/sqlitegenerator.h \
|
||||||
|
$$PWD/sqlservergenerator.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/abstractsqlgenerator.cpp \
|
||||||
|
$$PWD/postgresqlgenerator.cpp \
|
||||||
|
$$PWD/mysqlgenerator.cpp \
|
||||||
|
$$PWD/sqlitegenerator.cpp \
|
||||||
|
$$PWD/sqlservergenerator.cpp
|
||||||
|
|
@ -19,23 +19,23 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "mysqlgenerator.h"
|
#include "mysqlgenerator.h"
|
||||||
#include "../tablemodel.h"
|
#include "tablemodel.h"
|
||||||
|
|
||||||
#include <QPoint>
|
#include <QtCore/QPoint>
|
||||||
#include <QPointF>
|
#include <QtCore/QPointF>
|
||||||
#include <QTime>
|
#include <QtCore/QTime>
|
||||||
#include <QDate>
|
#include <QtCore/QDate>
|
||||||
#include <QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
#include <QPolygon>
|
# include <QtGui/QPolygon>
|
||||||
#include <QPolygonF>
|
# include <QtGui/QPolygonF>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sqlserializer.h"
|
#include "sqlserializer.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
MySqlGenerator::MySqlGenerator(Database *parent) : SqlGeneratorBase(parent)
|
MySqlGenerator::MySqlGenerator(Database *parent) : AbstractSqlGenerator(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -45,42 +45,42 @@ QString MySqlGenerator::fieldType(FieldModel *field)
|
||||||
QString dbType;
|
QString dbType;
|
||||||
|
|
||||||
switch (field->type) {
|
switch (field->type) {
|
||||||
case QMetaType::Bool: return "BOOLEAN";
|
case QMetaType::Bool: return QStringLiteral("BOOLEAN");
|
||||||
case QMetaType::Char:
|
case QMetaType::Char:
|
||||||
case QMetaType::QChar: return "CHAR(1)";
|
case QMetaType::QChar: return QStringLiteral("CHAR(1)");
|
||||||
case QMetaType::SChar:
|
case QMetaType::SChar:
|
||||||
case QMetaType::UChar: return "TINYINT";
|
case QMetaType::UChar: return QStringLiteral("TINYINT");
|
||||||
case QMetaType::Short:
|
case QMetaType::Short:
|
||||||
case QMetaType::UShort: return "SMALLINT";
|
case QMetaType::UShort: return QStringLiteral("SMALLINT");
|
||||||
case QMetaType::UInt:
|
case QMetaType::UInt:
|
||||||
case QMetaType::Int:
|
case QMetaType::Int:
|
||||||
dbType = "INT";
|
dbType = QStringLiteral("INT");
|
||||||
if(field->isAutoIncrement)
|
if(field->isAutoIncrement)
|
||||||
dbType += " AUTO_INCREMENT";
|
dbType += QStringLiteral(" AUTO_INCREMENT");
|
||||||
break;
|
break;
|
||||||
case QMetaType::Long:
|
case QMetaType::Long:
|
||||||
case QMetaType::ULong:
|
case QMetaType::ULong:
|
||||||
case QMetaType::LongLong:
|
case QMetaType::LongLong:
|
||||||
case QMetaType::ULongLong:
|
case QMetaType::ULongLong:
|
||||||
return "BIGINT";
|
return QStringLiteral("BIGINT");
|
||||||
|
|
||||||
case QMetaType::Float:
|
case QMetaType::Float:
|
||||||
return "FLOAT";
|
return QStringLiteral("FLOAT");
|
||||||
|
|
||||||
case QMetaType::Double:
|
case QMetaType::Double:
|
||||||
return "REAL";
|
return QStringLiteral("REAL");
|
||||||
|
|
||||||
case QMetaType::QBitArray: return "VARBINARY";
|
case QMetaType::QBitArray: return QStringLiteral("VARBINARY");
|
||||||
case QMetaType::QByteArray: return "BLOB";
|
case QMetaType::QByteArray: return QStringLiteral("BLOB");
|
||||||
case QMetaType::QDate: return "DATE";
|
case QMetaType::QDate: return QStringLiteral("DATE");
|
||||||
case QMetaType::QTime: return "TIME";
|
case QMetaType::QTime: return QStringLiteral("TIME");
|
||||||
case QMetaType::QDateTime: return "DATETIME";
|
case QMetaType::QDateTime: return QStringLiteral("DATETIME");
|
||||||
|
|
||||||
case QMetaType::QString:
|
case QMetaType::QString:
|
||||||
if(field->length)
|
if(field->length)
|
||||||
dbType = QString("VARCHAR(%1)").arg(field->length);
|
dbType = QStringLiteral("VARCHAR(%1)").arg(field->length);
|
||||||
else
|
else
|
||||||
dbType = "TEXT";
|
dbType = QStringLiteral("TEXT");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ QString MySqlGenerator::fieldType(FieldModel *field)
|
||||||
case QMetaType::QJsonValue:
|
case QMetaType::QJsonValue:
|
||||||
case QMetaType::QJsonObject:
|
case QMetaType::QJsonObject:
|
||||||
case QMetaType::QJsonDocument:
|
case QMetaType::QJsonDocument:
|
||||||
case QMetaType::QStringList: return "TEXT";
|
case QMetaType::QStringList: return QStringLiteral("TEXT");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
qWarning("Type %s::%s(%d) is not supported",
|
qWarning("Type %s::%s(%d) is not supported",
|
||||||
|
|
@ -128,16 +128,16 @@ QString MySqlGenerator::fieldType(FieldModel *field)
|
||||||
QString MySqlGenerator::escapeValue(const QVariant &v) const
|
QString MySqlGenerator::escapeValue(const QVariant &v) const
|
||||||
{
|
{
|
||||||
if (v.type() == QVariant::Bool)
|
if (v.type() == QVariant::Bool)
|
||||||
return v.toBool() ? "1" : "0";
|
return v.toBool() ? QStringLiteral("1") : QStringLiteral("0");
|
||||||
|
|
||||||
if (v.type() == QVariant::Time)
|
if (v.type() == QVariant::Time)
|
||||||
return "'" + v.toTime().toString("HH:mm:ss") + "'";
|
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::Date)
|
if (v.type() == QVariant::Date)
|
||||||
return "'" + v.toDate().toString("yyyy-MM-dd") + "'";
|
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::DateTime)
|
if (v.type() == QVariant::DateTime)
|
||||||
return "'" + v.toDateTime().toString("yyyy-MM-dd HH:mm:ss") + "'";
|
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
||||||
|
|
||||||
//#ifdef QT_GUI_LIB
|
//#ifdef QT_GUI_LIB
|
||||||
// if (v.type() == QVariant::Polygon) {
|
// if (v.type() == QVariant::Polygon) {
|
||||||
|
|
@ -178,7 +178,7 @@ QString MySqlGenerator::escapeValue(const QVariant &v) const
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// default:
|
// default:
|
||||||
return SqlGeneratorBase::escapeValue(v);
|
return AbstractSqlGenerator::escapeValue(v);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -194,7 +194,7 @@ QVariant MySqlGenerator::unescapeValue(const QMetaType::Type &type, const QVaria
|
||||||
// if (!readInsideParentese(ref, p))
|
// if (!readInsideParentese(ref, p))
|
||||||
// return pol;
|
// return pol;
|
||||||
// QStringList parts = p.split(",");
|
// QStringList parts = p.split(",");
|
||||||
// foreach (QString v, parts) {
|
// Q_FOREACH (QString v, parts) {
|
||||||
// QList<int> l = _serializer->toListInt(p.trimmed(), " ");
|
// QList<int> l = _serializer->toListInt(p.trimmed(), " ");
|
||||||
// if (l.count() != 2)
|
// if (l.count() != 2)
|
||||||
// return QPolygon();
|
// return QPolygon();
|
||||||
|
|
@ -210,7 +210,7 @@ QVariant MySqlGenerator::unescapeValue(const QMetaType::Type &type, const QVaria
|
||||||
// return pol;
|
// return pol;
|
||||||
|
|
||||||
// QStringList parts = p.split(",");
|
// QStringList parts = p.split(",");
|
||||||
// foreach (QString v, parts) {
|
// Q_FOREACH (QString v, parts) {
|
||||||
// QList<qreal> l = _serializer->toListReal(p.trimmed(), " ");
|
// QList<qreal> l = _serializer->toListReal(p.trimmed(), " ");
|
||||||
// if (l.count() != 2)
|
// if (l.count() != 2)
|
||||||
// return QPolygonF();
|
// return QPolygonF();
|
||||||
|
|
@ -229,7 +229,7 @@ QVariant MySqlGenerator::unescapeValue(const QMetaType::Type &type, const QVaria
|
||||||
if (type == QMetaType::QDate)
|
if (type == QMetaType::QDate)
|
||||||
return dbValue.toDate();
|
return dbValue.toDate();
|
||||||
|
|
||||||
return SqlGeneratorBase::unescapeValue(type, dbValue);
|
return AbstractSqlGenerator::unescapeValue(type, dbValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MySqlGenerator::readInsideParentese(QString &text, QString &out)
|
bool MySqlGenerator::readInsideParentese(QString &text, QString &out)
|
||||||
|
|
@ -316,10 +316,10 @@ QString MySqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::AddMinutesDateTime:
|
case PhraseData::AddMinutesDateTime:
|
||||||
case PhraseData::AddSeconds:
|
case PhraseData::AddSeconds:
|
||||||
case PhraseData::AddSecondsDateTime:
|
case PhraseData::AddSecondsDateTime:
|
||||||
return QString("DATE_ADD(%1, INTERVAL %2 %3)")
|
return QStringLiteral("DATE_ADD(%1, INTERVAL %2 %3)")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
d->operand.toString(),
|
d->operand.toString(),
|
||||||
SqlGeneratorBase::dateTimePartName(op));
|
AbstractSqlGenerator::dateTimePartName(op));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -333,26 +333,26 @@ QString MySqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::DatePartHour:
|
case PhraseData::DatePartHour:
|
||||||
case PhraseData::DatePartMinute:
|
case PhraseData::DatePartMinute:
|
||||||
case PhraseData::DatePartSecond:
|
case PhraseData::DatePartSecond:
|
||||||
return QString("%2(%1)")
|
return QStringLiteral("%2(%1)")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
SqlGeneratorBase::dateTimePartName(op));
|
AbstractSqlGenerator::dateTimePartName(op));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SqlGeneratorBase::createConditionalPhrase(d);
|
return AbstractSqlGenerator::createConditionalPhrase(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MySqlGenerator::appendSkipTake(QString &sql, int skip, int take)
|
void MySqlGenerator::appendSkipTake(QString &sql, int skip, int take)
|
||||||
{
|
{
|
||||||
if (take > 0 && skip > 0) {
|
if (take > 0 && skip > 0) {
|
||||||
sql.append(QString(" LIMIT %1 OFFSET %2")
|
sql.append(QStringLiteral(" LIMIT %1 OFFSET %2")
|
||||||
.arg(take)
|
.arg(take)
|
||||||
.arg(skip));
|
.arg(skip));
|
||||||
} else if (take > 0) {
|
} else if (take > 0) {
|
||||||
sql.append(QString(" LIMIT %1").arg(take));
|
sql.append(QStringLiteral(" LIMIT %1").arg(take));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -22,11 +22,12 @@
|
||||||
#define MYSQLGENERATOR_H
|
#define MYSQLGENERATOR_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include "sqlgeneratorbase_p.h"
|
|
||||||
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT MySqlGenerator : public SqlGeneratorBase
|
class NUT_EXPORT MySqlGenerator : public AbstractSqlGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit MySqlGenerator(Database *parent = nullptr);
|
explicit MySqlGenerator(Database *parent = nullptr);
|
||||||
|
|
@ -18,18 +18,19 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include <QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
#include <QPoint>
|
#include <QtCore/QPoint>
|
||||||
|
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
#include <QPolygon>
|
# include <QtGui/QPolygon>
|
||||||
#include <QPolygonF>
|
# include <QtGui/QPolygonF>
|
||||||
#endif
|
#endif
|
||||||
#include <QVariant>
|
#include <QtCore/QVariant>
|
||||||
#include <QJsonDocument>
|
#include <QtCore/QJsonDocument>
|
||||||
|
|
||||||
#include "postgresqlgenerator.h"
|
#include "postgresqlgenerator.h"
|
||||||
#include "../table.h"
|
#include "table.h"
|
||||||
#include "../tablemodel.h"
|
#include "tablemodel.h"
|
||||||
#include "sqlserializer.h"
|
#include "sqlserializer.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
@ -72,7 +73,7 @@ bool PostgreSqlGenerator::isPostGisType(const QVariant::Type &t) const
|
||||||
|| t == QVariant::PolygonF;
|
|| t == QVariant::PolygonF;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostgreSqlGenerator::PostgreSqlGenerator(Database *parent) : SqlGeneratorBase (parent)
|
PostgreSqlGenerator::PostgreSqlGenerator(Database *parent) : AbstractSqlGenerator (parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -83,44 +84,44 @@ QString PostgreSqlGenerator::fieldType(FieldModel *field)
|
||||||
|
|
||||||
switch (field->type) {
|
switch (field->type) {
|
||||||
case QMetaType::Bool:
|
case QMetaType::Bool:
|
||||||
dbType = "BOOLEAN";
|
dbType = QStringLiteral("BOOLEAN");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::QBitArray:
|
case QMetaType::QBitArray:
|
||||||
case QMetaType::QByteArray:
|
case QMetaType::QByteArray:
|
||||||
dbType = "BYTEA";
|
dbType = QStringLiteral("BYTEA");
|
||||||
break;
|
break;
|
||||||
case QMetaType::QDate:
|
case QMetaType::QDate:
|
||||||
dbType = "DATE";
|
dbType = QStringLiteral("DATE");
|
||||||
break;
|
break;
|
||||||
case QMetaType::QDateTime:
|
case QMetaType::QDateTime:
|
||||||
dbType = "TIMESTAMP";
|
dbType = QStringLiteral("TIMESTAMP");
|
||||||
break;
|
break;
|
||||||
case QMetaType::QTime:
|
case QMetaType::QTime:
|
||||||
dbType = "TIME";
|
dbType = QStringLiteral("TIME");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::SChar:
|
case QMetaType::SChar:
|
||||||
case QMetaType::UChar:
|
case QMetaType::UChar:
|
||||||
case QMetaType::Short:
|
case QMetaType::Short:
|
||||||
case QMetaType::UShort:
|
case QMetaType::UShort:
|
||||||
dbType = "SMALLINT";
|
dbType = QStringLiteral("SMALLINT");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::Float:
|
case QMetaType::Float:
|
||||||
dbType = "FLOAT";
|
dbType = QStringLiteral("FLOAT");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::Double:
|
case QMetaType::Double:
|
||||||
dbType = "REAL";
|
dbType = QStringLiteral("REAL");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::Int:
|
case QMetaType::Int:
|
||||||
case QMetaType::UInt:
|
case QMetaType::UInt:
|
||||||
if(field->isAutoIncrement)
|
if(field->isAutoIncrement)
|
||||||
dbType = "SERIAL";
|
dbType = QStringLiteral("SERIAL");
|
||||||
else
|
else
|
||||||
dbType = "INTEGER";
|
dbType = QStringLiteral("INTEGER");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::Long:
|
case QMetaType::Long:
|
||||||
|
|
@ -128,58 +129,58 @@ QString PostgreSqlGenerator::fieldType(FieldModel *field)
|
||||||
case QMetaType::LongLong:
|
case QMetaType::LongLong:
|
||||||
case QMetaType::ULongLong:
|
case QMetaType::ULongLong:
|
||||||
if(field->isAutoIncrement)
|
if(field->isAutoIncrement)
|
||||||
dbType = "BIGSERIAL";
|
dbType = QStringLiteral("BIGSERIAL");
|
||||||
else
|
else
|
||||||
dbType = "BIGINT";
|
dbType = QStringLiteral("BIGINT");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::Char:
|
case QMetaType::Char:
|
||||||
case QMetaType::QChar:
|
case QMetaType::QChar:
|
||||||
return "CHAR(1)";
|
return QStringLiteral("CHAR(1)");
|
||||||
|
|
||||||
case QMetaType::QString:
|
case QMetaType::QString:
|
||||||
if(field->length)
|
if(field->length)
|
||||||
dbType = QString("VARCHAR(%1)").arg(field->length);
|
dbType = QStringLiteral("VARCHAR(%1)").arg(field->length);
|
||||||
else
|
else
|
||||||
dbType = "TEXT";
|
dbType = QStringLiteral("TEXT");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::QPoint:
|
case QMetaType::QPoint:
|
||||||
case QMetaType::QPointF:
|
case QMetaType::QPointF:
|
||||||
dbType="POINT";
|
dbType = QStringLiteral("POINT");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::QUuid:
|
case QMetaType::QUuid:
|
||||||
dbType = "UUID";
|
dbType = QStringLiteral("UUID");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::QPolygon:
|
case QMetaType::QPolygon:
|
||||||
case QMetaType::QPolygonF:
|
case QMetaType::QPolygonF:
|
||||||
dbType = "POLYGON";
|
dbType = QStringLiteral("POLYGON");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::QLine:
|
case QMetaType::QLine:
|
||||||
case QMetaType::QLineF:
|
case QMetaType::QLineF:
|
||||||
return "LINE";
|
return QStringLiteral("LINE");
|
||||||
|
|
||||||
case QMetaType::QRect:
|
case QMetaType::QRect:
|
||||||
case QMetaType::QRectF:
|
case QMetaType::QRectF:
|
||||||
return "BOX";
|
return QStringLiteral("BOX");
|
||||||
|
|
||||||
case QMetaType::QJsonArray:
|
case QMetaType::QJsonArray:
|
||||||
case QMetaType::QJsonValue:
|
case QMetaType::QJsonValue:
|
||||||
case QMetaType::QJsonObject:
|
case QMetaType::QJsonObject:
|
||||||
case QMetaType::QJsonDocument:
|
case QMetaType::QJsonDocument:
|
||||||
return "JSONB";
|
return QStringLiteral("JSONB");
|
||||||
|
|
||||||
case QMetaType::QStringList:
|
case QMetaType::QStringList:
|
||||||
return "TEXT[]";
|
return QStringLiteral("TEXT[]");
|
||||||
|
|
||||||
case QMetaType::QSize:
|
case QMetaType::QSize:
|
||||||
case QMetaType::QSizeF:
|
case QMetaType::QSizeF:
|
||||||
case QMetaType::QUrl:
|
case QMetaType::QUrl:
|
||||||
case QMetaType::QColor:
|
case QMetaType::QColor:
|
||||||
return "TEXT";
|
return QStringLiteral("TEXT");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dbType = QString();
|
dbType = QString();
|
||||||
|
|
@ -196,13 +197,13 @@ QString PostgreSqlGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
if(!newField){
|
if(!newField){
|
||||||
sql = "DROP COLUMN " + oldField->name;
|
sql = QStringLiteral("DROP COLUMN ") + oldField->name;
|
||||||
}else{
|
}else{
|
||||||
if(oldField){
|
if(oldField){
|
||||||
sql = "ALTER COLUMN ";
|
sql = QStringLiteral("ALTER COLUMN ");
|
||||||
sql.append(newField->name + " TYPE " + fieldType(newField));
|
sql.append(newField->name + QStringLiteral(" TYPE ") + fieldType(newField));
|
||||||
} else {
|
} else {
|
||||||
sql = "ADD COLUMN ";
|
sql = QStringLiteral("ADD COLUMN ");
|
||||||
sql.append(fieldDeclare(newField));
|
sql.append(fieldDeclare(newField));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -212,27 +213,31 @@ QString PostgreSqlGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
||||||
QString PostgreSqlGenerator::escapeValue(const QVariant &v) const
|
QString PostgreSqlGenerator::escapeValue(const QVariant &v) const
|
||||||
{
|
{
|
||||||
if (v.type() == QVariant::Time)
|
if (v.type() == QVariant::Time)
|
||||||
return "'" + v.toTime().toString("HH:mm:ss") + "'";
|
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::Date)
|
if (v.type() == QVariant::Date)
|
||||||
return "'" + v.toDate().toString("yyyy-MM-dd") + "'";
|
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::DateTime)
|
if (v.type() == QVariant::DateTime)
|
||||||
return "'" + v.toDateTime().toString("yyyy-MM-dd HH:mm:ss") + "'";
|
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::StringList)
|
if (v.type() == QVariant::StringList)
|
||||||
return "'{" + v.toStringList().join(",") + "}'";
|
return QStringLiteral("'{")
|
||||||
|
+ v.toStringList().join(QStringLiteral(","))
|
||||||
|
+ QStringLiteral("}'");
|
||||||
|
|
||||||
if (v.type() == QVariant::Point) {
|
if (v.type() == QVariant::Point) {
|
||||||
QPoint pt = v.toPoint();
|
QPoint pt = v.toPoint();
|
||||||
return QString("point(%1, %2)").arg(pt.x()).arg(pt.y());
|
return QStringLiteral("point(%1, %2)").arg(pt.x()).arg(pt.y());
|
||||||
}
|
}
|
||||||
if (v.type() == QVariant::PointF) {
|
if (v.type() == QVariant::PointF) {
|
||||||
QPointF pt = v.toPointF();
|
QPointF pt = v.toPointF();
|
||||||
return QString("point(%1, %2)").arg(pt.x()).arg(pt.y());
|
return QStringLiteral("point(%1, %2)").arg(pt.x()).arg(pt.y());
|
||||||
}
|
}
|
||||||
if (v.userType() == QMetaType::QJsonDocument) {
|
if (v.userType() == QMetaType::QJsonDocument) {
|
||||||
return "'" + QString(v.toJsonDocument().toJson(QJsonDocument::Compact)) + "'";
|
return QStringLiteral("'")
|
||||||
|
+ QString::fromUtf8(v.toJsonDocument().toJson(QJsonDocument::Compact))
|
||||||
|
+ QStringLiteral("'");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
|
|
@ -243,10 +248,11 @@ QString PostgreSqlGenerator::escapeValue(const QVariant &v) const
|
||||||
for (int i = 0; i < pol.size(); ++i) {
|
for (int i = 0; i < pol.size(); ++i) {
|
||||||
pt = pol.at(i);
|
pt = pol.at(i);
|
||||||
if (!ret.isEmpty())
|
if (!ret.isEmpty())
|
||||||
ret.append("),(");
|
ret.append(QStringLiteral("),("));
|
||||||
ret.append(QString::number(pt.x()) + ", " + QString::number(pt.y()));
|
ret.append(QString::number(pt.x())
|
||||||
|
+ QStringLiteral(", ") + QString::number(pt.y()));
|
||||||
}
|
}
|
||||||
return "'((" + ret + "))'";
|
return QStringLiteral("'((") + ret + QStringLiteral("))'");
|
||||||
}
|
}
|
||||||
if (v.type() == QVariant::PolygonF) {
|
if (v.type() == QVariant::PolygonF) {
|
||||||
QString ret;
|
QString ret;
|
||||||
|
|
@ -255,14 +261,15 @@ QString PostgreSqlGenerator::escapeValue(const QVariant &v) const
|
||||||
for (int i = 0; i < pol.size(); ++i) {
|
for (int i = 0; i < pol.size(); ++i) {
|
||||||
pt = pol.at(i);
|
pt = pol.at(i);
|
||||||
if (!ret.isEmpty())
|
if (!ret.isEmpty())
|
||||||
ret.append("),(");
|
ret.append(QStringLiteral("),("));
|
||||||
ret.append(QString::number(pt.x()) + ", " + QString::number(pt.y()));
|
ret.append(QString::number(pt.x())
|
||||||
|
+ QStringLiteral(", ") + QString::number(pt.y()));
|
||||||
}
|
}
|
||||||
return "'((" + ret + "))'";
|
return QStringLiteral("'((") + ret + QStringLiteral("))'");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return SqlGeneratorBase::escapeValue(v);
|
return AbstractSqlGenerator::escapeValue(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant PostgreSqlGenerator::unescapeValue(const QMetaType::Type &type, const QVariant &dbValue)
|
QVariant PostgreSqlGenerator::unescapeValue(const QMetaType::Type &type, const QVariant &dbValue)
|
||||||
|
|
@ -277,14 +284,24 @@ QVariant PostgreSqlGenerator::unescapeValue(const QMetaType::Type &type, const Q
|
||||||
return dbValue.toDate();
|
return dbValue.toDate();
|
||||||
|
|
||||||
if (type == QMetaType::QPoint)
|
if (type == QMetaType::QPoint)
|
||||||
return SqlGeneratorBase::unescapeValue(QMetaType::QPoint, dbValue.toString()
|
return AbstractSqlGenerator::unescapeValue(QMetaType::QPoint,
|
||||||
.replace("(", "").replace(")", ""));
|
dbValue.toString()
|
||||||
|
.replace(QStringLiteral("("),
|
||||||
|
QStringLiteral(""))
|
||||||
|
.replace(QStringLiteral(")"),
|
||||||
|
QStringLiteral("")));
|
||||||
if (type == QMetaType::QPointF)
|
if (type == QMetaType::QPointF)
|
||||||
return SqlGeneratorBase::unescapeValue(QMetaType::QPointF, dbValue.toString()
|
return AbstractSqlGenerator::unescapeValue(QMetaType::QPointF,
|
||||||
.replace("(", "").replace(")", ""));
|
dbValue.toString()
|
||||||
|
.replace(QStringLiteral("("),
|
||||||
|
QStringLiteral(""))
|
||||||
|
.replace(QStringLiteral(")"),
|
||||||
|
QStringLiteral("")));
|
||||||
if (type == QMetaType::QStringList)
|
if (type == QMetaType::QStringList)
|
||||||
return dbValue.toString().replace("{", "").replace("}", "")
|
return dbValue.toString()
|
||||||
.split(",");
|
.replace(QStringLiteral("{"), QStringLiteral(""))
|
||||||
|
.replace(QStringLiteral("}"), QStringLiteral(""))
|
||||||
|
.split(QStringLiteral(","));
|
||||||
|
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
if (type == QMetaType::QPolygon) {
|
if (type == QMetaType::QPolygon) {
|
||||||
|
|
@ -320,7 +337,7 @@ QVariant PostgreSqlGenerator::unescapeValue(const QMetaType::Type &type, const Q
|
||||||
return pol;
|
return pol;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return SqlGeneratorBase::unescapeValue(type, dbValue);
|
return AbstractSqlGenerator::unescapeValue(type, dbValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
|
|
@ -337,8 +354,8 @@ QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
|
|
||||||
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 QStringLiteral("%1 ~= %2")
|
||||||
.arg(SqlGeneratorBase::createConditionalPhrase(d->left),
|
.arg(AbstractSqlGenerator::createConditionalPhrase(d->left),
|
||||||
escapeValue(d->operand));
|
escapeValue(d->operand));
|
||||||
}
|
}
|
||||||
switch (op) {
|
switch (op) {
|
||||||
|
|
@ -354,10 +371,10 @@ QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::AddMinutesDateTime:
|
case PhraseData::AddMinutesDateTime:
|
||||||
case PhraseData::AddSeconds:
|
case PhraseData::AddSeconds:
|
||||||
case PhraseData::AddSecondsDateTime:
|
case PhraseData::AddSecondsDateTime:
|
||||||
return QString("%1 + interval '%2 %3'")
|
return QStringLiteral("%1 + interval '%2 %3'")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
d->operand.toString(),
|
d->operand.toString(),
|
||||||
SqlGeneratorBase::dateTimePartName(op));
|
AbstractSqlGenerator::dateTimePartName(op));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -372,16 +389,16 @@ QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::DatePartHour:
|
case PhraseData::DatePartHour:
|
||||||
case PhraseData::DatePartMinute:
|
case PhraseData::DatePartMinute:
|
||||||
case PhraseData::DatePartSecond:
|
case PhraseData::DatePartSecond:
|
||||||
return QString("date_part('%2', %1)")
|
return QStringLiteral("date_part('%2', %1)")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
SqlGeneratorBase::dateTimePartName(op));
|
AbstractSqlGenerator::dateTimePartName(op));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SqlGeneratorBase::createConditionalPhrase(d);
|
return AbstractSqlGenerator::createConditionalPhrase(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -22,11 +22,12 @@
|
||||||
#define POSTGRESQLGENERATOR_H
|
#define POSTGRESQLGENERATOR_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include "sqlgeneratorbase_p.h"
|
|
||||||
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT PostgreSqlGenerator : public SqlGeneratorBase
|
class NUT_EXPORT PostgreSqlGenerator : public AbstractSqlGenerator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool readInsideParentese(QString &text, QString &out);
|
bool readInsideParentese(QString &text, QString &out);
|
||||||
|
|
@ -19,12 +19,12 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "sqlitegenerator.h"
|
#include "sqlitegenerator.h"
|
||||||
#include "../table.h"
|
#include "table.h"
|
||||||
#include "../tablemodel.h"
|
#include "tablemodel.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
SqliteGenerator::SqliteGenerator(Database *parent) : SqlGeneratorBase(parent)
|
SqliteGenerator::SqliteGenerator(Database *parent) : AbstractSqlGenerator(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -32,28 +32,28 @@ SqliteGenerator::SqliteGenerator(Database *parent) : SqlGeneratorBase(parent)
|
||||||
QString SqliteGenerator::fieldType(FieldModel *field)
|
QString SqliteGenerator::fieldType(FieldModel *field)
|
||||||
{
|
{
|
||||||
switch (field->type) {
|
switch (field->type) {
|
||||||
case QMetaType::Bool: return "BOOLEAN";
|
case QMetaType::Bool: return QStringLiteral("BOOLEAN");
|
||||||
case QMetaType::QBitArray:
|
case QMetaType::QBitArray:
|
||||||
case QMetaType::QByteArray: return "BLOB";
|
case QMetaType::QByteArray: return QStringLiteral("BLOB");
|
||||||
case QMetaType::QDate: return "DATE";
|
case QMetaType::QDate: return QStringLiteral("DATE");
|
||||||
case QMetaType::QDateTime: return "DATETIME";
|
case QMetaType::QDateTime: return QStringLiteral("DATETIME");
|
||||||
case QMetaType::QTime: return "TIME";
|
case QMetaType::QTime: return QStringLiteral("TIME");
|
||||||
case QMetaType::Double: return "DOUBLE";
|
case QMetaType::Double: return QStringLiteral("DOUBLE");
|
||||||
case QMetaType::Float: return "FLOAT";
|
case QMetaType::Float: return QStringLiteral("FLOAT");
|
||||||
|
|
||||||
case QMetaType::SChar:
|
case QMetaType::SChar:
|
||||||
case QMetaType::Char: return "TINYINT";
|
case QMetaType::Char: return QStringLiteral("TINYINT");
|
||||||
case QMetaType::UChar: return "TINYINT UNSIGNED";
|
case QMetaType::UChar: return QStringLiteral("TINYINT UNSIGNED");
|
||||||
case QMetaType::Short: return "SMALLINT";
|
case QMetaType::Short: return QStringLiteral("SMALLINT");
|
||||||
case QMetaType::UShort: return "SMALLINT UNSIGNED";
|
case QMetaType::UShort: return QStringLiteral("SMALLINT UNSIGNED");
|
||||||
case QMetaType::Int: return "INT";
|
case QMetaType::Int: return QStringLiteral("INT");
|
||||||
case QMetaType::UInt: return "INT UNSIGNED";
|
case QMetaType::UInt: return QStringLiteral("INT UNSIGNED");
|
||||||
case QMetaType::Long: return "MEDIUMINT";
|
case QMetaType::Long: return QStringLiteral("MEDIUMINT");
|
||||||
case QMetaType::ULong: return "MEDIUMINT UNSIGNED";
|
case QMetaType::ULong: return QStringLiteral("MEDIUMINT UNSIGNED");
|
||||||
case QMetaType::LongLong: return "BIGINT";
|
case QMetaType::LongLong: return QStringLiteral("BIGINT");
|
||||||
case QMetaType::ULongLong: return "BIGINT UNSIGNED";
|
case QMetaType::ULongLong: return QStringLiteral("BIGINT UNSIGNED");
|
||||||
|
|
||||||
case QMetaType::QChar: return "NCHAR(1)";
|
case QMetaType::QChar: return QStringLiteral("NCHAR(1)");
|
||||||
|
|
||||||
case QMetaType::QUrl:
|
case QMetaType::QUrl:
|
||||||
case QMetaType::QJsonArray:
|
case QMetaType::QJsonArray:
|
||||||
|
|
@ -72,16 +72,16 @@ QString SqliteGenerator::fieldType(FieldModel *field)
|
||||||
case QMetaType::QPolygonF:
|
case QMetaType::QPolygonF:
|
||||||
case QMetaType::QStringList:
|
case QMetaType::QStringList:
|
||||||
case QMetaType::QColor:
|
case QMetaType::QColor:
|
||||||
case QMetaType::QUuid: return "TEXT";
|
case QMetaType::QUuid: return QStringLiteral("TEXT");
|
||||||
|
|
||||||
// if (field->isAutoIncrement)
|
// if (field->isAutoIncrement)
|
||||||
// dbType.append(" PRIMARY KEY AUTOINCREMENT");
|
// dbType.append(" PRIMARY KEY AUTOINCREMENT");
|
||||||
|
|
||||||
case QMetaType::QString:
|
case QMetaType::QString:
|
||||||
if(field->length)
|
if(field->length)
|
||||||
return QString("VARCHAR(%1)").arg(field->length);
|
return QStringLiteral("VARCHAR(%1)").arg(field->length);
|
||||||
else
|
else
|
||||||
return "TEXT";
|
return QStringLiteral("TEXT");
|
||||||
default:
|
default:
|
||||||
// qWarning("The type (%s) does not supported",
|
// qWarning("The type (%s) does not supported",
|
||||||
// QMetaType::typeName(field->type));
|
// QMetaType::typeName(field->type));
|
||||||
|
|
@ -96,18 +96,18 @@ QString SqliteGenerator::fieldDeclare(FieldModel *field)
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
if (isNumeric(field->type) && field->isPrimaryKey) {
|
if (isNumeric(field->type) && field->isPrimaryKey) {
|
||||||
type = "INTEGER PRIMARY KEY";
|
type = QStringLiteral("INTEGER PRIMARY KEY");
|
||||||
if (field->isAutoIncrement)
|
if (field->isAutoIncrement)
|
||||||
type.append(" AUTOINCREMENT");
|
type.append(QStringLiteral(" AUTOINCREMENT"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field->notNull)
|
if (field->notNull)
|
||||||
type.append(" NOT NULL");
|
type.append(QStringLiteral(" NOT NULL"));
|
||||||
|
|
||||||
if (field->isUnique)
|
if (field->isUnique)
|
||||||
type.append(" UNIQUE");
|
type.append(QStringLiteral(" UNIQUE"));
|
||||||
|
|
||||||
return field->name + " " + type;
|
return field->name + QStringLiteral(" ") + type;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SqliteGenerator::supportAutoIncrement(const QMetaType::Type &type)
|
bool SqliteGenerator::supportAutoIncrement(const QMetaType::Type &type)
|
||||||
|
|
@ -124,10 +124,10 @@ QStringList SqliteGenerator::diff(TableModel *oldTable, TableModel *newTable)
|
||||||
if (*oldTable == *newTable)
|
if (*oldTable == *newTable)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
QStringList newTableSql = SqlGeneratorBase::diff(nullptr, newTable);
|
QStringList newTableSql = AbstractSqlGenerator::diff(nullptr, newTable);
|
||||||
|
|
||||||
if (!newTable)
|
if (!newTable)
|
||||||
return QStringList() << "DROP TABLE " + oldTable->name();
|
return QStringList() << QStringLiteral("DROP TABLE ") + oldTable->name();
|
||||||
|
|
||||||
if (!oldTable)
|
if (!oldTable)
|
||||||
return newTableSql;
|
return newTableSql;
|
||||||
|
|
@ -135,27 +135,27 @@ QStringList SqliteGenerator::diff(TableModel *oldTable, TableModel *newTable)
|
||||||
QList<QString> fieldNames;
|
QList<QString> fieldNames;
|
||||||
QList<QString> relations;
|
QList<QString> relations;
|
||||||
|
|
||||||
foreach (FieldModel *f, oldTable->fields())
|
Q_FOREACH (FieldModel *f, oldTable->fields())
|
||||||
if (!fieldNames.contains(f->name))
|
if (!fieldNames.contains(f->name))
|
||||||
fieldNames.append(f->name);
|
fieldNames.append(f->name);
|
||||||
foreach (RelationModel *r, oldTable->foreignKeys())
|
Q_FOREACH (RelationModel *r, oldTable->foreignKeys())
|
||||||
if (!relations.contains(r->localColumn))
|
if (!relations.contains(r->localColumn))
|
||||||
relations.append(r->localColumn);
|
relations.append(r->localColumn);
|
||||||
|
|
||||||
foreach (FieldModel *f, newTable->fields())
|
Q_FOREACH (FieldModel *f, newTable->fields())
|
||||||
if (!fieldNames.contains(f->name))
|
if (!fieldNames.contains(f->name))
|
||||||
fieldNames.append(f->name);
|
fieldNames.append(f->name);
|
||||||
foreach (RelationModel *r, newTable->foreignKeys())
|
Q_FOREACH (RelationModel *r, newTable->foreignKeys())
|
||||||
if (!relations.contains(r->localColumn))
|
if (!relations.contains(r->localColumn))
|
||||||
relations.append(r->localColumn);
|
relations.append(r->localColumn);
|
||||||
|
|
||||||
QString columns;
|
QString columns;
|
||||||
foreach (FieldModel *f, oldTable->fields()) {
|
Q_FOREACH (FieldModel *f, oldTable->fields()) {
|
||||||
if (!newTable->field(f->name))
|
if (!newTable->field(f->name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!columns.isEmpty())
|
if (!columns.isEmpty())
|
||||||
columns.append(", ");
|
columns.append(QStringLiteral(", "));
|
||||||
columns.append(f->name);
|
columns.append(f->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -176,26 +176,33 @@ QStringList SqliteGenerator::diff(TableModel *oldTable, TableModel *newTable)
|
||||||
SELECT id,
|
SELECT id,
|
||||||
t,
|
t,
|
||||||
m
|
m
|
||||||
FROM sqlitestudio_temp_table;
|
FROM nut_orm_temp_table;
|
||||||
|
|
||||||
DROP TABLE sqlitestudio_temp_table;
|
DROP TABLE sqlitestudio_temp_table;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret.append("ALTER TABLE " + newTable->name() + " RENAME TO sqlitestudio_temp_table;");
|
QString foreignKeys;
|
||||||
|
for (auto &f: newTable->foreignKeys()) {
|
||||||
|
if (!foreignKeys.isEmpty())
|
||||||
|
foreignKeys.append(QStringLiteral(", "));
|
||||||
|
foreignKeys.append(QStringLiteral("FOREIGN KEY(%1) REFERENCES %2(id)")
|
||||||
|
.arg(f->localColumn, f->masterTable->name()));
|
||||||
|
}
|
||||||
|
ret.append(QStringLiteral("ALTER TABLE ") + newTable->name() + QStringLiteral(" RENAME TO nut_orm_temp_table;"));
|
||||||
ret.append(newTableSql);
|
ret.append(newTableSql);
|
||||||
ret.append(QString("INSERT INTO %1 ( %2 ) SELECT %2 FROM sqlitestudio_temp_table;")
|
ret.append(QStringLiteral("INSERT INTO %1 ( %2 ) SELECT %2 FROM nut_orm_temp_table;")
|
||||||
.arg(newTable->name(), columns));
|
.arg(newTable->name(), columns));
|
||||||
ret.append("DROP TABLE sqlitestudio_temp_table;");
|
ret.append(QStringLiteral("DROP TABLE nut_orm_temp_table;"));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
void SqliteGenerator::appendSkipTake(QString &sql, int skip, int take)
|
void SqliteGenerator::appendSkipTake(QString &sql, int skip, int take)
|
||||||
{
|
{
|
||||||
if (take > 0 && skip > 0) {
|
if (take > 0 && skip > 0) {
|
||||||
sql.append(QString(" LIMIT %1 OFFSET %2")
|
sql.append(QStringLiteral(" LIMIT %1 OFFSET %2")
|
||||||
.arg(take)
|
.arg(take)
|
||||||
.arg(skip));
|
.arg(skip));
|
||||||
} else if (take > 0) {
|
} else if (take > 0) {
|
||||||
sql.append(QString(" LIMIT %1").arg(take));
|
sql.append(QStringLiteral(" LIMIT %1").arg(take));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,20 +236,20 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::AddMonths:
|
case PhraseData::AddMonths:
|
||||||
case PhraseData::AddDays: {
|
case PhraseData::AddDays: {
|
||||||
int i = d->operand.toInt();
|
int i = d->operand.toInt();
|
||||||
return QString("DATE(%1,'%2 %3')")
|
return QStringLiteral("DATE(%1,'%2 %3')")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
(i < 0 ? "" : "+") + QString::number(i),
|
(i < 0 ? QStringLiteral("") : QStringLiteral("+")) + QString::number(i),
|
||||||
dateTimePartName(op));
|
dateTimePartName(op));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PhraseData::AddHours:
|
case PhraseData::AddHours:
|
||||||
case PhraseData::AddMinutes:
|
case PhraseData::AddMinutes:
|
||||||
case PhraseData::AddSeconds: {
|
case PhraseData::AddSeconds: {
|
||||||
int i = d->operand.toInt();
|
int i = d->operand.toInt();
|
||||||
return QString("TIME(%1,'%2 %3')")
|
return QStringLiteral("TIME(%1,'%2 %3')")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
(i < 0 ? "" : "+") + QString::number(i),
|
(i < 0 ? QStringLiteral("") : QStringLiteral("+")) + QString::number(i),
|
||||||
dateTimePartName(op));
|
dateTimePartName(op));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PhraseData::AddYearsDateTime:
|
case PhraseData::AddYearsDateTime:
|
||||||
|
|
@ -252,9 +259,9 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::AddMinutesDateTime:
|
case PhraseData::AddMinutesDateTime:
|
||||||
case PhraseData::AddSecondsDateTime: {
|
case PhraseData::AddSecondsDateTime: {
|
||||||
int i = d->operand.toInt();
|
int i = d->operand.toInt();
|
||||||
return QString("DATETIME(%1,'%2 %3')")
|
return QStringLiteral("DATETIME(%1,'%2 %3')")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
(i < 0 ? "" : "+") + QString::number(i),
|
(i < 0 ? QStringLiteral("") : QStringLiteral("+")) + QString::number(i),
|
||||||
dateTimePartName(op));
|
dateTimePartName(op));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -265,27 +272,27 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
if (d->type == PhraseData::WithoutOperand) {
|
if (d->type == PhraseData::WithoutOperand) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case PhraseData::DatePartYear:
|
case PhraseData::DatePartYear:
|
||||||
return QString("CAST(strftime('%Y', %1) AS INT)")
|
return QStringLiteral("CAST(strftime('%Y', %1) AS INT)")
|
||||||
.arg(createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
||||||
case PhraseData::DatePartMonth:
|
case PhraseData::DatePartMonth:
|
||||||
return QString("CAST(strftime('%m', %1) AS INT)")
|
return QStringLiteral("CAST(strftime('%m', %1) AS INT)")
|
||||||
.arg(createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
||||||
case PhraseData::DatePartDay:
|
case PhraseData::DatePartDay:
|
||||||
return QString("CAST(strftime('%d', %1) AS INT)")
|
return QStringLiteral("CAST(strftime('%d', %1) AS INT)")
|
||||||
.arg(createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
||||||
case PhraseData::DatePartHour:
|
case PhraseData::DatePartHour:
|
||||||
return QString("CAST(strftime('%H', %1) AS INT)")
|
return QStringLiteral("CAST(strftime('%H', %1) AS INT)")
|
||||||
.arg(createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
||||||
case PhraseData::DatePartMinute:
|
case PhraseData::DatePartMinute:
|
||||||
return QString("CAST(strftime('%M', %1) AS INT)")
|
return QStringLiteral("CAST(strftime('%M', %1) AS INT)")
|
||||||
.arg(createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
||||||
case PhraseData::DatePartSecond:
|
case PhraseData::DatePartSecond:
|
||||||
return QString("CAST(strftime('%S', %1) AS INT)")
|
return QStringLiteral("CAST(strftime('%S', %1) AS INT)")
|
||||||
.arg(createConditionalPhrase(d->left));
|
.arg(createConditionalPhrase(d->left));
|
||||||
|
|
||||||
// case PhraseData::DatePartMilisecond:
|
// case PhraseData::DatePartMilisecond:
|
||||||
|
|
@ -296,21 +303,21 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SqlGeneratorBase::createConditionalPhrase(d);
|
return AbstractSqlGenerator::createConditionalPhrase(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqliteGenerator::escapeValue(const QVariant &v) const
|
QString SqliteGenerator::escapeValue(const QVariant &v) const
|
||||||
{
|
{
|
||||||
if (v.type() == QVariant::Time)
|
if (v.type() == QVariant::Time)
|
||||||
return "'" + v.toTime().toString("HH:mm:ss") + "'";
|
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::Date)
|
if (v.type() == QVariant::Date)
|
||||||
return "'" + v.toDate().toString("yyyy-MM-dd") + "'";
|
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::DateTime)
|
if (v.type() == QVariant::DateTime)
|
||||||
return "'" + v.toDateTime().toString("yyyy-MM-dd HH:mm:ss") + "'";
|
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
||||||
|
|
||||||
return SqlGeneratorBase::escapeValue(v);
|
return AbstractSqlGenerator::escapeValue(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SqliteGenerator::unescapeValue(const QMetaType::Type &type, const QVariant &dbValue)
|
QVariant SqliteGenerator::unescapeValue(const QMetaType::Type &type, const QVariant &dbValue)
|
||||||
|
|
@ -324,7 +331,7 @@ QVariant SqliteGenerator::unescapeValue(const QMetaType::Type &type, const QVari
|
||||||
if (type == QMetaType::QDate)
|
if (type == QMetaType::QDate)
|
||||||
return dbValue.toDate();
|
return dbValue.toDate();
|
||||||
|
|
||||||
return SqlGeneratorBase::unescapeValue(type, dbValue);
|
return AbstractSqlGenerator::unescapeValue(type, dbValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -22,11 +22,12 @@
|
||||||
#define SQLITEGENERATOR_H
|
#define SQLITEGENERATOR_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include "sqlgeneratorbase_p.h"
|
|
||||||
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT SqliteGenerator : public SqlGeneratorBase
|
class NUT_EXPORT SqliteGenerator : public AbstractSqlGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SqliteGenerator(Database *parent = nullptr);
|
explicit SqliteGenerator(Database *parent = nullptr);
|
||||||
|
|
@ -19,102 +19,93 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "sqlservergenerator.h"
|
#include "sqlservergenerator.h"
|
||||||
#include "../table.h"
|
#include "table.h"
|
||||||
#include "../tablemodel.h"
|
#include "tablemodel.h"
|
||||||
|
|
||||||
#include <QPoint>
|
#include <QtCore/QPoint>
|
||||||
#include <QRegularExpression>
|
#include <QtCore/QRegularExpression>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
SqlServerGenerator::SqlServerGenerator(Database *parent)
|
SqlServerGenerator::SqlServerGenerator(Database *parent)
|
||||||
: SqlGeneratorBase(parent)
|
: AbstractSqlGenerator(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlServerGenerator::masterDatabaseName(QString databaseName)
|
QString SqlServerGenerator::masterDatabaseName(QString databaseName)
|
||||||
{
|
{
|
||||||
return databaseName.replace(
|
return databaseName.replace(
|
||||||
QRegularExpression("DATABASE\\=(\\w+)",
|
QRegularExpression(QStringLiteral("DATABASE\\=(\\w+)"),
|
||||||
QRegularExpression::CaseInsensitiveOption),
|
QRegularExpression::CaseInsensitiveOption),
|
||||||
"DATABASE=");
|
QStringLiteral("DATABASE="));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlServerGenerator::fieldType(FieldModel *field)
|
QString SqlServerGenerator::fieldType(FieldModel *field)
|
||||||
{
|
{
|
||||||
QString dbType;
|
|
||||||
|
|
||||||
switch (field->type) {
|
switch (field->type) {
|
||||||
case QMetaType::Bool:
|
case QMetaType::Bool:
|
||||||
dbType = "BIT";
|
return QStringLiteral("BIT");
|
||||||
break;
|
|
||||||
|
|
||||||
case QMetaType::Char:
|
case QMetaType::Char:
|
||||||
case QMetaType::QChar:
|
case QMetaType::QChar:
|
||||||
dbType = "CHAR(1)";
|
return QStringLiteral("CHAR(1)");
|
||||||
break;
|
|
||||||
|
|
||||||
case QMetaType::SChar:
|
case QMetaType::SChar:
|
||||||
case QMetaType::UChar:
|
case QMetaType::UChar:
|
||||||
return "tinyint";
|
return QStringLiteral("tinyint");
|
||||||
|
|
||||||
case QMetaType::Short:
|
case QMetaType::Short:
|
||||||
case QMetaType::UShort:
|
case QMetaType::UShort:
|
||||||
return "smallint";
|
return QStringLiteral("smallint");
|
||||||
|
|
||||||
case QMetaType::UInt:
|
case QMetaType::UInt:
|
||||||
case QMetaType::Int:
|
case QMetaType::Int:
|
||||||
dbType = "INT";
|
|
||||||
if (field->isAutoIncrement)
|
if (field->isAutoIncrement)
|
||||||
dbType += " IDENTITY(1,1)";
|
return QStringLiteral("INT IDENTITY(1,1)");
|
||||||
break;
|
else
|
||||||
|
return QStringLiteral("INT");
|
||||||
|
|
||||||
case QMetaType::Long:
|
case QMetaType::Long:
|
||||||
case QMetaType::ULong:
|
case QMetaType::ULong:
|
||||||
case QMetaType::LongLong:
|
case QMetaType::LongLong:
|
||||||
case QMetaType::ULongLong:
|
case QMetaType::ULongLong:
|
||||||
return "bigint";
|
return QStringLiteral("bigint");
|
||||||
|
|
||||||
case QMetaType::Float:
|
case QMetaType::Float:
|
||||||
return "FLOAT(24)";
|
return QStringLiteral("FLOAT(24)");
|
||||||
|
|
||||||
case QMetaType::Double:
|
case QMetaType::Double:
|
||||||
return "REAL";
|
return QStringLiteral("REAL");
|
||||||
|
|
||||||
case QMetaType::QBitArray:
|
case QMetaType::QBitArray:
|
||||||
case QMetaType::QByteArray:
|
case QMetaType::QByteArray:
|
||||||
dbType = "VARBINARY";
|
|
||||||
|
|
||||||
if (field->length)
|
if (field->length)
|
||||||
dbType.append(" (" + QString::number(field->length) + ")");
|
return QStringLiteral("VARBINARY (") + QString::number(field->length) + QStringLiteral(")");
|
||||||
else
|
else
|
||||||
dbType.append(" (MAX)");
|
return QStringLiteral("VARBINARY (MAX)");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QMetaType::QDate:
|
case QMetaType::QDate:
|
||||||
dbType = "DATE";
|
return QStringLiteral("DATE");
|
||||||
break;
|
|
||||||
case QMetaType::QDateTime:
|
case QMetaType::QDateTime:
|
||||||
dbType = "DATETIME";
|
return QStringLiteral("DATETIME");
|
||||||
break;
|
|
||||||
case QMetaType::QTime:
|
case QMetaType::QTime:
|
||||||
dbType = "TIME";
|
return QStringLiteral("TIME");
|
||||||
break;
|
|
||||||
|
|
||||||
case QMetaType::QPoint:
|
case QMetaType::QPoint:
|
||||||
case QMetaType::QPointF:
|
case QMetaType::QPointF:
|
||||||
dbType = "TEXT";
|
return QStringLiteral("TEXT");
|
||||||
break;
|
|
||||||
|
|
||||||
case QMetaType::QString:
|
case QMetaType::QString:
|
||||||
if (field->length)
|
if (field->length)
|
||||||
dbType = QString("NVARCHAR(%1)").arg(field->length);
|
return QStringLiteral("NVARCHAR(%1)").arg(field->length);
|
||||||
else
|
else
|
||||||
dbType = "NVARCHAR(MAX)";
|
return QStringLiteral("NVARCHAR(MAX)");
|
||||||
break;
|
|
||||||
|
|
||||||
case QMetaType::QUuid:
|
case QMetaType::QUuid:
|
||||||
dbType = "UNIQUEIDENTIFIER";
|
return QStringLiteral("UNIQUEIDENTIFIER");
|
||||||
break;
|
|
||||||
|
|
||||||
case QMetaType::QPolygon:
|
case QMetaType::QPolygon:
|
||||||
case QMetaType::QPolygonF:
|
case QMetaType::QPolygonF:
|
||||||
|
|
@ -131,14 +122,12 @@ QString SqlServerGenerator::fieldType(FieldModel *field)
|
||||||
case QMetaType::QJsonObject:
|
case QMetaType::QJsonObject:
|
||||||
case QMetaType::QJsonDocument:
|
case QMetaType::QJsonDocument:
|
||||||
case QMetaType::QUrl:
|
case QMetaType::QUrl:
|
||||||
return "TEXT";
|
return QStringLiteral("TEXT");
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// Q_UNREACHABLE();
|
// Q_UNREACHABLE();
|
||||||
dbType = QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
return dbType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlServerGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
QString SqlServerGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
||||||
|
|
@ -149,12 +138,12 @@ QString SqlServerGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
||||||
return sql;
|
return sql;
|
||||||
|
|
||||||
if (!newField) {
|
if (!newField) {
|
||||||
sql = "DROP COLUMN " + oldField->name;
|
sql = QStringLiteral("DROP COLUMN ") + oldField->name;
|
||||||
} else {
|
} else {
|
||||||
if (oldField)
|
if (oldField)
|
||||||
sql = "MODIFY COLUMN ";
|
sql = QStringLiteral("MODIFY COLUMN ");
|
||||||
else
|
else
|
||||||
sql = "ADD ";
|
sql = QStringLiteral("ADD ");
|
||||||
|
|
||||||
sql.append(fieldDeclare(newField));
|
sql.append(fieldDeclare(newField));
|
||||||
}
|
}
|
||||||
|
|
@ -181,7 +170,7 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
||||||
// case QVariant::JsonObject:
|
// case QVariant::JsonObject:
|
||||||
// case QVariant::JsonDocument:
|
// case QVariant::JsonDocument:
|
||||||
case QVariant::Url:
|
case QVariant::Url:
|
||||||
return "N" + SqlGeneratorBase::escapeValue(v);
|
return QStringLiteral("N") + AbstractSqlGenerator::escapeValue(v);
|
||||||
|
|
||||||
// case QVariant::Point: {
|
// case QVariant::Point: {
|
||||||
// QPoint pt = v.toPoint();
|
// QPoint pt = v.toPoint();
|
||||||
|
|
@ -195,18 +184,17 @@ QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
||||||
// }
|
// }
|
||||||
|
|
||||||
case QVariant::Time:
|
case QVariant::Time:
|
||||||
return "'" + v.toTime().toString("HH:mm:ss") + "'";
|
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
||||||
|
|
||||||
case QVariant::Date:
|
case QVariant::Date:
|
||||||
return "'" + v.toDate().toString("yyyy-MM-dd") + "'";
|
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
||||||
|
|
||||||
case QVariant::DateTime:
|
case QVariant::DateTime:
|
||||||
return "'" + v.toDateTime().toString("yyyy-MM-dd HH:mm:ss") + "'";
|
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
return AbstractSqlGenerator::escapeValue(v);
|
||||||
}
|
}
|
||||||
return SqlGeneratorBase::escapeValue(v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SqlServerGenerator::unescapeValue(const QMetaType::Type &type, const QVariant &dbValue)
|
QVariant SqlServerGenerator::unescapeValue(const QMetaType::Type &type, const QVariant &dbValue)
|
||||||
|
|
@ -220,18 +208,18 @@ QVariant SqlServerGenerator::unescapeValue(const QMetaType::Type &type, const QV
|
||||||
if (type == QMetaType::QDate)
|
if (type == QMetaType::QDate)
|
||||||
return dbValue.toDate();
|
return dbValue.toDate();
|
||||||
|
|
||||||
return SqlGeneratorBase::unescapeValue(type, dbValue);
|
return AbstractSqlGenerator::unescapeValue(type, dbValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SqlServerGenerator::appendSkipTake(QString &sql, int skip, int take)
|
void SqlServerGenerator::appendSkipTake(QString &sql, int skip, int take)
|
||||||
{
|
{
|
||||||
if (skip != -1)
|
if (skip != -1)
|
||||||
sql.append(QString(" OFFSET %1 ROWS")
|
sql.append(QStringLiteral(" OFFSET %1 ROWS")
|
||||||
.arg(skip));
|
.arg(skip));
|
||||||
if (take > 0)
|
if (take > 0)
|
||||||
sql.append(QString(" FETCH %2 %1 ROWS ONLY")
|
sql.append(QStringLiteral(" FETCH %2 %1 ROWS ONLY")
|
||||||
.arg(take)
|
.arg(take)
|
||||||
.arg(skip > 1 ? "NEXT" : "FIRST"));
|
.arg(skip > 1 ? QStringLiteral("NEXT") : QStringLiteral("FIRST")));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlServerGenerator::createConditionalPhrase(const PhraseData *d) const
|
QString SqlServerGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
|
|
@ -260,10 +248,10 @@ QString SqlServerGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::AddMinutesDateTime:
|
case PhraseData::AddMinutesDateTime:
|
||||||
case PhraseData::AddSeconds:
|
case PhraseData::AddSeconds:
|
||||||
case PhraseData::AddSecondsDateTime:
|
case PhraseData::AddSecondsDateTime:
|
||||||
return QString("DATEADD(%3, %2, %1)")
|
return QStringLiteral("DATEADD(%3, %2, %1)")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
d->operand.toString(),
|
d->operand.toString(),
|
||||||
SqlGeneratorBase::dateTimePartName(op));
|
AbstractSqlGenerator::dateTimePartName(op));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -278,16 +266,16 @@ QString SqlServerGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::DatePartHour:
|
case PhraseData::DatePartHour:
|
||||||
case PhraseData::DatePartMinute:
|
case PhraseData::DatePartMinute:
|
||||||
case PhraseData::DatePartSecond:
|
case PhraseData::DatePartSecond:
|
||||||
return QString("DATEPART(%2, %1)")
|
return QStringLiteral("DATEPART(%2, %1)")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
SqlGeneratorBase::dateTimePartName(op));
|
AbstractSqlGenerator::dateTimePartName(op));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return SqlGeneratorBase::createConditionalPhrase(d);
|
return AbstractSqlGenerator::createConditionalPhrase(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -22,11 +22,12 @@
|
||||||
#define SQLSERVERGENERATOR_H
|
#define SQLSERVERGENERATOR_H
|
||||||
|
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include "sqlgeneratorbase_p.h"
|
|
||||||
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT SqlServerGenerator : public SqlGeneratorBase
|
class NUT_EXPORT SqlServerGenerator : public AbstractSqlGenerator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit SqlServerGenerator(Database *parent = nullptr);
|
explicit SqlServerGenerator(Database *parent = nullptr);
|
||||||
|
|
@ -21,15 +21,15 @@
|
||||||
#include "databasemodel.h"
|
#include "databasemodel.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
|
|
||||||
#include <QJsonArray>
|
#include <QtCore/QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QtCore/QJsonObject>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QMap<QString, DatabaseModel*> DatabaseModel::_models;
|
QMap<QString, DatabaseModel*> DatabaseModel::_models;
|
||||||
|
|
||||||
#define NODE_VERSION "version"
|
#define NODE_VERSION QStringLiteral("version")
|
||||||
#define NODE_TABLES "tables"
|
#define NODE_TABLES QStringLiteral("tables")
|
||||||
DatabaseModel::DatabaseModel(const QString &name) :
|
DatabaseModel::DatabaseModel(const QString &name) :
|
||||||
QList<TableModel*>(), _databaseClassName(name), _version(0)
|
QList<TableModel*>(), _databaseClassName(name), _version(0)
|
||||||
{
|
{
|
||||||
|
|
@ -48,7 +48,7 @@ DatabaseModel::DatabaseModel(const QJsonObject &json) :
|
||||||
setVersion(json.value(NODE_VERSION).toInt());
|
setVersion(json.value(NODE_VERSION).toInt());
|
||||||
|
|
||||||
QJsonObject tables = json.value(NODE_TABLES).toObject();
|
QJsonObject tables = json.value(NODE_TABLES).toObject();
|
||||||
foreach (QString key, tables.keys()) {
|
Q_FOREACH (QString key, tables.keys()) {
|
||||||
if(!tables.value(key).isObject())
|
if(!tables.value(key).isObject())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ RelationModel *DatabaseModel::relationByClassNames(const QString &masterClassNam
|
||||||
if(!childTable)
|
if(!childTable)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
foreach (RelationModel *rel, childTable->foreignKeys())
|
Q_FOREACH (RelationModel *rel, childTable->foreignKeys())
|
||||||
if(rel->masterClassName == masterClassName)
|
if(rel->masterClassName == masterClassName)
|
||||||
return rel;
|
return rel;
|
||||||
|
|
||||||
|
|
@ -160,7 +160,7 @@ RelationModel *DatabaseModel::relationByTableNames(const QString &masterTableNam
|
||||||
if(!childTable)
|
if(!childTable)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
foreach (RelationModel *rel, childTable->foreignKeys())
|
Q_FOREACH (RelationModel *rel, childTable->foreignKeys())
|
||||||
if(rel->masterTable->name() == masterTableName)
|
if(rel->masterTable->name() == masterTableName)
|
||||||
return rel;
|
return rel;
|
||||||
|
|
||||||
|
|
@ -174,7 +174,7 @@ DatabaseModel DatabaseModel::fromJson(QJsonObject &json)
|
||||||
model.setVersion(json.value(NODE_VERSION).toInt());
|
model.setVersion(json.value(NODE_VERSION).toInt());
|
||||||
|
|
||||||
QJsonObject tables = json.value(NODE_TABLES).toObject();
|
QJsonObject tables = json.value(NODE_TABLES).toObject();
|
||||||
foreach (QString key, tables.keys()) {
|
Q_FOREACH (QString key, tables.keys()) {
|
||||||
if(!json.value(key).isObject())
|
if(!json.value(key).isObject())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -209,8 +209,8 @@ bool DatabaseModel::remove(const QString &tableName)
|
||||||
void DatabaseModel::fixRelations()
|
void DatabaseModel::fixRelations()
|
||||||
{
|
{
|
||||||
/*TODO: fixme
|
/*TODO: fixme
|
||||||
foreach (TableModel *table, currentModel)
|
Q_FOREACH (TableModel *table, currentModel)
|
||||||
foreach (RelationModel *fk, table->foreignKeys())
|
Q_FOREACH (RelationModel *fk, table->foreignKeys())
|
||||||
fk->masterTable = currentModel.tableByClassName(fk->masterClassName);
|
fk->masterTable = currentModel.tableByClassName(fk->masterClassName);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
|
||||||
#include "defines.h"
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/databasemodel.h \
|
||||||
|
$$PWD/sqlmodel.h \
|
||||||
|
$$PWD/sqlmodel_p.h \
|
||||||
|
$$PWD/tablemodel.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/databasemodel.cpp \
|
||||||
|
$$PWD/sqlmodel.cpp \
|
||||||
|
$$PWD/tablemodel.cpp
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "tablesetbase_p.h"
|
#include "abstracttableset.h"
|
||||||
#include "databasemodel.h"
|
#include "databasemodel.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
|
@ -29,55 +29,58 @@
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
//SqlModel::SqlModel(Query *q) : QAbstractItemModel(q.)
|
SqlModelPrivate::SqlModelPrivate(SqlModel *parent) : q_ptr(parent)
|
||||||
//{
|
, renderer(nullptr)
|
||||||
|
{
|
||||||
//}
|
Q_UNUSED(parent)
|
||||||
|
}
|
||||||
|
|
||||||
void SqlModel::setRenderer(const std::function<QVariant (int, QVariant)> &renderer)
|
void SqlModel::setRenderer(const std::function<QVariant (int, QVariant)> &renderer)
|
||||||
{
|
{
|
||||||
_renderer = renderer;
|
Q_D(SqlModel);
|
||||||
|
d->renderer = renderer;
|
||||||
}
|
}
|
||||||
|
|
||||||
SqlModel::SqlModel(Database *database, TableSetBase *tableSet, QObject *parent)
|
SqlModel::SqlModel(Database *database, AbstractTableSet *tableSet, QObject *parent)
|
||||||
: QAbstractTableModel(parent)
|
: QAbstractTableModel(parent)
|
||||||
, _renderer(nullptr)
|
, d_ptr(new SqlModelPrivate(this))
|
||||||
, d(new SqlModelPrivate(this))
|
|
||||||
{
|
{
|
||||||
|
Q_D(SqlModel);
|
||||||
d->model = database->model()
|
d->model = database->model()
|
||||||
.tableByClassName(tableSet->childClassName());
|
.tableByClassName(tableSet->childClassName());
|
||||||
d->tableName = d->model->name();
|
d->tableName = d->model->name();
|
||||||
|
|
||||||
|
|
||||||
// setQuery("SELECT * FROM " + d->tableName, database->databaseName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SqlModel::rowCount(const QModelIndex &parent) const
|
int SqlModel::rowCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
|
Q_D(const SqlModel);
|
||||||
Q_UNUSED(parent)
|
Q_UNUSED(parent)
|
||||||
return d->rows.count();
|
return d->rows.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SqlModel::columnCount(const QModelIndex &parent) const
|
int SqlModel::columnCount(const QModelIndex &parent) const
|
||||||
{
|
{
|
||||||
|
Q_D(const SqlModel);
|
||||||
Q_UNUSED(parent)
|
Q_UNUSED(parent)
|
||||||
return d->model->fields().count();
|
return d->model->fields().count();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant SqlModel::data(const QModelIndex &index, int role) const
|
QVariant SqlModel::data(const QModelIndex &index, int role) const
|
||||||
{
|
{
|
||||||
|
Q_D(const SqlModel);
|
||||||
|
|
||||||
if (!index.isValid())
|
if (!index.isValid())
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
||||||
if (index.row() >= d->rows.count() || index.row() < 0)
|
if (index.row() >= d->rows.count() || index.row() < 0)
|
||||||
return QVariant("-");
|
return QVariant::fromValue(QStringLiteral("-"));
|
||||||
|
|
||||||
if (role == Qt::DisplayRole) {
|
if (role == Qt::DisplayRole) {
|
||||||
Row<Table> t = d->rows.at(index.row());
|
Row<Table> t = d->rows.at(index.row());
|
||||||
QVariant v = t->property(d->model->field(index.column())->name.toLocal8Bit().data());
|
QVariant v = t->property(d->model->field(index.column())->name.toLocal8Bit().data());
|
||||||
|
|
||||||
if (_renderer != nullptr)
|
if (d->renderer != nullptr)
|
||||||
v = _renderer(index.column(), v);
|
v = d->renderer(index.column(), v);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
|
@ -85,7 +88,8 @@ QVariant SqlModel::data(const QModelIndex &index, int role) const
|
||||||
|
|
||||||
void SqlModel::setRows(RowList<Table> rows)
|
void SqlModel::setRows(RowList<Table> rows)
|
||||||
{
|
{
|
||||||
d.detach();
|
Q_D(SqlModel);
|
||||||
|
|
||||||
if (d->rows.count()) {
|
if (d->rows.count()) {
|
||||||
beginRemoveRows(QModelIndex(), 0, d->rows.count());
|
beginRemoveRows(QModelIndex(), 0, d->rows.count());
|
||||||
d->rows.clear();
|
d->rows.clear();
|
||||||
|
|
@ -98,19 +102,15 @@ void SqlModel::setRows(RowList<Table> rows)
|
||||||
|
|
||||||
void SqlModel::append(Row<Table> table)
|
void SqlModel::append(Row<Table> table)
|
||||||
{
|
{
|
||||||
d.detach();
|
Q_D(SqlModel);
|
||||||
beginInsertRows(QModelIndex(), d->rows.count(), d->rows.count());
|
beginInsertRows(QModelIndex(), d->rows.count(), d->rows.count());
|
||||||
d->rows.append(table);
|
d->rows.append(table);
|
||||||
endInsertRows();
|
endInsertRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
//void SqlModel::append(Table *table)
|
|
||||||
//{
|
|
||||||
// append(TableType<Table>::Row(table));
|
|
||||||
//}
|
|
||||||
|
|
||||||
QVariant SqlModel::headerData(int section, Qt::Orientation orientation, int role) const
|
QVariant SqlModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
{
|
{
|
||||||
|
Q_D(const SqlModel);
|
||||||
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
||||||
return d->model->field(section)->displayName;
|
return d->model->field(section)->displayName;
|
||||||
}
|
}
|
||||||
|
|
@ -119,13 +119,8 @@ QVariant SqlModel::headerData(int section, Qt::Orientation orientation, int role
|
||||||
|
|
||||||
Row<Table> SqlModel::at(const int &i) const
|
Row<Table> SqlModel::at(const int &i) const
|
||||||
{
|
{
|
||||||
|
Q_D(const SqlModel);
|
||||||
return d->rows.at(i);
|
return d->rows.at(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
SqlModelPrivate::SqlModelPrivate(SqlModel *parent)
|
|
||||||
{
|
|
||||||
Q_UNUSED(parent)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -22,28 +22,27 @@
|
||||||
#define SQLMODEL_H
|
#define SQLMODEL_H
|
||||||
|
|
||||||
#include <QtCore/QAbstractTableModel>
|
#include <QtCore/QAbstractTableModel>
|
||||||
#include "defines.h"
|
#include <QtCore/QExplicitlySharedDataPointer>
|
||||||
#include "sqlmodel_p.h"
|
#include <QtCore/QList>
|
||||||
#include <QExplicitlySharedDataPointer>
|
|
||||||
#include <QList>
|
#include <QtNut/nut_global.h>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
class TableSetBase;
|
class AbstractTableSet;
|
||||||
class Table;
|
class Table;
|
||||||
class TableModel;
|
class TableModel;
|
||||||
|
class SqlModelPrivate;
|
||||||
class NUT_EXPORT SqlModel : public QAbstractTableModel
|
class NUT_EXPORT SqlModel : public QAbstractTableModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
SqlModelPrivate *d_ptr;
|
||||||
std::function <QVariant(int, QVariant)> _renderer;
|
Q_DECLARE_PRIVATE(SqlModel)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// explicit SqlModel(Query *q);
|
// explicit SqlModel(Query *q);
|
||||||
explicit SqlModel(Database *database, TableSetBase *tableSet, QObject *parent = Q_NULLPTR);
|
explicit SqlModel(Database *database, AbstractTableSet *tableSet, QObject *parent = Q_NULLPTR);
|
||||||
|
|
||||||
int rowCount(const QModelIndex &parent) const;
|
int rowCount(const QModelIndex &parent) const;
|
||||||
int columnCount(const QModelIndex &parent) const;
|
int columnCount(const QModelIndex &parent) const;
|
||||||
|
|
@ -56,14 +55,11 @@ public:
|
||||||
void append(Row<Table> table);
|
void append(Row<Table> table);
|
||||||
// void append(Table *table);
|
// void append(Table *table);
|
||||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const;
|
||||||
Row<Nut::Table> at(const int &i) const;
|
Row<Table> at(const int &i) const;
|
||||||
|
|
||||||
void setRenderer(const std::function<QVariant (int, QVariant)> &renderer);
|
void setRenderer(const std::function<QVariant (int, QVariant)> &renderer);
|
||||||
|
|
||||||
private:
|
Q_SIGNALS:
|
||||||
QExplicitlySharedDataPointer<SqlModelPrivate> d;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void beforeShowText(int col, QVariant &value);
|
void beforeShowText(int col, QVariant &value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -71,7 +67,7 @@ template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void SqlModel::setTable(RowList<T> rows)
|
Q_OUTOFLINE_TEMPLATE void SqlModel::setTable(RowList<T> rows)
|
||||||
{
|
{
|
||||||
RowList<Table> tab;
|
RowList<Table> tab;
|
||||||
foreach (auto t, rows)
|
Q_FOREACH (auto t, rows)
|
||||||
tab.append(t);
|
tab.append(t);
|
||||||
setRows(tab);
|
setRows(tab);
|
||||||
}
|
}
|
||||||
|
|
@ -1,23 +1,30 @@
|
||||||
#ifndef SQLMODEL_P_H
|
#ifndef SQLMODEL_P_H
|
||||||
#define SQLMODEL_P_H
|
#define SQLMODEL_P_H
|
||||||
|
|
||||||
#include <QSharedPointer>
|
#include <QtCore/QSharedPointer>
|
||||||
#include <QString>
|
#include <QtCore/QString>
|
||||||
#include "defines.h"
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class SqlModel;
|
class SqlModel;
|
||||||
class Table;
|
class Table;
|
||||||
class TableModel;
|
class TableModel;
|
||||||
class NUT_EXPORT SqlModelPrivate : public QSharedData {
|
class NUT_EXPORT SqlModelPrivate {
|
||||||
public:
|
public:
|
||||||
|
SqlModel *q_ptr;
|
||||||
|
Q_DECLARE_PUBLIC(SqlModel);
|
||||||
|
|
||||||
explicit SqlModelPrivate(SqlModel *parent);
|
explicit SqlModelPrivate(SqlModel *parent);
|
||||||
|
|
||||||
QString tableName;
|
QString tableName;
|
||||||
|
|
||||||
RowList<Table> rows;
|
RowList<Table> rows;
|
||||||
TableModel *model;
|
TableModel *model;
|
||||||
|
std::function <QVariant(int, QVariant)> renderer;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -21,15 +21,19 @@
|
||||||
#include <QtCore/QMetaObject>
|
#include <QtCore/QMetaObject>
|
||||||
#include <QtCore/QMetaProperty>
|
#include <QtCore/QMetaProperty>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QJsonArray>
|
||||||
#include <QJsonArray>
|
#include <QtCore/QJsonObject>
|
||||||
#include <QJsonObject>
|
|
||||||
|
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
#include "defines.h"
|
#include "nut_global.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
#define REL_LOCAL_COLUMN QStringLiteral("localColumn")
|
||||||
|
#define REL_LOCAL_PROPERTY QStringLiteral("localProperty")
|
||||||
|
#define REL_MASTER_CLASS_NAME QStringLiteral("masterClassName")
|
||||||
|
#define REL_FOREIGIN_COLUMN QStringLiteral("foreignColumn")
|
||||||
|
|
||||||
QString TableModel::name() const
|
QString TableModel::name() const
|
||||||
{
|
{
|
||||||
return _name;
|
return _name;
|
||||||
|
|
@ -70,7 +74,7 @@ FieldModel *TableModel::field(int n) const
|
||||||
|
|
||||||
FieldModel *TableModel::field(const QString &name) const
|
FieldModel *TableModel::field(const QString &name) const
|
||||||
{
|
{
|
||||||
foreach (FieldModel *f, _fields)
|
Q_FOREACH (FieldModel *f, _fields)
|
||||||
if(f->name == name)
|
if(f->name == name)
|
||||||
return f;
|
return f;
|
||||||
|
|
||||||
|
|
@ -90,7 +94,7 @@ QList<RelationModel *> TableModel::foreignKeys() const
|
||||||
QStringList TableModel::fieldsNames() const
|
QStringList TableModel::fieldsNames() const
|
||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
foreach (FieldModel *f, _fields)
|
Q_FOREACH (FieldModel *f, _fields)
|
||||||
ret.append(f->name);
|
ret.append(f->name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -102,7 +106,7 @@ bool TableModel::operator ==(const TableModel &t) const{
|
||||||
if(fields().count() != t.fields().count())
|
if(fields().count() != t.fields().count())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
foreach (FieldModel *f, _fields) {
|
Q_FOREACH (FieldModel *f, _fields) {
|
||||||
FieldModel *tf = t.field(f->name);
|
FieldModel *tf = t.field(f->name);
|
||||||
if(!tf)
|
if(!tf)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -129,7 +133,7 @@ TableModel::TableModel(int typeId, const QString &tableName)
|
||||||
|
|
||||||
_typeId = typeId;
|
_typeId = typeId;
|
||||||
_name = tableName;
|
_name = tableName;
|
||||||
_className = tableMetaObject->className();
|
_className = QString::fromUtf8(tableMetaObject->className());
|
||||||
|
|
||||||
//#ifdef NUT_NAMESPACE
|
//#ifdef NUT_NAMESPACE
|
||||||
// if(_className.startsWith(QT_STRINGIFY(NUT_NAMESPACE) "::"))
|
// if(_className.startsWith(QT_STRINGIFY(NUT_NAMESPACE) "::"))
|
||||||
|
|
@ -147,7 +151,7 @@ TableModel::TableModel(int typeId, const QString &tableName)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == __nut_FIELD){
|
if(type == QStringLiteral(__nut_FIELD)) {
|
||||||
auto *f = new FieldModel;
|
auto *f = new FieldModel;
|
||||||
f->name = f->displayName = name;
|
f->name = f->displayName = name;
|
||||||
_fields.append(f);
|
_fields.append(f);
|
||||||
|
|
@ -156,15 +160,15 @@ TableModel::TableModel(int typeId, const QString &tableName)
|
||||||
// Browse all fields
|
// Browse all fields
|
||||||
for(int j = 1; j < tableMetaObject->propertyCount(); j++){
|
for(int j = 1; j < tableMetaObject->propertyCount(); j++){
|
||||||
QMetaProperty fieldProperty = tableMetaObject->property(j);
|
QMetaProperty fieldProperty = tableMetaObject->property(j);
|
||||||
|
auto name = QString::fromUtf8(fieldProperty.name());
|
||||||
FieldModel *fieldObj = field(fieldProperty.name());
|
FieldModel *fieldObj = field(name);
|
||||||
foreach (FieldModel *f, _fields)
|
Q_FOREACH (FieldModel *f, _fields)
|
||||||
if(f->name == fieldProperty.name())
|
if(f->name == name)
|
||||||
f = fieldObj;
|
f = fieldObj;
|
||||||
if(!fieldObj)
|
if(!fieldObj)
|
||||||
continue;
|
continue;
|
||||||
fieldObj->type = static_cast<QMetaType::Type>(fieldProperty.type());
|
fieldObj->type = static_cast<QMetaType::Type>(fieldProperty.type());
|
||||||
fieldObj->typeName = QString(fieldProperty.typeName());
|
fieldObj->typeName = QString::fromUtf8(fieldProperty.typeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Browse class infos
|
// Browse class infos
|
||||||
|
|
@ -178,17 +182,17 @@ TableModel::TableModel(int typeId, const QString &tableName)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == __nut_FOREIGN_KEY){
|
if(type == QStringLiteral(__nut_FOREIGN_KEY)) {
|
||||||
auto *fk = new RelationModel;
|
auto *fk = new RelationModel;
|
||||||
fk->slaveTable = this;
|
fk->slaveTable = this;
|
||||||
fk->localColumn = name + "Id";
|
fk->localColumn = name + QStringLiteral("Id");
|
||||||
fk->localProperty = name;
|
fk->localProperty = name;
|
||||||
fk->foreignColumn = value;
|
fk->foreignColumn = value;
|
||||||
fk->masterClassName = value;
|
fk->masterClassName = value;
|
||||||
_foreignKeys.append(fk);
|
_foreignKeys.append(fk);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == __nut_FIELD){
|
if(type == QStringLiteral(__nut_FIELD)) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -197,21 +201,21 @@ TableModel::TableModel(int typeId, const QString &tableName)
|
||||||
if (!f)
|
if (!f)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (type == __nut_LEN)
|
if (type == QStringLiteral(__nut_LEN))
|
||||||
f->length = value.toInt();
|
f->length = value.toInt();
|
||||||
else if (type == __nut_NOT_NULL)
|
else if (type == QStringLiteral(__nut_NOT_NULL))
|
||||||
f->notNull = true;
|
f->notNull = true;
|
||||||
else if (type == __nut_DEFAULT_VALUE)
|
else if (type == QStringLiteral(__nut_DEFAULT_VALUE))
|
||||||
f->defaultValue = value;
|
f->defaultValue = value;
|
||||||
else if (type == __nut_PRIMARY_KEY)
|
else if (type == QStringLiteral(__nut_PRIMARY_KEY))
|
||||||
f->isPrimaryKey = true;
|
f->isPrimaryKey = true;
|
||||||
else if (type == __nut_AUTO_INCREMENT)
|
else if (type == QStringLiteral(__nut_AUTO_INCREMENT))
|
||||||
f->isAutoIncrement = true;
|
f->isAutoIncrement = true;
|
||||||
else if (type == __nut_UNIQUE)
|
else if (type == QStringLiteral(__nut_UNIQUE))
|
||||||
f->isUnique = true;
|
f->isUnique = true;
|
||||||
else if (type == __nut_DISPLAY)
|
else if (type == QStringLiteral(__nut_DISPLAY))
|
||||||
f->displayName = value.mid(1, value.length() - 2);
|
f->displayName = value.mid(1, value.length() - 2);
|
||||||
else if (type == __nut_PRIMARY_KEY_AI) {
|
else if (type == QStringLiteral(__nut_PRIMARY_KEY_AI)) {
|
||||||
f->isPrimaryKey = true;
|
f->isPrimaryKey = true;
|
||||||
f->isAutoIncrement = true;
|
f->isAutoIncrement = true;
|
||||||
}
|
}
|
||||||
|
|
@ -238,31 +242,31 @@ TableModel::TableModel(const QJsonObject &json, const QString &tableName) : _typ
|
||||||
{
|
{
|
||||||
_name = tableName;
|
_name = tableName;
|
||||||
|
|
||||||
QJsonObject fields = json.value(__FIELDS).toObject();
|
QJsonObject fields = json.value(QStringLiteral(__FIELDS)).toObject();
|
||||||
QJsonObject relations = json.value(__FOREIGN_KEYS).toObject();
|
QJsonObject relations = json.value(QStringLiteral(__FOREIGN_KEYS)).toObject();
|
||||||
foreach (QString key, fields.keys()) {
|
Q_FOREACH (QString key, fields.keys()) {
|
||||||
QJsonObject fieldObject = fields.value(key).toObject();
|
QJsonObject fieldObject = fields.value(key).toObject();
|
||||||
//TODO: use FieldModel(QJsonObject) ctor
|
//TODO: use FieldModel(QJsonObject) ctor
|
||||||
auto *f = new FieldModel;
|
auto *f = new FieldModel;
|
||||||
f->name = fieldObject.value(__NAME).toString();
|
f->name = fieldObject.value(QStringLiteral(__NAME)).toString();
|
||||||
f->type = static_cast<QMetaType::Type>(QMetaType::type(fieldObject.value(__TYPE).toString().toLatin1().data()));
|
f->type = static_cast<QMetaType::Type>(QMetaType::type(fieldObject.value(QStringLiteral(__TYPE)).toString().toLatin1().data()));
|
||||||
f->typeName = QMetaType::typeName(f->type);
|
f->typeName = QString::fromUtf8(QMetaType::typeName(f->type));
|
||||||
|
|
||||||
if(fieldObject.contains(__nut_NOT_NULL))
|
if(fieldObject.contains(QStringLiteral(__nut_NOT_NULL)))
|
||||||
f->notNull = fieldObject.value(__nut_NOT_NULL).toBool();
|
f->notNull = fieldObject.value(QStringLiteral(__nut_NOT_NULL)).toBool();
|
||||||
|
|
||||||
if(fieldObject.contains(__nut_UNIQUE))
|
if(fieldObject.contains(QStringLiteral(__nut_UNIQUE)))
|
||||||
f->isUnique = fieldObject.value(__nut_UNIQUE).toBool();
|
f->isUnique = fieldObject.value(QStringLiteral(__nut_UNIQUE)).toBool();
|
||||||
|
|
||||||
if(fieldObject.contains(__nut_LEN))
|
if(fieldObject.contains(QStringLiteral(__nut_LEN)))
|
||||||
f->length = fieldObject.value(__nut_LEN).toInt();
|
f->length = fieldObject.value(QStringLiteral(__nut_LEN)).toInt();
|
||||||
|
|
||||||
if(fieldObject.contains(__nut_DEFAULT_VALUE))
|
if(fieldObject.contains(QStringLiteral(__nut_DEFAULT_VALUE)))
|
||||||
f->defaultValue = fieldObject.value(__nut_DEFAULT_VALUE).toString();
|
f->defaultValue = fieldObject.value(QStringLiteral(__nut_DEFAULT_VALUE)).toString();
|
||||||
_fields.append(f);
|
_fields.append(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (QString key, relations.keys()) {
|
Q_FOREACH (QString key, relations.keys()) {
|
||||||
QJsonObject relObject = fields.value(key).toObject();
|
QJsonObject relObject = fields.value(key).toObject();
|
||||||
_foreignKeys.append(new RelationModel(relObject));
|
_foreignKeys.append(new RelationModel(relObject));
|
||||||
}
|
}
|
||||||
|
|
@ -280,43 +284,43 @@ QJsonObject TableModel::toJson() const
|
||||||
QJsonObject fieldsObj;
|
QJsonObject fieldsObj;
|
||||||
QJsonObject foreignKeysObj;
|
QJsonObject foreignKeysObj;
|
||||||
|
|
||||||
foreach (FieldModel *f, _fields) {
|
Q_FOREACH (FieldModel *f, _fields) {
|
||||||
QJsonObject fieldObj;
|
QJsonObject fieldObj;
|
||||||
fieldObj.insert(__NAME, f->name);
|
fieldObj.insert(QStringLiteral(__NAME), f->name);
|
||||||
fieldObj.insert(__TYPE, QString(QVariant::typeToName(f->type)));
|
fieldObj.insert(QStringLiteral(__TYPE), QString::fromUtf8(QVariant::typeToName(f->type)));
|
||||||
|
|
||||||
if(f->length)
|
if(f->length)
|
||||||
fieldObj.insert(__nut_LEN, f->length);
|
fieldObj.insert(QStringLiteral(__nut_LEN), f->length);
|
||||||
|
|
||||||
if(f->notNull)
|
if(f->notNull)
|
||||||
fieldObj.insert(__nut_NOT_NULL, f->notNull);
|
fieldObj.insert(QStringLiteral(__nut_NOT_NULL), f->notNull);
|
||||||
|
|
||||||
if(f->isUnique)
|
if(f->isUnique)
|
||||||
fieldObj.insert(__nut_UNIQUE, f->isUnique);
|
fieldObj.insert(QStringLiteral(__nut_UNIQUE), f->isUnique);
|
||||||
|
|
||||||
if(!f->defaultValue.isNull())
|
if(!f->defaultValue.isNull())
|
||||||
fieldObj.insert(__nut_DEFAULT_VALUE, f->defaultValue);
|
fieldObj.insert(QStringLiteral(__nut_DEFAULT_VALUE), f->defaultValue);
|
||||||
|
|
||||||
if(f->isAutoIncrement)
|
if(f->isAutoIncrement)
|
||||||
obj.insert(__nut_AUTO_INCREMENT, f->name);
|
obj.insert(QStringLiteral(__nut_AUTO_INCREMENT), f->name);
|
||||||
|
|
||||||
if(f->isPrimaryKey)
|
if(f->isPrimaryKey)
|
||||||
obj.insert(__nut_PRIMARY_KEY, f->name);
|
obj.insert(QStringLiteral(__nut_PRIMARY_KEY), f->name);
|
||||||
|
|
||||||
fieldsObj.insert(f->name, fieldObj);
|
fieldsObj.insert(f->name, fieldObj);
|
||||||
}
|
}
|
||||||
foreach (RelationModel *rel, _foreignKeys)
|
Q_FOREACH (RelationModel *rel, _foreignKeys)
|
||||||
foreignKeysObj.insert(rel->localColumn, rel->toJson());
|
foreignKeysObj.insert(rel->localColumn, rel->toJson());
|
||||||
|
|
||||||
obj.insert(__FIELDS, fieldsObj);
|
obj.insert(QStringLiteral(__FIELDS), fieldsObj);
|
||||||
obj.insert(__FOREIGN_KEYS, foreignKeysObj);
|
obj.insert(QStringLiteral(__FOREIGN_KEYS), foreignKeysObj);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelationModel *TableModel::foreignKey(const QString &otherTable) const
|
RelationModel *TableModel::foreignKey(const QString &otherTable) const
|
||||||
{
|
{
|
||||||
foreach (RelationModel *fk, _foreignKeys)
|
Q_FOREACH (RelationModel *fk, _foreignKeys)
|
||||||
if(fk->masterClassName == otherTable)
|
if(fk->masterClassName == otherTable)
|
||||||
return fk;
|
return fk;
|
||||||
|
|
||||||
|
|
@ -325,7 +329,7 @@ RelationModel *TableModel::foreignKey(const QString &otherTable) const
|
||||||
|
|
||||||
RelationModel *TableModel::foreignKeyByField(const QString &fieldName) const
|
RelationModel *TableModel::foreignKeyByField(const QString &fieldName) const
|
||||||
{
|
{
|
||||||
foreach (RelationModel *fk, _foreignKeys)
|
Q_FOREACH (RelationModel *fk, _foreignKeys)
|
||||||
if(fk->localColumn == fieldName)
|
if(fk->localColumn == fieldName)
|
||||||
return fk;
|
return fk;
|
||||||
|
|
||||||
|
|
@ -335,17 +339,18 @@ RelationModel *TableModel::foreignKeyByField(const QString &fieldName) const
|
||||||
QString TableModel::toString() const
|
QString TableModel::toString() const
|
||||||
{
|
{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
foreach (FieldModel *f, _fields)
|
Q_FOREACH (FieldModel *f, _fields)
|
||||||
sl.append(f->name + " " + QVariant::typeToName(f->type));
|
sl.append(f->name + QStringLiteral(" ")
|
||||||
|
+ QString::fromUtf8(QVariant::typeToName(f->type)));
|
||||||
|
|
||||||
QString ret = QString("%1 (%2)")
|
QString ret = QStringLiteral("%1 (%2)")
|
||||||
.arg(_name, sl.join(", "));
|
.arg(_name, sl.join(QStringLiteral(", ")));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString TableModel::primaryKey() const
|
QString TableModel::primaryKey() const
|
||||||
{
|
{
|
||||||
foreach (FieldModel *f, _fields)
|
Q_FOREACH (FieldModel *f, _fields)
|
||||||
if(f->isPrimaryKey)
|
if(f->isPrimaryKey)
|
||||||
return f->name;
|
return f->name;
|
||||||
return QString();
|
return QString();
|
||||||
|
|
@ -361,47 +366,47 @@ bool TableModel::isPrimaryKeyAutoIncrement() const
|
||||||
|
|
||||||
FieldModel::FieldModel(const QJsonObject &json)
|
FieldModel::FieldModel(const QJsonObject &json)
|
||||||
{
|
{
|
||||||
name = json.value(__NAME).toString();
|
name = json.value(QStringLiteral(__NAME)).toString();
|
||||||
type = static_cast<QMetaType::Type>(json.value(__TYPE).toInt());
|
type = static_cast<QMetaType::Type>(json.value(QStringLiteral(__TYPE)).toInt());
|
||||||
length = json.value(__nut_LEN).toInt();
|
length = json.value(QStringLiteral(__nut_LEN)).toInt();
|
||||||
notNull = json.value(__nut_NOT_NULL).toBool();
|
notNull = json.value(QStringLiteral(__nut_NOT_NULL)).toBool();
|
||||||
isUnique = json.value(__nut_UNIQUE).toBool();
|
isUnique = json.value(QStringLiteral(__nut_UNIQUE)).toBool();
|
||||||
isAutoIncrement = json.value(__nut_AUTO_INCREMENT).toBool();
|
isAutoIncrement = json.value(QStringLiteral(__nut_AUTO_INCREMENT)).toBool();
|
||||||
isPrimaryKey = json.value(__nut_PRIMARY_KEY).toBool();
|
isPrimaryKey = json.value(QStringLiteral(__nut_PRIMARY_KEY)).toBool();
|
||||||
defaultValue = json.value(__nut_DEFAULT_VALUE).toString();
|
defaultValue = json.value(QStringLiteral(__nut_DEFAULT_VALUE)).toString();
|
||||||
isUnique = json.value(__nut_UNIQUE).toBool();
|
isUnique = json.value(QStringLiteral(__nut_UNIQUE)).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject FieldModel::toJson() const
|
QJsonObject FieldModel::toJson() const
|
||||||
{
|
{
|
||||||
QJsonObject fieldObj;
|
QJsonObject fieldObj;
|
||||||
fieldObj.insert(__NAME, name);
|
fieldObj.insert(QStringLiteral(__NAME), name);
|
||||||
fieldObj.insert(__TYPE, QString(QVariant::typeToName(type)));
|
fieldObj.insert(QStringLiteral(__TYPE), QString::fromUtf8(QVariant::typeToName(type)));
|
||||||
fieldObj.insert(__nut_LEN, length);
|
fieldObj.insert(QStringLiteral(__nut_LEN), length);
|
||||||
fieldObj.insert(__nut_NOT_NULL, notNull);
|
fieldObj.insert(QStringLiteral(__nut_NOT_NULL), notNull);
|
||||||
fieldObj.insert(__nut_UNIQUE, isUnique);
|
fieldObj.insert(QStringLiteral(__nut_UNIQUE), isUnique);
|
||||||
fieldObj.insert(__nut_AUTO_INCREMENT, isAutoIncrement);
|
fieldObj.insert(QStringLiteral(__nut_AUTO_INCREMENT), isAutoIncrement);
|
||||||
fieldObj.insert(__nut_PRIMARY_KEY, isPrimaryKey);
|
fieldObj.insert(QStringLiteral(__nut_PRIMARY_KEY), isPrimaryKey);
|
||||||
fieldObj.insert(__nut_DEFAULT_VALUE, defaultValue);
|
fieldObj.insert(QStringLiteral(__nut_DEFAULT_VALUE), defaultValue);
|
||||||
return fieldObj;
|
return fieldObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelationModel::RelationModel(const QJsonObject &obj)
|
RelationModel::RelationModel(const QJsonObject &obj)
|
||||||
{
|
{
|
||||||
localColumn = obj.value("localColumn").toString();
|
localColumn = obj.value(REL_LOCAL_COLUMN).toString();
|
||||||
localProperty = obj.value("localProperty").toString();
|
localProperty = obj.value(REL_LOCAL_PROPERTY).toString();
|
||||||
masterClassName = obj.value("masterClassName").toString();
|
masterClassName = obj.value(REL_MASTER_CLASS_NAME).toString();
|
||||||
foreignColumn = obj.value("foreignColumn").toString();
|
foreignColumn = obj.value(REL_FOREIGIN_COLUMN).toString();
|
||||||
slaveTable = masterTable = nullptr;
|
slaveTable = masterTable = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
QJsonObject RelationModel::toJson() const
|
QJsonObject RelationModel::toJson() const
|
||||||
{
|
{
|
||||||
QJsonObject o;
|
QJsonObject o;
|
||||||
o.insert("localColumn", localColumn);
|
o.insert(REL_LOCAL_COLUMN, localColumn);
|
||||||
o.insert("localProperty", localProperty);
|
o.insert(REL_LOCAL_PROPERTY, localProperty);
|
||||||
o.insert("masterClassName", masterClassName);
|
o.insert(REL_MASTER_CLASS_NAME, masterClassName);
|
||||||
o.insert("foreignColumn", foreignColumn);
|
o.insert(REL_FOREIGIN_COLUMN, foreignColumn);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -22,8 +22,9 @@
|
||||||
#define TABLEMODEL_H
|
#define TABLEMODEL_H
|
||||||
|
|
||||||
#include <QtCore/QVariant>
|
#include <QtCore/QVariant>
|
||||||
#include <QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include "defines.h"
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
DEFINES += NUT_SHARED_POINTER
|
||||||
|
QT = core sql gui
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD
|
||||||
|
|
||||||
|
include(config/config.pri)
|
||||||
|
include(core/core.pri)
|
||||||
|
include(generators/generators.pri)
|
||||||
|
include(types/types.pri)
|
||||||
|
include(phrases/phrases.pri)
|
||||||
|
include(models/models.pri)
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/phrase.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/phrase.cpp
|
||||||
|
|
||||||
|
include($$PWD/3rdparty/serializer/src/src.pri)
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
load(qt_build_config)
|
||||||
|
MODULE = nut
|
||||||
|
|
||||||
|
TARGET = QtNut
|
||||||
|
|
||||||
|
QT = core sql gui
|
||||||
|
|
||||||
|
DEFINES += QT_DEPRECATED_WARNINGS NUT_SHARED NUT_BUILD_LIB
|
||||||
|
|
||||||
|
DEFINES += NUT_SHARED_POINTER
|
||||||
|
|
||||||
|
include(config/config.pri)
|
||||||
|
include(core/core.pri)
|
||||||
|
include(generators/generators.pri)
|
||||||
|
include(types/types.pri)
|
||||||
|
include(phrases/phrases.pri)
|
||||||
|
include(models/models.pri)
|
||||||
|
|
||||||
|
HEADERS += \
|
||||||
|
$$PWD/phrase.h
|
||||||
|
|
||||||
|
SOURCES += \
|
||||||
|
$$PWD/phrase.cpp
|
||||||
|
|
||||||
|
load(qt_module)
|
||||||
|
|
||||||
|
include($$PWD/3rdparty/serializer/src/src.pri)
|
||||||
|
|
@ -18,43 +18,4 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef QUERY_P_H
|
|
||||||
#define QUERY_P_H
|
|
||||||
|
|
||||||
#include "phrase.h"
|
#include "phrase.h"
|
||||||
|
|
||||||
#include <QtCore/QList>
|
|
||||||
#include <QtCore/QString>
|
|
||||||
#include <QtCore/QSharedData>
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
class Database;
|
|
||||||
class TableSetBase;
|
|
||||||
class QueryBase;
|
|
||||||
struct RelationModel;
|
|
||||||
class NUT_EXPORT QueryPrivate : public QSharedData {
|
|
||||||
QueryBase *q_ptr;
|
|
||||||
Q_DECLARE_PUBLIC(QueryBase)
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit QueryPrivate(QueryBase *parent);
|
|
||||||
~QueryPrivate();
|
|
||||||
|
|
||||||
QString sql;
|
|
||||||
QString className;
|
|
||||||
QString tableName;
|
|
||||||
QString select;
|
|
||||||
Database *database;
|
|
||||||
TableSetBase *tableSet;
|
|
||||||
QStringList joins;
|
|
||||||
QList<RelationModel*> relations;
|
|
||||||
int skip;
|
|
||||||
int take;
|
|
||||||
PhraseList orderPhrase, fieldPhrase;
|
|
||||||
ConditionalPhrase wherePhrase;
|
|
||||||
};
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // QUERY_P_H
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Nut project.
|
||||||
|
** https://github.com/HamedMasafi/Nut
|
||||||
|
**
|
||||||
|
** Nut is free software: you can redistribute it and/or modify
|
||||||
|
** it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
** the Free Software Foundation, either version 3 of the License, or
|
||||||
|
** (at your option) any later version.
|
||||||
|
**
|
||||||
|
** Nut is distributed in the hope that it will be useful,
|
||||||
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
** GNU Lesser General Public License for more details.
|
||||||
|
**
|
||||||
|
** You should have received a copy of the GNU Lesser General Public License
|
||||||
|
** along with Nut. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef PHRASE_H
|
||||||
|
#define PHRASE_H
|
||||||
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
#include <QtNut/conditionalphrase.h>
|
||||||
|
#include <QtNut/abstractfieldphrase.h>
|
||||||
|
#include <QtNut/fieldphrase.h>
|
||||||
|
#include <QtNut/phraselist.h>
|
||||||
|
#include <QtNut/assignmentphraselist.h>
|
||||||
|
#include <QtNut/phrasedatalist.h>
|
||||||
|
#include <QtNut/phrasedata.h>
|
||||||
|
#include <QtNut/assignmentphrase.h>
|
||||||
|
#include <QtNut/numericphrase.h>
|
||||||
|
#include <QtNut/fieldphrase_date.h>
|
||||||
|
#include <QtNut/fieldphrase_qstring.h>
|
||||||
|
#include <QtNut/fieldphrase_bool.h>
|
||||||
|
|
||||||
|
#endif // PHRASE_H
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "abstractfieldphrase.h"
|
#include "abstractfieldphrase.h"
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -34,22 +35,26 @@ AbstractFieldPhrase::AbstractFieldPhrase(const char *className,
|
||||||
AbstractFieldPhrase::AbstractFieldPhrase(const AbstractFieldPhrase &other)
|
AbstractFieldPhrase::AbstractFieldPhrase(const AbstractFieldPhrase &other)
|
||||||
{
|
{
|
||||||
data = other.data;
|
data = other.data;
|
||||||
data->parents++;
|
data->ref.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFieldPhrase::AbstractFieldPhrase(AbstractFieldPhrase &&other)
|
AbstractFieldPhrase::AbstractFieldPhrase(AbstractFieldPhrase &&other)
|
||||||
{
|
{
|
||||||
data = other.data;
|
data = other.data;
|
||||||
data->parents++;
|
|
||||||
other.data = nullptr;
|
other.data = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractFieldPhrase::~AbstractFieldPhrase()
|
AbstractFieldPhrase::~AbstractFieldPhrase()
|
||||||
{
|
{
|
||||||
if (data) {
|
if (data) {
|
||||||
--data->parents;
|
if (!data->ref.deref()) {
|
||||||
if (data->parents <= 0)
|
// qDebug() << "deleted" << data->className
|
||||||
|
// << data->fieldName;
|
||||||
delete data;
|
delete data;
|
||||||
|
}
|
||||||
|
// else
|
||||||
|
// qDebug() << "more parents for" << data->className
|
||||||
|
// << data->fieldName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -87,6 +92,14 @@ AssignmentPhrase AbstractFieldPhrase::operator <<(const QVariant &other)
|
||||||
return AssignmentPhrase(this, other);
|
return AssignmentPhrase(this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractFieldPhrase::detach()
|
||||||
|
{
|
||||||
|
auto clone = data->clone();
|
||||||
|
if (!data->ref.deref())
|
||||||
|
delete data;
|
||||||
|
data = clone;
|
||||||
|
}
|
||||||
|
|
||||||
#define AbstractFieldPhraseOperatorVariant(class, op, cond) \
|
#define AbstractFieldPhraseOperatorVariant(class, op, cond) \
|
||||||
ConditionalPhrase class::operator op(const QVariant &other) \
|
ConditionalPhrase class::operator op(const QVariant &other) \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -118,7 +131,7 @@ AbstractFieldPhrase AbstractFieldPhrase::operator ~()
|
||||||
|
|
||||||
AbstractFieldPhrase AbstractFieldPhrase::operator !()
|
AbstractFieldPhrase AbstractFieldPhrase::operator !()
|
||||||
{
|
{
|
||||||
AbstractFieldPhrase f(data->className, data->fieldName);
|
AbstractFieldPhrase f(data->clone());
|
||||||
f.data->isNot = !data->isNot;
|
f.data->isNot = !data->isNot;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
@ -21,11 +21,10 @@
|
||||||
#ifndef ABSTRACTFIELDPHRASE_H
|
#ifndef ABSTRACTFIELDPHRASE_H
|
||||||
#define ABSTRACTFIELDPHRASE_H
|
#define ABSTRACTFIELDPHRASE_H
|
||||||
|
|
||||||
#include "../defines.h"
|
#include <QtNut/nut_global.h>
|
||||||
|
#include <QtNut/assignmentphrase.h>
|
||||||
#include "assignmentphrase.h"
|
#include <QtNut/conditionalphrase.h>
|
||||||
#include "conditionalphrase.h"
|
#include <QtNut/phraselist.h>
|
||||||
#include "phraselist.h"
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -47,7 +46,7 @@ public:
|
||||||
ConditionalPhrase in(QList<T> list)
|
ConditionalPhrase in(QList<T> list)
|
||||||
{
|
{
|
||||||
QVariantList vlist;
|
QVariantList vlist;
|
||||||
foreach (T t, list)
|
Q_FOREACH (T t, list)
|
||||||
vlist.append(QVariant::fromValue(t));
|
vlist.append(QVariant::fromValue(t));
|
||||||
|
|
||||||
return ConditionalPhrase(this, PhraseData::In, vlist);
|
return ConditionalPhrase(this, PhraseData::In, vlist);
|
||||||
|
|
@ -81,6 +80,9 @@ public:
|
||||||
AssignmentPhrase operator =(const QVariant &other);
|
AssignmentPhrase operator =(const QVariant &other);
|
||||||
AssignmentPhrase operator =(const ConditionalPhrase &other);
|
AssignmentPhrase operator =(const ConditionalPhrase &other);
|
||||||
AssignmentPhrase operator <<(const QVariant &other);
|
AssignmentPhrase operator <<(const QVariant &other);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void detach();
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -26,7 +26,7 @@ NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
AssignmentPhrase::AssignmentPhrase(PhraseData *d) : data(d)
|
AssignmentPhrase::AssignmentPhrase(PhraseData *d) : data(d)
|
||||||
{
|
{
|
||||||
d->parents++;
|
d->ref.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const QVariant r)
|
AssignmentPhrase::AssignmentPhrase(AbstractFieldPhrase *l, const QVariant r)
|
||||||
|
|
@ -56,9 +56,8 @@ AssignmentPhrase::AssignmentPhrase(AssignmentPhrase *ph, const QVariant &v)
|
||||||
|
|
||||||
AssignmentPhrase::~AssignmentPhrase()
|
AssignmentPhrase::~AssignmentPhrase()
|
||||||
{
|
{
|
||||||
if (data)
|
if (data && data->ref.deref())
|
||||||
if (!--data->parents)
|
delete data;
|
||||||
delete data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -21,9 +21,8 @@
|
||||||
#ifndef ASSIGNMENTPHRASE_H
|
#ifndef ASSIGNMENTPHRASE_H
|
||||||
#define ASSIGNMENTPHRASE_H
|
#define ASSIGNMENTPHRASE_H
|
||||||
|
|
||||||
#include "../defines.h"
|
#include <QtNut/nut_global.h>
|
||||||
|
#include <QtNut/assignmentphraselist.h>
|
||||||
#include "assignmentphraselist.h"
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -68,17 +68,17 @@ AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase
|
||||||
|
|
||||||
AssignmentPhraseList::~AssignmentPhraseList()
|
AssignmentPhraseList::~AssignmentPhraseList()
|
||||||
{
|
{
|
||||||
foreach (PhraseData *d, data)
|
// Q_FOREACH (PhraseData *d, data)
|
||||||
if (!--d->parents)
|
// if (!d->ref.deref())
|
||||||
delete d;
|
// delete d;
|
||||||
// qDeleteAll(data);
|
// qDeleteAll(data);
|
||||||
// data.clear();
|
// data.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignmentPhraseList::incAllDataParents()
|
void AssignmentPhraseList::incAllDataParents()
|
||||||
{
|
{
|
||||||
foreach (PhraseData *d, data)
|
Q_FOREACH (PhraseData *d, data)
|
||||||
d->parents++;
|
d->ref.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#ifndef ASSIGNMENTPHRASELIST_H
|
#ifndef ASSIGNMENTPHRASELIST_H
|
||||||
#define ASSIGNMENTPHRASELIST_H
|
#define ASSIGNMENTPHRASELIST_H
|
||||||
|
|
||||||
#include "../defines.h"
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -18,6 +18,8 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
#include "abstractfieldphrase.h"
|
#include "abstractfieldphrase.h"
|
||||||
#include "conditionalphrase.h"
|
#include "conditionalphrase.h"
|
||||||
#include "phrasedata.h"
|
#include "phrasedata.h"
|
||||||
|
|
@ -30,21 +32,21 @@ ConditionalPhrase::ConditionalPhrase() : data(nullptr)
|
||||||
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other)
|
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other)
|
||||||
{
|
{
|
||||||
data = other.data;
|
data = other.data;
|
||||||
data->parents++;
|
data->ref.ref();
|
||||||
// const_cast<ConditionalPhrase&>(other).data = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef Q_COMPILER_RVALUE_REFS
|
#ifdef Q_COMPILER_RVALUE_REFS
|
||||||
ConditionalPhrase::ConditionalPhrase(ConditionalPhrase &&other)
|
ConditionalPhrase::ConditionalPhrase(ConditionalPhrase &&other)
|
||||||
{
|
{
|
||||||
this->data = qMove(other.data);
|
data = other.data;
|
||||||
|
other.data = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ConditionalPhrase::ConditionalPhrase(const PhraseData *data)
|
ConditionalPhrase::ConditionalPhrase(const PhraseData *data)
|
||||||
{
|
{
|
||||||
this->data = const_cast<PhraseData*>(data);
|
data = const_cast<PhraseData*>(data);
|
||||||
this->data->parents++;
|
data->ref.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l,
|
ConditionalPhrase::ConditionalPhrase(AbstractFieldPhrase *l,
|
||||||
|
|
@ -104,8 +106,10 @@ ConditionalPhrase::~ConditionalPhrase()
|
||||||
{
|
{
|
||||||
if (data) {
|
if (data) {
|
||||||
data->cleanUp();
|
data->cleanUp();
|
||||||
if (!--data->parents)
|
if (!data->ref.deref()) {
|
||||||
|
// qDebug() << "deleted for cond";
|
||||||
delete data;
|
delete data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,7 +117,7 @@ ConditionalPhrase &ConditionalPhrase::operator =(const ConditionalPhrase &other)
|
||||||
{
|
{
|
||||||
data = other.data;
|
data = other.data;
|
||||||
if (data)
|
if (data)
|
||||||
data->parents++;
|
data->ref.ref();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,23 +126,6 @@ ConditionalPhrase ConditionalPhrase::operator ==(const QVariant &other)
|
||||||
return ConditionalPhrase(this, PhraseData::Equal, other);
|
return ConditionalPhrase(this, PhraseData::Equal, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
//ConditionalPhrase ConditionalPhrase::operator ==(const AbstractFieldPhrase &other)
|
|
||||||
//{
|
|
||||||
// return ConditionalPhrase(this, PhraseData::Equal, other);
|
|
||||||
//}
|
|
||||||
|
|
||||||
//ConditionalPhrase ConditionalPhrase::operator &&(const ConditionalPhrase &other)
|
|
||||||
//{
|
|
||||||
// return ConditionalPhrase(this, PhraseData::And,
|
|
||||||
// const_cast<ConditionalPhrase&>(other));
|
|
||||||
//}
|
|
||||||
|
|
||||||
//ConditionalPhrase ConditionalPhrase::operator ||(const ConditionalPhrase &other)
|
|
||||||
//{
|
|
||||||
// return ConditionalPhrase(this, PhraseData::Or,
|
|
||||||
// const_cast<ConditionalPhrase&>(other));
|
|
||||||
//}
|
|
||||||
|
|
||||||
#define DECLARE_CONDITIONALPHRASE_OPERATORS_IMPL(op, cond) \
|
#define DECLARE_CONDITIONALPHRASE_OPERATORS_IMPL(op, cond) \
|
||||||
ConditionalPhrase operator op(const ConditionalPhrase &l, \
|
ConditionalPhrase operator op(const ConditionalPhrase &l, \
|
||||||
const ConditionalPhrase &r) \
|
const ConditionalPhrase &r) \
|
||||||
|
|
@ -149,8 +136,8 @@ ConditionalPhrase operator op(const ConditionalPhrase &l, \
|
||||||
p.data->operatorCond = cond; \
|
p.data->operatorCond = cond; \
|
||||||
p.data->left = l.data; \
|
p.data->left = l.data; \
|
||||||
p.data->right = r.data; \
|
p.data->right = r.data; \
|
||||||
l.data->parents++; \
|
l.data->ref.ref(); \
|
||||||
r.data->parents++; \
|
r.data->ref.ref(); \
|
||||||
return p; \
|
return p; \
|
||||||
} \
|
} \
|
||||||
ConditionalPhrase operator op(const ConditionalPhrase &l, \
|
ConditionalPhrase operator op(const ConditionalPhrase &l, \
|
||||||
|
|
@ -162,8 +149,8 @@ ConditionalPhrase operator op(const ConditionalPhrase &l, \
|
||||||
p.data->operatorCond = cond; \
|
p.data->operatorCond = cond; \
|
||||||
p.data->left = l.data; \
|
p.data->left = l.data; \
|
||||||
p.data->right = r.data; \
|
p.data->right = r.data; \
|
||||||
l.data->parents++; \
|
l.data->ref.ref(); \
|
||||||
r.data->parents++; \
|
r.data = nullptr; \
|
||||||
return p; \
|
return p; \
|
||||||
} \
|
} \
|
||||||
ConditionalPhrase operator op(ConditionalPhrase &&l, \
|
ConditionalPhrase operator op(ConditionalPhrase &&l, \
|
||||||
|
|
@ -175,8 +162,8 @@ ConditionalPhrase operator op(ConditionalPhrase &&l, \
|
||||||
p.data->operatorCond = cond; \
|
p.data->operatorCond = cond; \
|
||||||
p.data->left = l.data; \
|
p.data->left = l.data; \
|
||||||
p.data->right = r.data; \
|
p.data->right = r.data; \
|
||||||
l.data->parents++; \
|
r.data->ref.ref(); \
|
||||||
r.data->parents++; \
|
l.data = nullptr; \
|
||||||
return p; \
|
return p; \
|
||||||
} \
|
} \
|
||||||
ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r) \
|
ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r) \
|
||||||
|
|
@ -187,8 +174,8 @@ ConditionalPhrase operator op(ConditionalPhrase &&l, ConditionalPhrase &&r) \
|
||||||
p.data->operatorCond = cond; \
|
p.data->operatorCond = cond; \
|
||||||
p.data->left = l.data; \
|
p.data->left = l.data; \
|
||||||
p.data->right = r.data; \
|
p.data->right = r.data; \
|
||||||
l.data->parents++; \
|
l.data = nullptr; \
|
||||||
r.data->parents++; \
|
r.data = nullptr; \
|
||||||
return p; \
|
return p; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -198,8 +185,9 @@ DECLARE_CONDITIONALPHRASE_OPERATORS_IMPL(&&, PhraseData::And)
|
||||||
|
|
||||||
ConditionalPhrase ConditionalPhrase::operator !()
|
ConditionalPhrase ConditionalPhrase::operator !()
|
||||||
{
|
{
|
||||||
ConditionalPhrase f(data);
|
ConditionalPhrase f;
|
||||||
f.data->isNot = !data->isNot;
|
f.data = data->clone();
|
||||||
|
f.data->isNot = !f.data->isNot;
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
#ifndef CONDITIONALPHRASE_H
|
#ifndef CONDITIONALPHRASE_H
|
||||||
#define CONDITIONALPHRASE_H
|
#define CONDITIONALPHRASE_H
|
||||||
|
|
||||||
#include "phrasedata.h"
|
#include <QtNut/phrasedata.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -21,9 +21,8 @@
|
||||||
#ifndef FIELDPHRASE_H
|
#ifndef FIELDPHRASE_H
|
||||||
#define FIELDPHRASE_H
|
#define FIELDPHRASE_H
|
||||||
|
|
||||||
#include "../defines.h"
|
#include <QtNut/nut_global.h>
|
||||||
|
#include <QtNut/abstractfieldphrase.h>
|
||||||
#include "abstractfieldphrase.h"
|
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -51,28 +50,6 @@ Q_OUTOFLINE_TEMPLATE ConditionalPhrase FieldPhrase<T>::operator ==(const QVarian
|
||||||
return ConditionalPhrase(this, PhraseData::Equal, other);
|
return ConditionalPhrase(this, PhraseData::Equal, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<>
|
|
||||||
class FieldPhrase<QString> : public AbstractFieldPhrase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FieldPhrase(const char *className, const char *s) :
|
|
||||||
AbstractFieldPhrase(className, s)
|
|
||||||
{}
|
|
||||||
|
|
||||||
ConditionalPhrase like(const QString &term) {
|
|
||||||
return ConditionalPhrase(this, PhraseData::Like, term);
|
|
||||||
}
|
|
||||||
|
|
||||||
ConditionalPhrase contains(const QString &term) {
|
|
||||||
return ConditionalPhrase(this, PhraseData::Like, "%" + term + "%");
|
|
||||||
}
|
|
||||||
|
|
||||||
AssignmentPhrase operator =(const QVariant &v) {
|
|
||||||
return AssignmentPhrase(this, v);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
//Date and time
|
//Date and time
|
||||||
#define CONDITIONAL_VARIANT_METHOD(name, cond) \
|
#define CONDITIONAL_VARIANT_METHOD(name, cond) \
|
||||||
ConditionalPhrase name(int val) \
|
ConditionalPhrase name(int val) \
|
||||||
|
|
@ -80,31 +57,6 @@ public:
|
||||||
return ConditionalPhrase(this, cond, val); \
|
return ConditionalPhrase(this, cond, val); \
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
|
||||||
class FieldPhrase<bool> : public AbstractFieldPhrase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FieldPhrase(const char *className, const char *s) :
|
|
||||||
AbstractFieldPhrase(className, s)
|
|
||||||
{}
|
|
||||||
|
|
||||||
AssignmentPhrase operator =(const bool &other) {
|
|
||||||
return AssignmentPhrase(this, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
FieldPhrase<bool> operator !()
|
|
||||||
{
|
|
||||||
FieldPhrase<bool> f(data->className, data->fieldName);
|
|
||||||
// f.data = new PhraseData(data);
|
|
||||||
f.data->isNot = !data->isNot;
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
operator ConditionalPhrase()
|
|
||||||
{
|
|
||||||
return ConditionalPhrase(this, PhraseData::Equal, !data->isNot);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include "fieldphrase_bool.h"
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef NUT_FIELDPHRASE_BOOL_H
|
||||||
|
#define NUT_FIELDPHRASE_BOOL_H
|
||||||
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
#include <QtNut/fieldphrase.h>
|
||||||
|
#include <QtNut/fieldphrase.h>
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class FieldPhrase<bool> : public AbstractFieldPhrase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FieldPhrase(const char *className, const char *s) :
|
||||||
|
AbstractFieldPhrase(className, s)
|
||||||
|
{}
|
||||||
|
|
||||||
|
AssignmentPhrase operator =(const bool &other) {
|
||||||
|
return AssignmentPhrase(this, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
FieldPhrase<bool> operator !()
|
||||||
|
{
|
||||||
|
FieldPhrase<bool> f(data->className, data->fieldName);
|
||||||
|
// f.data = new PhraseData(data);
|
||||||
|
f.data->isNot = !data->isNot;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator ConditionalPhrase()
|
||||||
|
{
|
||||||
|
return ConditionalPhrase(this, PhraseData::Equal, !data->isNot);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // NUT_FIELDPHRASE_BOOL_H
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "datephrase.h"
|
#include "fieldphrase_date.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -21,10 +21,11 @@
|
||||||
#ifndef DATEPHRASE_H
|
#ifndef DATEPHRASE_H
|
||||||
#define DATEPHRASE_H
|
#define DATEPHRASE_H
|
||||||
|
|
||||||
#include "fieldphrase.h"
|
#include <QtCore/QDateTime>
|
||||||
#include <QDateTime>
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include <QtNut/fieldphrase.h>
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#define COMMON_OPERATORS_DECL(T) \
|
#define COMMON_OPERATORS_DECL(T) \
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
#include "fieldphrase_qstring.h"
|
||||||
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
#ifndef NUT_FIELDPHRASE_QSTRING_H
|
||||||
|
#define NUT_FIELDPHRASE_QSTRING_H
|
||||||
|
|
||||||
|
#include <QtNut/nut_global.h>
|
||||||
|
#include <QtNut/abstractfieldphrase.h>
|
||||||
|
#include <QtNut/fieldphrase.h>
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class FieldPhrase<QString> : public AbstractFieldPhrase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FieldPhrase(const char *className, const char *s)
|
||||||
|
: AbstractFieldPhrase(className, s)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ConditionalPhrase like(const QString &term)
|
||||||
|
{
|
||||||
|
return ConditionalPhrase(this, PhraseData::Like, term);
|
||||||
|
}
|
||||||
|
|
||||||
|
ConditionalPhrase contains(const QString &term)
|
||||||
|
{
|
||||||
|
return ConditionalPhrase(this,
|
||||||
|
PhraseData::Like,
|
||||||
|
QVariant(QStringLiteral("%") + term
|
||||||
|
+ QStringLiteral("%")));
|
||||||
|
}
|
||||||
|
|
||||||
|
AssignmentPhrase operator=(const QVariant &v)
|
||||||
|
{
|
||||||
|
return AssignmentPhrase(this, v);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // NUT_FIELDPHRASE_QSTRING_H
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue