parent
8fa6a3b6d7
commit
ad6eab9de1
|
|
@ -0,0 +1 @@
|
||||||
|
set(QT_REPO_MODULE_VERSION "0.7.0")
|
||||||
|
|
@ -1,90 +1,158 @@
|
||||||
name: CI build
|
name: CI Build
|
||||||
|
|
||||||
on: [push]
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- "releases/**"
|
||||||
|
paths-ignore:
|
||||||
|
- "**.md"
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- "**.md"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
version:
|
qt_version: [5.12.11, 5.15.2, 6.2.0]
|
||||||
- 5.15.0
|
platform: [ubuntu-20.04, windows-latest, macos-latest]
|
||||||
|
|
||||||
platform:
|
|
||||||
- gcc_64
|
|
||||||
- android
|
|
||||||
- msvc2019
|
|
||||||
- msvc2019_64
|
|
||||||
- winrt_x64_msvc2019
|
|
||||||
- winrt_x86_msvc2019
|
|
||||||
- winrt_armv7_msvc2019
|
|
||||||
- mingw81_64
|
|
||||||
- mingw81_32
|
|
||||||
- clang_64
|
|
||||||
- ios
|
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- platform: gcc_64
|
- qt_version: 6.2.0
|
||||||
os: ubuntu-latest
|
additional_arguments: -D QT_DEFAULT_MAJOR_VERSION=6
|
||||||
- platform: android
|
build_cmake: true
|
||||||
os: ubuntu-latest
|
- platform: ubuntu-20.04
|
||||||
- platform: msvc2019_64
|
make: make
|
||||||
os: windows-latest
|
#CXXFLAGS: -Wall -Wextra
|
||||||
- platform: msvc2019
|
MAKEFLAGS: -j2
|
||||||
os: windows-latest
|
- platform: macos-latest
|
||||||
- platform: winrt_x64_msvc2019
|
make: make
|
||||||
os: windows-latest
|
#CXXFLAGS: -Wall -Wextra
|
||||||
- platform: winrt_x86_msvc2019
|
MAKEFLAGS: -j3
|
||||||
os: windows-latest
|
- platform: windows-latest
|
||||||
- platform: winrt_armv7_msvc2019
|
make: nmake
|
||||||
os: windows-latest
|
QMAKE_MSC_VER: 16.11.31911.196
|
||||||
- platform: mingw81_64
|
cmake_params: -D CMAKE_CXX_FLAGS_DEBUG="/g"
|
||||||
os: windows-latest
|
- platform: ubuntu-20.04
|
||||||
- platform: mingw81_32
|
tests: [sqlite, posgtresql]
|
||||||
os: windows-latest
|
- platform: ubuntu-20.04
|
||||||
- platform: clang_64
|
qt_version: system
|
||||||
os: macos-latest
|
tests: [sqlite, posgtresql, mysql]
|
||||||
|
make: make
|
||||||
|
name: ubuntu-20.04, system
|
||||||
|
- platform: windows-latest
|
||||||
|
qt_version: 5.15.2
|
||||||
|
tests: [mssql]
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.platform }}
|
||||||
|
name: ${{ matrix.platform }} - Qt ${{ matrix.qt_version }}
|
||||||
|
|
||||||
|
env:
|
||||||
|
CXXFLAGS: ${{ matrix.CXXFLAGS }}
|
||||||
|
MAKEFLAGS: ${{ matrix.MAKEFLAGS }}
|
||||||
|
QMAKE_MSC_VER: ${{ matrix.QMAKE_MSC_VER }}
|
||||||
|
CMAKE_PREFIX_PATH: $Qt6_DIR/lib/cmake
|
||||||
|
CMAKE_CXX_FLAGS_DEBUG: ${{ matrix.CMAKE_CXX_FLAGS_DEBUG }}
|
||||||
|
|
||||||
runs-on: ${{matrix.os}}
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- name: Clone repo
|
||||||
|
uses: actions/checkout@v2.3.4
|
||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
- uses: actions/setup-python@v1
|
|
||||||
- uses: Skycoder42/action-setup-qt@master
|
- name: Install Qt
|
||||||
id: qt
|
if: matrix.qt_version != 'system'
|
||||||
|
uses: jurplel/install-qt-action@v2.14.0
|
||||||
with:
|
with:
|
||||||
version: ${{matrix.version}}
|
version: ${{ matrix.qt_version }}
|
||||||
platform: ${{matrix.platform}}
|
|
||||||
packages: qt.tools.ifw.32
|
- name: Install Qt from package manager
|
||||||
- name: qmake
|
if: matrix.qt_version == 'system'
|
||||||
run: |
|
run: |
|
||||||
qmake CONFIG+=install_ok QT_PLATFORM=${{matrix.platform}} "QT_TOOL_PATH=${{steps.qt.outputs.qtdir}}/Tools" nut.pro
|
sudo apt install qt5-default qt5-qmake qt5-qmake-bin libqt5core5a libqt5gui5 libqt5sql5 libqt5sql5-psql libqt5sql5-mysql libqt5sql5-sqlite
|
||||||
${{steps.qt.outputs.make}} qmake_all
|
|
||||||
- name: make module
|
- name: Setup MSVC environment for QMake
|
||||||
run: |
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
${{steps.qt.outputs.make}}
|
|
||||||
${{steps.qt.outputs.make}} INSTALL_ROOT="${{steps.qt.outputs.installdir}}" install
|
|
||||||
- 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
|
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
|
||||||
with:
|
with:
|
||||||
repo_token: ${{secrets.GITHUB_TOKEN}}
|
uwp: false
|
||||||
directory: ${{steps.qt.outputs.outdir}}
|
|
||||||
platform: ${{matrix.platform}}
|
- name: Build with QMake
|
||||||
asset_name: nut-${{matrix.platform}}-${{matrix.version}}
|
run: |
|
||||||
tag: ${{github.ref}}
|
mkdir build-qmake
|
||||||
overwrite: true
|
cd build-qmake
|
||||||
|
qmake ../nut.pro
|
||||||
|
${{ matrix.make }} qmake_all
|
||||||
|
${{ matrix.make }}
|
||||||
|
|
||||||
|
- name: Build with CMake
|
||||||
|
if: startsWith(matrix.qt_version, '6.')
|
||||||
|
run: |
|
||||||
|
mkdir build-cmake
|
||||||
|
cd build-cmake
|
||||||
|
cmake .. ${{ matrix.additional_arguments }} ${{ matrix.cmake_params }}
|
||||||
|
cmake --build .
|
||||||
|
|
||||||
|
- name: Seutp postgres
|
||||||
|
if: contains(matrix.tests, 'posgtresql')
|
||||||
|
uses: ikalnytskyi/action-setup-postgres@v1
|
||||||
|
|
||||||
|
- name: Setup sql server
|
||||||
|
if: contains(matrix.tests, 'mssql')
|
||||||
|
uses: potatoqualitee/mssqlsuite@v1
|
||||||
|
with:
|
||||||
|
install: sqlengine
|
||||||
|
sa-password: NUT_sa_PASS_1_???
|
||||||
|
show-log: true
|
||||||
|
|
||||||
|
- name: Check sql server
|
||||||
|
if: contains(matrix.tests, 'mssql')
|
||||||
|
run: sqlcmd -S localhost -U sa -P NUT_sa_PASS_1_??? -d tempdb -Q "SELECT @@version;"
|
||||||
|
|
||||||
|
- name: Run tests with sqlite
|
||||||
|
if: contains(matrix.tests, 'sqlite')
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
rm tests/auto/common/test_params.h
|
||||||
|
cp tests/auto/common/test_params_sqlite.h tests/auto/common/test_params.h
|
||||||
|
cd build-qmake
|
||||||
|
${{ matrix.make }} all
|
||||||
|
${{ matrix.make }} run-tests
|
||||||
|
|
||||||
|
- name: Run tests with posgtresql
|
||||||
|
if: contains(matrix.tests, 'posgtresql')
|
||||||
|
#continue-on-error: true
|
||||||
|
run: |
|
||||||
|
rm tests/auto/common/test_params.h
|
||||||
|
cp tests/auto/common/test_params_postgresql.h tests/auto/common/test_params.h
|
||||||
|
cd build-qmake
|
||||||
|
${{ matrix.make }} all
|
||||||
|
${{ matrix.make }} run-tests
|
||||||
|
|
||||||
|
- name: Run tests with mysql
|
||||||
|
if: contains(matrix.tests, 'mysql')
|
||||||
|
#continue-on-error: true
|
||||||
|
run: |
|
||||||
|
sudo systemctl start mysql.service
|
||||||
|
rm tests/auto/common/test_params.h
|
||||||
|
cp tests/auto/common/test_params_mysql.h tests/auto/common/test_params.h
|
||||||
|
cd build-qmake
|
||||||
|
${{ matrix.make }} all
|
||||||
|
${{ matrix.make }} run-tests
|
||||||
|
|
||||||
|
- name: Run tests with sql server
|
||||||
|
if: contains(matrix.tests, 'mssql')
|
||||||
|
continue-on-error: true
|
||||||
|
run: |
|
||||||
|
rm tests/auto/common/test_params.h
|
||||||
|
cp tests/auto/common/test_params_mssql.h tests/auto/common/test_params.h
|
||||||
|
cd build-qmake
|
||||||
|
${{ matrix.make }} all
|
||||||
|
${{ matrix.make }} run-tests
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
if: startsWith(github.ref, 'refs/tags/')
|
if: startsWith(github.ref, 'refs/tags/')
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-20.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
with:
|
with:
|
||||||
|
|
@ -94,7 +162,7 @@ jobs:
|
||||||
- uses: Skycoder42/action-deploy-qt@master
|
- uses: Skycoder42/action-deploy-qt@master
|
||||||
with:
|
with:
|
||||||
token: ${{secrets.GITHUB_TOKEN}}
|
token: ${{secrets.GITHUB_TOKEN}}
|
||||||
version: 5.15.0
|
version: 5.15.2
|
||||||
host: ${{secrets.SSHFS_HOST}}
|
host: ${{secrets.SSHFS_HOST}}
|
||||||
key: ${{secrets.SSHFS_KEY}}
|
key: ${{secrets.SSHFS_KEY}}
|
||||||
port: ${{secrets.SSHFS_PORT}}
|
port: ${{secrets.SSHFS_PORT}}
|
||||||
|
|
|
||||||
|
|
@ -54,3 +54,4 @@ test/tst_quuid/tst_uuid*
|
||||||
test/tst_upgrades/tst_upgrades*
|
test/tst_upgrades/tst_upgrades*
|
||||||
|
|
||||||
.idea
|
.idea
|
||||||
|
CMakeLists.txt.user
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
[submodule "src/nut/3rdparty/serializer"]
|
|
||||||
path = src/nut/3rdparty/serializer
|
|
||||||
url = https://github.com/HamedMasafi/Serializer.git
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
# Generated from nut.pro.
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
set(CMAKE_AUTOMOC ON)
|
||||||
|
|
||||||
|
include(.cmake.conf)
|
||||||
|
project(Nut
|
||||||
|
VERSION "0.7.0"
|
||||||
|
DESCRIPTION "Nut"
|
||||||
|
HOMEPAGE_URL "https://github.com/HamedMasafi/Nut"
|
||||||
|
LANGUAGES CXX C
|
||||||
|
)
|
||||||
|
|
||||||
|
set(PROJECT_VERSION_MAJOR, 0)
|
||||||
|
set(PROJECT_VERSION_MINOR, 7)
|
||||||
|
set(PROJECT_VERSION_PATCH, 0)
|
||||||
|
|
||||||
|
find_package(Qt6 CONFIG REQUIRED COMPONENTS BuildInternals Core Gui Sql)
|
||||||
|
|
||||||
|
qt_build_repo()
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
Database class must inherits from Nut::Database class.
|
Database class must inherit from Nut::Database class.
|
||||||
Database class can have NUT_DB_VERSION for declaring version number, version will be stored in database if upgrade needed.
|
Database class can have NUT_DB_VERSION for declaring version number, version will be stored in database if upgrade needed.
|
||||||
```cpp
|
```cpp
|
||||||
NUT_DB_VERSION(major, minor)
|
NUT_DB_VERSION(major, minor)
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ auto posts = db.posts().query()
|
||||||
->orderBy(Post::idField())
|
->orderBy(Post::idField())
|
||||||
->toList();
|
->toList();
|
||||||
```
|
```
|
||||||
Also you can sort descending by adding **!** to field name
|
Also, you can sort descending by adding **!** to field name
|
||||||
```cpp
|
```cpp
|
||||||
auto posts = db.posts().query()
|
auto posts = db.posts().query()
|
||||||
->where(Post::idField() == 1)
|
->where(Post::idField() == 1)
|
||||||
|
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
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
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Generated from src.pro.
|
||||||
|
|
||||||
|
add_subdirectory(nut)
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
Subproject commit 535778e15d30ef51b53e80d47630bef4ca20f4c7
|
|
||||||
|
|
@ -0,0 +1,65 @@
|
||||||
|
# Generated from nut.pro.
|
||||||
|
|
||||||
|
#####################################################################
|
||||||
|
## Nut Module:
|
||||||
|
#####################################################################
|
||||||
|
|
||||||
|
qt_internal_add_module(Nut
|
||||||
|
SOURCES
|
||||||
|
config/nut_config.h
|
||||||
|
config/nut_consts.h
|
||||||
|
config/nut_global.h
|
||||||
|
config/nut_macros.h
|
||||||
|
config/nut_namespace.h
|
||||||
|
core/abstracttableset.cpp core/abstracttableset.h
|
||||||
|
core/abstracttablesetdata.h
|
||||||
|
core/bulkinserter.cpp core/bulkinserter.h core/bulkinserter_p.h
|
||||||
|
core/changelogtable.cpp core/changelogtable.h
|
||||||
|
core/database.cpp core/database.h core/database_p.h
|
||||||
|
core/foreigncontainer.cpp core/foreigncontainer.h
|
||||||
|
core/propertysignalmapper.cpp core/propertysignalmapper.h
|
||||||
|
core/query.cpp core/query.h
|
||||||
|
core/table.cpp core/table.h core/table_p.h
|
||||||
|
core/tableset.cpp core/tableset.h
|
||||||
|
core/sqlserializer.cpp core/sqlserializer.h
|
||||||
|
generators/abstractsqlgenerator.cpp generators/abstractsqlgenerator.h
|
||||||
|
generators/mysqlgenerator.cpp generators/mysqlgenerator.h
|
||||||
|
generators/postgresqlgenerator.cpp generators/postgresqlgenerator.h
|
||||||
|
generators/sqlitegenerator.cpp generators/sqlitegenerator.h
|
||||||
|
generators/sqlservergenerator.cpp generators/sqlservergenerator.h
|
||||||
|
models/databasemodel.cpp models/databasemodel.h
|
||||||
|
models/sqlmodel.cpp models/sqlmodel.h models/sqlmodel_p.h
|
||||||
|
models/tablemodel.cpp models/tablemodel.h
|
||||||
|
phrase.cpp phrase.h
|
||||||
|
phrases/abstractfieldphrase.cpp phrases/abstractfieldphrase.h
|
||||||
|
phrases/assignmentphrase.cpp phrases/assignmentphrase.h
|
||||||
|
phrases/assignmentphraselist.cpp phrases/assignmentphraselist.h
|
||||||
|
phrases/conditionalphrase.cpp phrases/conditionalphrase.h
|
||||||
|
phrases/fieldphrase.cpp phrases/fieldphrase.h
|
||||||
|
phrases/fieldphrase_bool.cpp phrases/fieldphrase_bool.h
|
||||||
|
phrases/fieldphrase_date.cpp phrases/fieldphrase_date.h
|
||||||
|
phrases/fieldphrase_qstring.cpp phrases/fieldphrase_qstring.h
|
||||||
|
phrases/phrasedata.cpp phrases/phrasedata.h
|
||||||
|
phrases/phrasedatalist.cpp phrases/phrasedatalist.h
|
||||||
|
phrases/phraselist.cpp phrases/phraselist.h
|
||||||
|
types/dbgeography.cpp types/dbgeography.h
|
||||||
|
DEFINES
|
||||||
|
NUT_BUILD_LIB
|
||||||
|
NUT_SHARED
|
||||||
|
NUT_SHARED_POINTER
|
||||||
|
QT_DEPRECATED_WARNINGS
|
||||||
|
INCLUDE_DIRECTORIES
|
||||||
|
config
|
||||||
|
core
|
||||||
|
generators
|
||||||
|
models
|
||||||
|
phrases
|
||||||
|
types
|
||||||
|
PUBLIC_LIBRARIES
|
||||||
|
Qt::Core
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Sql
|
||||||
|
)
|
||||||
|
|
||||||
|
#### Keys ignored in scope 1:.:.:nut.pro:<TRUE>:
|
||||||
|
# MODULE = "nut"
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
#ifndef NUT_CONFIG_H
|
#ifndef NUT_CONFIG_H
|
||||||
#define NUT_CONFIG_H
|
#define NUT_CONFIG_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#if defined(NUT_SHARED) || !defined(NUT_STATIC)
|
#if defined(NUT_SHARED) || !defined(NUT_STATIC)
|
||||||
# ifdef NUT_STATIC
|
# ifdef NUT_STATIC
|
||||||
# error "Both NUT_SHARED and NUT_STATIC defined, please make up your mind"
|
# error "Both NUT_SHARED and NUT_STATIC defined, please make up your mind"
|
||||||
|
|
@ -17,4 +21,6 @@
|
||||||
# define NUT_EXPORT
|
# define NUT_EXPORT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_CONFIG_H
|
#endif // NUT_CONFIG_H
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,10 @@
|
||||||
#ifndef NUT_CONSTS_H
|
#ifndef NUT_CONSTS_H
|
||||||
#define NUT_CONSTS_H
|
#define NUT_CONSTS_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#define __NAME "name"
|
#define __NAME "name"
|
||||||
#define __TYPE "type"
|
#define __TYPE "type"
|
||||||
#define __FIELDS "fields"
|
#define __FIELDS "fields"
|
||||||
|
|
@ -46,6 +50,7 @@
|
||||||
#define __nut_REMOVE "remove"
|
#define __nut_REMOVE "remove"
|
||||||
#define __nut_CHANGE "change"
|
#define __nut_CHANGE "change"
|
||||||
|
|
||||||
|
#define NUT_NAMESPACE Nut
|
||||||
#ifdef NUT_NAMESPACE
|
#ifdef NUT_NAMESPACE
|
||||||
# define NUT_BEGIN_NAMESPACE namespace NUT_NAMESPACE{
|
# define NUT_BEGIN_NAMESPACE namespace NUT_NAMESPACE{
|
||||||
# define NUT_END_NAMESPACE }
|
# define NUT_END_NAMESPACE }
|
||||||
|
|
@ -56,4 +61,6 @@
|
||||||
# define NUT_WRAP_NAMESPACE(x) x
|
# define NUT_WRAP_NAMESPACE(x) x
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_CONSTS_H
|
#endif // NUT_CONSTS_H
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#ifndef NUT_GLOBAL_H
|
#ifndef NUT_GLOBAL_H
|
||||||
#define NUT_GLOBAL_H
|
#define NUT_GLOBAL_H
|
||||||
|
|
||||||
#define NUT_NAMESPACE Nut
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#include <QtNut/nut_config.h>
|
#include <QtNut/nut_config.h>
|
||||||
#include <QtNut/nut_consts.h>
|
#include <QtNut/nut_consts.h>
|
||||||
|
|
@ -9,4 +11,6 @@
|
||||||
#include <QtNut/nut_macros.h>
|
#include <QtNut/nut_macros.h>
|
||||||
#include <QtNut/nut_namespace.h>
|
#include <QtNut/nut_namespace.h>
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_GLOBAL_H
|
#endif // NUT_GLOBAL_H
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
#ifndef NUT_MACROS_H
|
#ifndef NUT_MACROS_H
|
||||||
#define NUT_MACROS_H
|
#define NUT_MACROS_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#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, \
|
||||||
|
|
@ -17,127 +20,128 @@
|
||||||
#define NUT_DB_VERSION(version) \
|
#define NUT_DB_VERSION(version) \
|
||||||
NUT_INFO(__nut_DB_VERSION, version, 0)
|
NUT_INFO(__nut_DB_VERSION, version, 0)
|
||||||
|
|
||||||
#define NUT_DECLARE_TABLE(type, name) \
|
#define NUT_DECLARE_TABLE(type, name) \
|
||||||
NUT_INFO(__nut_TABLE, type, name) \
|
NUT_INFO(__nut_TABLE, type, name) \
|
||||||
Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet<type>) name READ name) \
|
Q_PROPERTY(NUT_WRAP_NAMESPACE(TableSet<type>) name READ name) \
|
||||||
NUT_WRAP_NAMESPACE(TableSet<type>) *m_##name; \
|
NUT_WRAP_NAMESPACE(TableSet<type>) * m_##name; \
|
||||||
public: \
|
\
|
||||||
static const type *_##name; \
|
public: \
|
||||||
NUT_WRAP_NAMESPACE(TableSet<type>) *name() const \
|
static const type *_##name; \
|
||||||
{ return m_##name; } \
|
NUT_WRAP_NAMESPACE(TableSet<type>) * name() const { return m_##name; } \
|
||||||
private:
|
\
|
||||||
|
private:
|
||||||
|
|
||||||
//Table
|
//Table
|
||||||
#define NUT_FIELD(type, name) \
|
#define NUT_FIELD(type, name) \
|
||||||
private: \
|
private: \
|
||||||
NUT_INFO(__nut_FIELD, name, 0) \
|
NUT_INFO(__nut_FIELD, name, 0) \
|
||||||
public: \
|
public: \
|
||||||
static NUT_WRAP_NAMESPACE(FieldPhrase<type>)& name ## Field(){ \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) & name##Field() \
|
||||||
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = \
|
{ \
|
||||||
NUT_WRAP_NAMESPACE(FieldPhrase<type>) \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = NUT_WRAP_NAMESPACE( \
|
||||||
(staticMetaObject.className(), #name); \
|
FieldPhrase<type>)(staticMetaObject.className(), #name); \
|
||||||
return f; \
|
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) \
|
||||||
type m_##name; \
|
type m_##name; \
|
||||||
public: \
|
\
|
||||||
static NUT_WRAP_NAMESPACE(FieldPhrase<type>)& name ## Field(){ \
|
public: \
|
||||||
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) & name##Field() \
|
||||||
NUT_WRAP_NAMESPACE(FieldPhrase<type>) \
|
{ \
|
||||||
(staticMetaObject.className(), #name); \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<type>) f = NUT_WRAP_NAMESPACE( \
|
||||||
return f; \
|
FieldPhrase<type>)(staticMetaObject.className(), #name); \
|
||||||
} \
|
return f; \
|
||||||
type read() const{ \
|
} \
|
||||||
return m_##name; \
|
type read() const { return m_##name; } \
|
||||||
} \
|
void write(type name) \
|
||||||
void write(type name){ \
|
{ \
|
||||||
m_##name = name; \
|
m_##name = name; \
|
||||||
propertyChanged(QString::fromUtf8(#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_WRAP_NAMESPACE(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_WRAP_NAMESPACE(Row<type>) m_##name; \
|
||||||
public Q_SLOTS: \
|
public Q_SLOTS: \
|
||||||
Nut::Row<type> read() const { return m_##name ; } \
|
NUT_WRAP_NAMESPACE(Row<type>) read() const { return m_##name; } \
|
||||||
Q_INVOKABLE void write(Nut::Row<type> name){ \
|
Q_INVOKABLE void write(NUT_WRAP_NAMESPACE(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_WRAP_NAMESPACE(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_WRAP_NAMESPACE(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_WRAP_NAMESPACE(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 = \
|
{ \
|
||||||
NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) \
|
static NUT_WRAP_NAMESPACE(FieldPhrase<keytype>) f = NUT_WRAP_NAMESPACE( \
|
||||||
(staticMetaObject.className(), #name "Id"); \
|
FieldPhrase<keytype>)(staticMetaObject.className(), #name "Id"); \
|
||||||
return f; \
|
return f; \
|
||||||
} \
|
} \
|
||||||
public : \
|
\
|
||||||
Q_INVOKABLE void write(Nut::Row<type> name); \
|
public: \
|
||||||
Q_INVOKABLE void write(Nut::Row<Nut::Table> name); \
|
Q_INVOKABLE void write(NUT_WRAP_NAMESPACE(Row<type>) name); \
|
||||||
|
Q_INVOKABLE void write(NUT_WRAP_NAMESPACE(Row<NUT_WRAP_NAMESPACE(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_WRAP_NAMESPACE(Row<type>) class ::read() const { return m_##name; } \
|
||||||
void class::write(Nut::Row<type> name){ \
|
void class ::write(NUT_WRAP_NAMESPACE(Row<type>) name) \
|
||||||
propertyChanged(QStringLiteral(QT_STRINGIFY2(name##Id))); \
|
{ \
|
||||||
m_##name = name; \
|
propertyChanged(QStringLiteral(QT_STRINGIFY2(name##Id))); \
|
||||||
m_##name##Id = name->primaryValue().value<keytype>(); \
|
m_##name = name; \
|
||||||
} \
|
m_##name##Id = name->primaryValue().value<keytype>(); \
|
||||||
void class::write(Nut::Row<Nut::Table> name){ \
|
} \
|
||||||
write(qSharedPointerDynamicCast<type>(name)); \
|
void class ::write(NUT_WRAP_NAMESPACE(Row<NUT_WRAP_NAMESPACE(Table)>) name) \
|
||||||
} keytype class::read##Id() const{ \
|
{ \
|
||||||
if (m_##name) \
|
write(qSharedPointerDynamicCast<type>(name)); \
|
||||||
return m_##name->primaryValue().value<keytype>(); \
|
} \
|
||||||
return m_##name##Id; \
|
keytype class ::read##Id() const \
|
||||||
} \
|
{ \
|
||||||
void class::write##Id(keytype name##Id){ \
|
if (m_##name) \
|
||||||
m_##name##Id = name##Id; \
|
return m_##name->primaryValue().value<keytype>(); \
|
||||||
m_##name = nullptr; \
|
return m_##name##Id; \
|
||||||
propertyChanged(QStringLiteral(QT_STRINGIFY2(name##Id))); \
|
} \
|
||||||
|
void class ::write##Id(keytype name##Id) \
|
||||||
|
{ \
|
||||||
|
m_##name##Id = name##Id; \
|
||||||
|
m_##name = nullptr; \
|
||||||
|
propertyChanged(QStringLiteral(QT_STRINGIFY2(name##Id))); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define NUT_DECLARE_CHILD_TABLE(type, n) \
|
||||||
|
private: \
|
||||||
|
NUT_WRAP_NAMESPACE(TableSet)<type> *m_##n; \
|
||||||
|
\
|
||||||
|
public: \
|
||||||
|
static type *n##Table(); \
|
||||||
|
NUT_WRAP_NAMESPACE(TableSet)<type> *n();
|
||||||
|
|
||||||
#define NUT_DECLARE_CHILD_TABLE(type, n) \
|
#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \
|
||||||
private: \
|
type *class ::n##Table() \
|
||||||
NUT_WRAP_NAMESPACE(TableSet)<type> *m_##n; \
|
{ \
|
||||||
public: \
|
static auto f = new type(); \
|
||||||
static type *n##Table(); \
|
return f; \
|
||||||
NUT_WRAP_NAMESPACE(TableSet)<type> *n();
|
} \
|
||||||
|
NUT_WRAP_NAMESPACE(TableSet)<type> *class ::n() { return m_##n; }
|
||||||
#define NUT_IMPLEMENT_CHILD_TABLE(class, type, n) \
|
|
||||||
type *class::n##Table(){ \
|
|
||||||
static auto f = new type(); \
|
|
||||||
return f; \
|
|
||||||
} \
|
|
||||||
NUT_WRAP_NAMESPACE(TableSet)<type> *class::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) \
|
||||||
public: \
|
NUT_INFO(__nut_PRIMARY_KEY, x, 0) \
|
||||||
QVariant primaryValue() const override { \
|
public: \
|
||||||
return property(#x); \
|
QVariant primaryValue() const override { return property(#x); } \
|
||||||
} \
|
void setPrimaryValue(const QVariant &value) override { setProperty(#x, value); } \
|
||||||
void setPrimaryValue(const QVariant &value) override { \
|
\
|
||||||
setProperty(#x, value); \
|
private:
|
||||||
} \
|
|
||||||
private:
|
|
||||||
|
|
||||||
|
|
||||||
#define NUT_AUTO_INCREMENT(x) NUT_INFO(__nut_AUTO_INCREMENT, x, 0)
|
#define NUT_AUTO_INCREMENT(x) NUT_INFO(__nut_AUTO_INCREMENT, x, 0)
|
||||||
#define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_INFO(__nut_PRIMARY_KEY_AI, x, 0)\
|
#define NUT_PRIMARY_AUTO_INCREMENT(x) NUT_INFO(__nut_PRIMARY_KEY_AI, x, 0)\
|
||||||
|
|
@ -149,4 +153,6 @@ public : \
|
||||||
#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)
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_MACROS_H
|
#endif // NUT_MACROS_H
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
#ifndef NUT_NAMESPACE_H
|
#ifndef NUT_NAMESPACE_H
|
||||||
#define NUT_NAMESPACE_H
|
#define NUT_NAMESPACE_H
|
||||||
|
|
||||||
#ifndef NUT_GLOBAL_H
|
|
||||||
# error "Do not include nut_namespace.h header directly!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//avoid ide warnings
|
//avoid ide warnings
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
|
@ -13,6 +9,8 @@
|
||||||
#include <QtCore/QVariant>
|
#include <QtCore/QVariant>
|
||||||
#include <QtCore/QMetaClassInfo>
|
#include <QtCore/QMetaClassInfo>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
inline bool nutClassInfo(const QMetaClassInfo &classInfo,
|
inline bool nutClassInfo(const QMetaClassInfo &classInfo,
|
||||||
|
|
@ -84,59 +82,77 @@ inline bool nutClassInfoInt(const QMetaClassInfo &classInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NUT_RAW_POINTER
|
#ifdef NUT_RAW_POINTER
|
||||||
template <typename T>
|
template<typename T>
|
||||||
using RowList = QList<T*>;
|
using RowList = QList<T *>;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using RowSet = QSet<T*>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using Row = T*;
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Row<T> create() {
|
using WeakRowList = 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;
|
return new T;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T *get(const Row<T> row) {
|
inline T *get(const Row<T> row)
|
||||||
|
{
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline T *get(const QSharedPointer<T> row) {
|
inline T *get(const QSharedPointer<T> row)
|
||||||
|
{
|
||||||
return row.data();
|
return row.data();
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template <class T>
|
template<class T>
|
||||||
using RowList = QList<QSharedPointer<T>>;
|
using RowList = QList<QSharedPointer<T>>;
|
||||||
|
|
||||||
template <class T>
|
template<class T>
|
||||||
using RowSet = QSet<QSharedPointer<T>>;
|
using WeakRowList = QList<QWeakPointer<T>>;
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using Row = QSharedPointer<T>;
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Row<T> create() {
|
using RowSet = QSet<QSharedPointer<T>>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using Row = QSharedPointer<T>;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
using WeakRow = QWeakPointer<T>;
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline Row<T> create()
|
||||||
|
{
|
||||||
return QSharedPointer<T>(new T);
|
return QSharedPointer<T>(new T);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Row<T> create(QObject *parent) {
|
inline Row<T> create(QObject *parent)
|
||||||
|
{
|
||||||
return QSharedPointer<T>(new T(parent));
|
return QSharedPointer<T>(new T(parent));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Row<T> createFrom(T *row) {
|
inline Row<T> createFrom(T *row)
|
||||||
|
{
|
||||||
return QSharedPointer<T>(row);
|
return QSharedPointer<T>(row);
|
||||||
}
|
}
|
||||||
template<class T>
|
template<class T>
|
||||||
inline Row<T> createFrom(const QSharedPointer<T> row) {
|
inline Row<T> createFrom(const QSharedPointer<T> row)
|
||||||
|
{
|
||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_NAMESPACE_H
|
#endif // NUT_NAMESPACE_H
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,16 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include <QWeakPointer>
|
||||||
|
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "abstracttableset.h"
|
#include "abstracttableset.h"
|
||||||
#include "databasemodel.h"
|
#include "databasemodel.h"
|
||||||
#include "abstracttablesetdata.h"
|
#include "abstracttablesetdata.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
AbstractTableSet::AbstractTableSet(Database *parent) : QObject(parent),
|
AbstractTableSet::AbstractTableSet(Database *parent) : QObject(parent),
|
||||||
|
|
@ -40,7 +44,7 @@ AbstractTableSet::AbstractTableSet(Table *parent) : QObject(parent),
|
||||||
|
|
||||||
AbstractTableSet::~AbstractTableSet()
|
AbstractTableSet::~AbstractTableSet()
|
||||||
{
|
{
|
||||||
Q_FOREACH (Row<Table> t, data->childs)
|
for (auto &t: data->children)
|
||||||
if (t)
|
if (t)
|
||||||
t->setParentTableSet(nullptr);
|
t->setParentTableSet(nullptr);
|
||||||
}
|
}
|
||||||
|
|
@ -52,14 +56,14 @@ int AbstractTableSet::save(Database *db, bool cleanUp)
|
||||||
if (data->table)
|
if (data->table)
|
||||||
masterModel = db->model().tableByClassName(QString::fromUtf8(data->table->metaObject()->className()));
|
masterModel = db->model().tableByClassName(QString::fromUtf8(data->table->metaObject()->className()));
|
||||||
|
|
||||||
Q_FOREACH (Row<Table> t, data->childs) {
|
for (auto &t : data->children) {
|
||||||
if (data->table)
|
if (data->table)
|
||||||
t->setParentTable(data->table,
|
t->setParentTable(data->table,
|
||||||
masterModel,
|
masterModel,
|
||||||
db->model().tableByClassName(QString::fromUtf8(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)
|
||||||
|
|
@ -71,32 +75,67 @@ int AbstractTableSet::save(Database *db, bool cleanUp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cleanUp)
|
for (auto &row : data->weakChildren) {
|
||||||
data->childs.clear();
|
auto t = row.lock();
|
||||||
|
if (data->table)
|
||||||
|
t->setParentTable(data->table,
|
||||||
|
masterModel,
|
||||||
|
db->model().tableByClassName(
|
||||||
|
QString::fromUtf8(t->metaObject()->className())));
|
||||||
|
|
||||||
|
if (t->status() == Table::Added || t->status() == Table::Modified
|
||||||
|
|| t->status() == Table::Deleted) {
|
||||||
|
rowsAffected += t->save(db);
|
||||||
|
if (cleanUp)
|
||||||
|
#ifdef NUT_RAW_POINTER
|
||||||
|
t->deleteLater();
|
||||||
|
#else
|
||||||
|
remove(row);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cleanUp) {
|
||||||
|
data->children.clear();
|
||||||
|
data->weakChildren.clear();
|
||||||
|
}
|
||||||
|
|
||||||
return rowsAffected;
|
return rowsAffected;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractTableSet::clearChilds()
|
void AbstractTableSet::clearChildren()
|
||||||
{
|
{
|
||||||
#ifdef NUT_RAW_POINTER
|
#ifdef NUT_RAW_POINTER
|
||||||
Q_FOREACH (Table *t, data->childs)
|
for (auto &t: data->children)
|
||||||
t->deleteLater();
|
t->deleteLater();
|
||||||
#endif
|
#endif
|
||||||
data->childs.clear();
|
data->children.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AbstractTableSet::add(Row<Table> t)
|
void AbstractTableSet::add(Row<Table> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.append(t);
|
data->children.append(t);
|
||||||
t->setParentTableSet(this);
|
t->setParentTableSet(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AbstractTableSet::add(WeakRow<Table> t)
|
||||||
|
{
|
||||||
|
data.detach();
|
||||||
|
data->weakChildren.append(t);
|
||||||
|
t.toStrongRef()->setParentTableSet(this);
|
||||||
|
}
|
||||||
|
|
||||||
void AbstractTableSet::remove(Row<Table> t)
|
void AbstractTableSet::remove(Row<Table> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.removeAll(t);
|
data->children.removeAll(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AbstractTableSet::remove(WeakRow<Table> t)
|
||||||
|
{
|
||||||
|
data.detach();
|
||||||
|
data->weakChildren.removeAll(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AbstractTableSet::childClassName() const
|
QString AbstractTableSet::childClassName() const
|
||||||
|
|
@ -117,7 +156,9 @@ void AbstractTableSet::setDatabase(Database *database)
|
||||||
|
|
||||||
int AbstractTableSet::size() const
|
int AbstractTableSet::size() const
|
||||||
{
|
{
|
||||||
return data->childs.size();
|
return data->children.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,14 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Table;
|
class Table;
|
||||||
class Database;
|
class Database;
|
||||||
class AbstractTableSetData;
|
class AbstractTableSetData;
|
||||||
|
class TableModel;
|
||||||
class NUT_EXPORT AbstractTableSet : public QObject
|
class NUT_EXPORT AbstractTableSet : public QObject
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -42,7 +45,7 @@ public:
|
||||||
virtual ~AbstractTableSet();
|
virtual ~AbstractTableSet();
|
||||||
|
|
||||||
virtual int save(Database *db, bool cleanUp = false);
|
virtual int save(Database *db, bool cleanUp = false);
|
||||||
void clearChilds();
|
void clearChildren();
|
||||||
QString childClassName() const;
|
QString childClassName() const;
|
||||||
|
|
||||||
Database *database() const;
|
Database *database() const;
|
||||||
|
|
@ -58,12 +61,17 @@ public://TODO: change this to private
|
||||||
// void remove(Table *t);
|
// void remove(Table *t);
|
||||||
|
|
||||||
void add(Row<Table> t);
|
void add(Row<Table> t);
|
||||||
|
void add(WeakRow<Table> t);
|
||||||
void remove(Row<Table> t);
|
void remove(Row<Table> t);
|
||||||
|
void remove(WeakRow<Table> t);
|
||||||
|
|
||||||
friend class Table;
|
friend class Table;
|
||||||
friend class QueryBase;
|
friend class QueryBase;
|
||||||
|
private:
|
||||||
|
void saveChangedOnRow(Nut::Table *t, Nut::TableModel *masterModel);
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_ABSTRACTTABLESET_H
|
#endif // NUT_ABSTRACTTABLESET_H
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Table;
|
class Table;
|
||||||
|
|
@ -42,13 +44,17 @@ public:
|
||||||
|
|
||||||
// QSet<Table*> tables;
|
// QSet<Table*> tables;
|
||||||
// QList<Table*> childRows;
|
// QList<Table*> childRows;
|
||||||
RowList<Table> childs;
|
RowList<Table> children;
|
||||||
|
WeakRowList<Table> weakChildren;
|
||||||
|
|
||||||
Database *database;
|
Database *database;
|
||||||
Table *table;
|
Table *table;
|
||||||
QString childClassName;
|
QString childClassName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_ABSTRACTTABLESETDATA_H
|
#endif // NUT_ABSTRACTTABLESETDATA_H
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,23 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "bulkinserter.h"
|
#include "bulkinserter.h"
|
||||||
#include "bulkinserter_p.h"
|
#include "bulkinserter_p.h"
|
||||||
|
|
||||||
|
|
@ -8,6 +28,8 @@
|
||||||
|
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
BulkInserterPrivate::BulkInserterPrivate(Database *db)
|
BulkInserterPrivate::BulkInserterPrivate(Database *db)
|
||||||
|
|
@ -21,7 +43,7 @@ BulkInserter::BulkInserter(Database *db, QString &className)
|
||||||
{
|
{
|
||||||
Q_D(BulkInserter);
|
Q_D(BulkInserter);
|
||||||
|
|
||||||
Q_FOREACH (TableModel *m, db->model())
|
for (auto &m: db->model())
|
||||||
if (m->className() == className)
|
if (m->className() == className)
|
||||||
d->className = m->name();
|
d->className = m->name();
|
||||||
}
|
}
|
||||||
|
|
@ -71,3 +93,5 @@ int BulkInserter::apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,23 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 BULKINSERTER_H
|
#ifndef BULKINSERTER_H
|
||||||
#define BULKINSERTER_H
|
#define BULKINSERTER_H
|
||||||
|
|
||||||
|
|
@ -8,6 +28,8 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class PhraseList;
|
class PhraseList;
|
||||||
|
|
@ -15,7 +37,7 @@ class Database;
|
||||||
class BulkInserterPrivate;
|
class BulkInserterPrivate;
|
||||||
class NUT_EXPORT BulkInserter
|
class NUT_EXPORT BulkInserter
|
||||||
{
|
{
|
||||||
Q_DECLARE_PRIVATE(BulkInserter);
|
Q_DECLARE_PRIVATE(BulkInserter)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
BulkInserter(Database *db, QString &className);
|
BulkInserter(Database *db, QString &className);
|
||||||
|
|
@ -37,4 +59,6 @@ private:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // BULKINSERTER_H
|
#endif // BULKINSERTER_H
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,40 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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/>.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Nut API. This header
|
||||||
|
// file may change from version to version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
#ifndef BULKINSERTER_P_H
|
#ifndef BULKINSERTER_P_H
|
||||||
#define BULKINSERTER_P_H
|
#define BULKINSERTER_P_H
|
||||||
|
|
||||||
#include <QtNut/phraselist.h>
|
#include <QtNut/phraselist.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
@ -20,4 +52,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // BULKINSERTER_P_H
|
#endif // BULKINSERTER_P_H
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "changelogtable.h"
|
#include "changelogtable.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
ChangeLogTable::ChangeLogTable(QObject *tableSet) : Table(tableSet)
|
ChangeLogTable::ChangeLogTable(QObject *tableSet) : Table(tableSet)
|
||||||
|
|
@ -29,3 +31,5 @@ ChangeLogTable::ChangeLogTable(QObject *tableSet) : Table(tableSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtNut/table.h>
|
#include <QtNut/table.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT ChangeLogTable : public Table
|
class NUT_EXPORT ChangeLogTable : public Table
|
||||||
|
|
@ -43,6 +45,8 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(Nut::ChangeLogTable*)
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(NUT_WRAP_NAMESPACE(ChangeLogTable*))
|
||||||
|
|
||||||
#endif // CHANGELOGTABLE_H
|
#endif // CHANGELOGTABLE_H
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ HEADERS += \
|
||||||
$$PWD/foreigncontainer.h \
|
$$PWD/foreigncontainer.h \
|
||||||
$$PWD/propertysignalmapper.h \
|
$$PWD/propertysignalmapper.h \
|
||||||
$$PWD/query.h \
|
$$PWD/query.h \
|
||||||
|
$$PWD/sqlserializer.h \
|
||||||
$$PWD/table.h \
|
$$PWD/table.h \
|
||||||
$$PWD/table_p.h \
|
$$PWD/table_p.h \
|
||||||
$$PWD/tableset.h
|
$$PWD/tableset.h
|
||||||
|
|
@ -23,6 +24,7 @@ SOURCES += \
|
||||||
$$PWD/foreigncontainer.cpp \
|
$$PWD/foreigncontainer.cpp \
|
||||||
$$PWD/propertysignalmapper.cpp \
|
$$PWD/propertysignalmapper.cpp \
|
||||||
$$PWD/query.cpp \
|
$$PWD/query.cpp \
|
||||||
|
$$PWD/sqlserializer.cpp \
|
||||||
$$PWD/table.cpp \
|
$$PWD/table.cpp \
|
||||||
$$PWD/tableset.cpp
|
$$PWD/tableset.cpp
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,8 +49,11 @@
|
||||||
# define __CHANGE_LOG_TABLE_NAME "__change_logs"
|
# define __CHANGE_LOG_TABLE_NAME "__change_logs"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
QStringList DatabasePrivate::updatedDatabases;
|
||||||
qulonglong DatabasePrivate::lastId = 0;
|
qulonglong DatabasePrivate::lastId = 0;
|
||||||
QMap<QString, DatabaseModel> DatabasePrivate::allTableMaps;
|
QMap<QString, DatabaseModel> DatabasePrivate::allTableMaps;
|
||||||
|
|
||||||
|
|
@ -131,7 +134,12 @@ bool DatabasePrivate::updateDatabase()
|
||||||
{
|
{
|
||||||
Q_Q(Database);
|
Q_Q(Database);
|
||||||
|
|
||||||
if (!getCurrectSchema())
|
QString databaseHistoryName = driver + "\t" + databaseName + "\t" + hostName;
|
||||||
|
|
||||||
|
if (updatedDatabases.contains(databaseHistoryName))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (!getCurrentSchema())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
DatabaseModel last = isDatabaseNew ? DatabaseModel() : getLastSchema();
|
DatabaseModel last = isDatabaseNew ? DatabaseModel() : getLastSchema();
|
||||||
|
|
@ -140,12 +148,12 @@ bool DatabasePrivate::updateDatabase()
|
||||||
if (last == current) {
|
if (last == current) {
|
||||||
qDebug("Database is up-to-date");
|
qDebug("Database is up-to-date");
|
||||||
//TODO: crash without this and I don't know why!
|
//TODO: crash without this and I don't know why!
|
||||||
changeLogs->clearChilds();
|
changeLogs->clearChildren();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH (TableModel *tm, current) {
|
for (auto &tm: current) {
|
||||||
Q_FOREACH (FieldModel *fm, tm->fields()) {
|
for (auto &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),
|
||||||
|
|
@ -160,10 +168,10 @@ bool DatabasePrivate::updateDatabase()
|
||||||
else
|
else
|
||||||
qDebug("Database is changed");
|
qDebug("Database is changed");
|
||||||
|
|
||||||
QStringList sql = sqlGenerator->diff(last, current);
|
QStringList sql = sqlGenerator->diffDatabase(last, current);
|
||||||
|
|
||||||
db.transaction();
|
db.transaction();
|
||||||
Q_FOREACH (QString s, sql) {
|
for (auto &s: sql) {
|
||||||
db.exec(s);
|
db.exec(s);
|
||||||
|
|
||||||
if (db.lastError().type() != QSqlError::NoError) {
|
if (db.lastError().type() != QSqlError::NoError) {
|
||||||
|
|
@ -182,6 +190,7 @@ bool DatabasePrivate::updateDatabase()
|
||||||
if (!last.count())
|
if (!last.count())
|
||||||
q->databaseCreated();
|
q->databaseCreated();
|
||||||
|
|
||||||
|
updatedDatabases.append(databaseHistoryName);
|
||||||
} else {
|
} else {
|
||||||
qWarning("Unable update database, error = %s",
|
qWarning("Unable update database, error = %s",
|
||||||
db.lastError().text().toLatin1().data());
|
db.lastError().text().toLatin1().data());
|
||||||
|
|
@ -190,14 +199,14 @@ bool DatabasePrivate::updateDatabase()
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabasePrivate::getCurrectSchema()
|
bool DatabasePrivate::getCurrentSchema()
|
||||||
{
|
{
|
||||||
Q_Q(Database);
|
Q_Q(Database);
|
||||||
|
|
||||||
//is not first instanicate of this class
|
//is not first instanicate of this class
|
||||||
if (allTableMaps.contains(QString::fromUtf8(q->metaObject()->className()))) {
|
if (allTableMaps.contains(QString::fromUtf8(q->metaObject()->className()))) {
|
||||||
currentModel = allTableMaps[QString::fromUtf8(q->metaObject()->className())];
|
currentModel = allTableMaps[QString::fromUtf8(q->metaObject()->className())];
|
||||||
return false;
|
// return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, QString> tables;
|
QMap<QString, QString> tables;
|
||||||
|
|
@ -252,15 +261,28 @@ 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(QString::fromUtf8(tableProperty.name()))
|
if ((unsigned) typeId >= QVariant::UserType) {
|
||||||
|
bool contains{false};
|
||||||
|
auto tableName = QString::fromUtf8(tableProperty.name());
|
||||||
|
for (auto i = tables.begin(); i != tables.end(); ++i)
|
||||||
|
if (i.value() == tableName)
|
||||||
|
contains = true;
|
||||||
|
|
||||||
|
if (contains) {
|
||||||
|
TableModel *sch = new TableModel(typeId, tableName);
|
||||||
|
currentModel.append(sch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*if (tables.values().contains(QString::fromUtf8(tableProperty.name()))
|
||||||
&& (unsigned)typeId >= QVariant::UserType) {
|
&& (unsigned)typeId >= QVariant::UserType) {
|
||||||
TableModel *sch = new TableModel(typeId, QString::fromUtf8(tableProperty.name()));
|
TableModel *sch = new TableModel(typeId, QString::fromUtf8(tableProperty.name()));
|
||||||
currentModel.append(sch);
|
currentModel.append(sch);
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH (TableModel *table, currentModel) {
|
for (auto &table: currentModel) {
|
||||||
Q_FOREACH (FieldModel *f, table->fields()) {
|
for (auto &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));
|
||||||
|
|
@ -270,7 +292,7 @@ bool DatabasePrivate::getCurrectSchema()
|
||||||
qPrintable(f->typeName));
|
qPrintable(f->typeName));
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH (RelationModel *fk, table->foreignKeys())
|
for (auto &fk: table->foreignKeys())
|
||||||
fk->masterTable = currentModel.tableByClassName(fk->masterClassName);
|
fk->masterTable = currentModel.tableByClassName(fk->masterClassName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -295,28 +317,8 @@ DatabaseModel DatabasePrivate::getLastSchema()
|
||||||
|
|
||||||
DatabaseModel ret = json;
|
DatabaseModel ret = json;
|
||||||
return ret;
|
return ret;
|
||||||
/*
|
|
||||||
Q_FOREACH (QString key, json.keys()) {
|
|
||||||
TableModel *sch = new TableModel(json.value(key).toObject(), key);
|
|
||||||
ret.append(sch);
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
return DatabaseModel();
|
return DatabaseModel();
|
||||||
|
|
||||||
// QSqlQuery query = q->exec("select * from __change_logs order by id
|
|
||||||
// desc limit 1");
|
|
||||||
// DatabaseModel ret;
|
|
||||||
// if(query.next()){
|
|
||||||
// QJsonObject json =
|
|
||||||
// QJsonDocument::fromJson(query.value("data").toByteArray()).object();
|
|
||||||
|
|
||||||
// Q_FOREACH (QString key, json.keys()) {
|
|
||||||
// TableModel *sch = new TableModel(json.value(key).toObject(),
|
|
||||||
// key);
|
|
||||||
// ret.append(sch);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DatabasePrivate::putModelToDatabase()
|
bool DatabasePrivate::putModelToDatabase()
|
||||||
|
|
@ -333,26 +335,16 @@ bool DatabasePrivate::putModelToDatabase()
|
||||||
changeLog->deleteLater();
|
changeLog->deleteLater();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// QSqlQuery query(db);
|
|
||||||
// query.prepare("insert into __change_logs (data) values (:data)");
|
|
||||||
// query.bindValue(":data",
|
|
||||||
// QString(QJsonDocument(currentModel.toJson()).toJson()));
|
|
||||||
// bool ret = query.exec();
|
|
||||||
// if(query.lastError().type() != QSqlError::NoError)
|
|
||||||
// qWarning(QString("storeSchemaInDB" +
|
|
||||||
// query.lastError().text()).toLatin1().data());
|
|
||||||
// return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DatabasePrivate::createChangeLogs()
|
void DatabasePrivate::createChangeLogs()
|
||||||
{
|
{
|
||||||
// currentModel.model("change_log")
|
// currentModel.model("change_log")
|
||||||
QStringList diff = sqlGenerator->diff(nullptr,
|
QStringList diff = sqlGenerator->diffTable(nullptr,
|
||||||
currentModel.tableByName(
|
currentModel.tableByName(
|
||||||
QStringLiteral("__change_log")));
|
QStringLiteral("__change_log")));
|
||||||
|
|
||||||
Q_FOREACH (QString s, diff)
|
for (auto &s: diff)
|
||||||
db.exec(s);
|
db.exec(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -564,12 +556,12 @@ bool Database::open(bool updateDatabase)
|
||||||
else if (d->driver == QStringLiteral("QODBC") || d->driver == QStringLiteral("QODBC3")) {
|
else if (d->driver == QStringLiteral("QODBC") || d->driver == QStringLiteral("QODBC3")) {
|
||||||
QString driverName = QString();
|
QString driverName = QString();
|
||||||
QStringList parts = d->databaseName.toLower().split(';');
|
QStringList parts = d->databaseName.toLower().split(';');
|
||||||
Q_FOREACH (QString p, parts)
|
for (auto &p: parts)
|
||||||
if (p.trimmed().startsWith(QStringLiteral("driver=")))
|
if (p.trimmed().startsWith(QStringLiteral("driver=")))
|
||||||
driverName = p.split('=').at(1).toLower().trimmed();
|
driverName = p.split('=').at(1).toLower().trimmed();
|
||||||
|
|
||||||
// if (driverName == "{sql server}")
|
// if (driverName == "{sql server}")
|
||||||
d->sqlGenerator = new SqlServerGenerator(this);
|
d->sqlGenerator = new SqlServerGenerator(this);
|
||||||
// TODO: add ODBC driver for mysql, postgres, ...
|
// TODO: add ODBC driver for mysql, postgres, ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,7 +607,7 @@ int Database::saveChanges(bool cleanUp)
|
||||||
}
|
}
|
||||||
|
|
||||||
int rowsAffected = 0;
|
int rowsAffected = 0;
|
||||||
Q_FOREACH (AbstractTableSet *ts, d->tableSets)
|
for (const auto &ts: qAsConst(d->tableSets))
|
||||||
rowsAffected += ts->save(this, cleanUp);
|
rowsAffected += ts->save(this, cleanUp);
|
||||||
|
|
||||||
return rowsAffected;
|
return rowsAffected;
|
||||||
|
|
@ -624,8 +616,10 @@ int Database::saveChanges(bool cleanUp)
|
||||||
void Database::cleanUp()
|
void Database::cleanUp()
|
||||||
{
|
{
|
||||||
Q_D(Database);
|
Q_D(Database);
|
||||||
Q_FOREACH (AbstractTableSet *ts, d->tableSets)
|
for (const auto &ts: qAsConst(d->tableSets))
|
||||||
ts->clearChilds();
|
ts->clearChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
#include <QtNut/tableset.h>
|
#include <QtNut/tableset.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class DatabaseModel;
|
class DatabaseModel;
|
||||||
|
|
@ -57,7 +59,7 @@ public:
|
||||||
|
|
||||||
QSqlQuery exec(const QString& sql);
|
QSqlQuery exec(const QString& sql);
|
||||||
|
|
||||||
int saveChanges(bool cleanUp = false);
|
int saveChanges(bool cleanUp = true);
|
||||||
void cleanUp();
|
void cleanUp();
|
||||||
|
|
||||||
QString databaseName() const;
|
QString databaseName() const;
|
||||||
|
|
@ -75,7 +77,6 @@ public:
|
||||||
QSqlDatabase database();
|
QSqlDatabase database();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//remove minor version
|
|
||||||
virtual void databaseCreated();
|
virtual void databaseCreated();
|
||||||
virtual void databaseUpdated(int oldVersion, int newVersion);
|
virtual void databaseUpdated(int oldVersion, int newVersion);
|
||||||
|
|
||||||
|
|
@ -96,4 +97,6 @@ private:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUTDATABASE_H
|
#endif // NUTDATABASE_H
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,16 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Nut API. This header
|
||||||
|
// file may change from version to version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
#ifndef DATABASE_P_H
|
#ifndef DATABASE_P_H
|
||||||
#define DATABASE_P_H
|
#define DATABASE_P_H
|
||||||
|
|
||||||
|
|
@ -27,6 +37,8 @@
|
||||||
#include <QtNut/database.h>
|
#include <QtNut/database.h>
|
||||||
#include <QtNut/databasemodel.h>
|
#include <QtNut/databasemodel.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class ChangeLogTable;
|
class ChangeLogTable;
|
||||||
|
|
@ -44,7 +56,7 @@ public:
|
||||||
void createChangeLogs();
|
void createChangeLogs();
|
||||||
bool putModelToDatabase();
|
bool putModelToDatabase();
|
||||||
DatabaseModel getLastSchema();
|
DatabaseModel getLastSchema();
|
||||||
bool getCurrectSchema();
|
bool getCurrentSchema();
|
||||||
|
|
||||||
QSqlDatabase db;
|
QSqlDatabase db;
|
||||||
|
|
||||||
|
|
@ -63,6 +75,7 @@ public:
|
||||||
|
|
||||||
static QMap<QString, DatabaseModel> allTableMaps;
|
static QMap<QString, DatabaseModel> allTableMaps;
|
||||||
static qulonglong lastId;
|
static qulonglong lastId;
|
||||||
|
static QStringList updatedDatabases;
|
||||||
|
|
||||||
QSet<AbstractTableSet *> tableSets;
|
QSet<AbstractTableSet *> tableSets;
|
||||||
|
|
||||||
|
|
@ -73,4 +86,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // DATABASE_P_H
|
#endif // DATABASE_P_H
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,33 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 FOREIGNCONTAINER_H
|
#ifndef FOREIGNCONTAINER_H
|
||||||
#define FOREIGNCONTAINER_H
|
#define FOREIGNCONTAINER_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
#include <QtNut/NutGlobal>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template<class _OBJECT, typename _KEY>
|
template<class _OBJECT, typename _KEY>
|
||||||
class ForeignContainer
|
class ForeignContainer
|
||||||
{
|
{
|
||||||
|
|
@ -55,4 +82,8 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // FOREIGNCONTAINER_H
|
#endif // FOREIGNCONTAINER_H
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,9 @@
|
||||||
|
|
||||||
#include "propertysignalmapper.h"
|
#include "propertysignalmapper.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
#include "nut_global.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -71,3 +74,5 @@ QString PropertySignalMapper::changedProperty(QObject *obj, int senderSignalInde
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include <QMetaMethod>
|
#include <QMetaMethod>
|
||||||
#include <QMetaProperty>
|
#include <QMetaProperty>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Table;
|
class Table;
|
||||||
|
|
@ -46,4 +48,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // PROPERTYSIGNALMAPPER_H
|
#endif // PROPERTYSIGNALMAPPER_H
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -80,3 +82,5 @@ NUT_BEGIN_NAMESPACE
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -44,9 +44,18 @@
|
||||||
#include <QtNut/tablemodel.h>
|
#include <QtNut/tablemodel.h>
|
||||||
#include <QtNut/sqlmodel.h>
|
#include <QtNut/sqlmodel.h>
|
||||||
|
|
||||||
|
#ifdef NUT_PRINT_DEBUG_INFO
|
||||||
|
# define printSql(sql) qDebug().noquote() << "[Nut][" << __FUNCTION__ << "] sql=" << sql;
|
||||||
|
#else
|
||||||
|
# define printSql(sql)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
struct NUT_EXPORT QueryData {
|
struct NUT_EXPORT QueryData {
|
||||||
|
bool hasCustomCommand{false};
|
||||||
QString sql;
|
QString sql;
|
||||||
QString className;
|
QString className;
|
||||||
QString tableName;
|
QString tableName;
|
||||||
|
|
@ -146,24 +155,28 @@ public:
|
||||||
|
|
||||||
//debug purpose
|
//debug purpose
|
||||||
QString sqlCommand() const;
|
QString sqlCommand() const;
|
||||||
|
|
||||||
|
Query<T> &setSqlCommand(const QString &command);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T>
|
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(AbstractQuery);
|
|
||||||
QList<O> ret;
|
QList<O> ret;
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
if (!d->hasCustomCommand) {
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
d->joins.prepend(d->tableName);
|
||||||
AbstractSqlGenerator::SingleField,
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
QStringLiteral("*"),
|
AbstractSqlGenerator::SingleField,
|
||||||
d->wherePhrase,
|
QStringLiteral("*"),
|
||||||
d->relations,
|
d->wherePhrase,
|
||||||
d->skip,
|
d->relations,
|
||||||
d->take);
|
d->skip,
|
||||||
|
d->take);
|
||||||
|
|
||||||
|
printSql(d->sql);
|
||||||
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
while (q.next()) {
|
while (q.next()) {
|
||||||
|
|
@ -184,8 +197,6 @@ template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, AbstractTableSet *tableSet)
|
Q_OUTOFLINE_TEMPLATE Query<T>::Query(Database *database, AbstractTableSet *tableSet)
|
||||||
: d(new QueryData(database))
|
: d(new QueryData(database))
|
||||||
{
|
{
|
||||||
//Q_D(AbstractQuery);
|
|
||||||
|
|
||||||
d->database = database;
|
d->database = database;
|
||||||
d->tableSet = tableSet;
|
d->tableSet = tableSet;
|
||||||
d->className = QString::fromUtf8(T::staticMetaObject.className());
|
d->className = QString::fromUtf8(T::staticMetaObject.className());
|
||||||
|
|
@ -209,7 +220,6 @@ Q_OUTOFLINE_TEMPLATE Query<T>::Query(Query<T> &&other) {
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
|
Q_OUTOFLINE_TEMPLATE Query<T>::~Query()
|
||||||
{
|
{
|
||||||
//Q_D(AbstractQuery);
|
|
||||||
delete d;
|
delete d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,14 +238,19 @@ Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::operator=(const Query<T> &q)
|
||||||
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(AbstractQuery);
|
|
||||||
RowList<T> returnList;
|
RowList<T> returnList;
|
||||||
d->select = QStringLiteral("*");
|
d->select = QStringLiteral("*");
|
||||||
|
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
if (!d->hasCustomCommand)
|
||||||
d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase,
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
d->relations, d->skip, count);
|
d->fieldPhrase,
|
||||||
|
d->wherePhrase,
|
||||||
|
d->orderPhrase,
|
||||||
|
d->relations,
|
||||||
|
d->skip,
|
||||||
|
count);
|
||||||
|
|
||||||
|
printSql(d->sql);
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
if (q.lastError().isValid()) {
|
if (q.lastError().isValid()) {
|
||||||
qDebug() << q.lastError().text();
|
qDebug() << q.lastError().text();
|
||||||
|
|
@ -244,7 +259,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);
|
||||||
Q_FOREACH (RelationModel *rel, d->relations)
|
for (auto &rel: d->relations)
|
||||||
relatedTables << rel->slaveTable << rel->masterTable;
|
relatedTables << rel->slaveTable << rel->masterTable;
|
||||||
|
|
||||||
struct LevelData{
|
struct LevelData{
|
||||||
|
|
@ -271,7 +286,7 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
data.lastKeyValue = QVariant();
|
data.lastKeyValue = QVariant();
|
||||||
|
|
||||||
QHash<QString, QString> masters;
|
QHash<QString, QString> masters;
|
||||||
Q_FOREACH (RelationModel *rel, d->relations)
|
for (auto &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);
|
||||||
|
|
||||||
|
|
@ -337,7 +352,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
|
||||||
Q_FOREACH (int m, data.masters)
|
for (auto &m: data.masters)
|
||||||
if (!checked[m]) {
|
if (!checked[m]) {
|
||||||
// qDebug() << "row is checked";
|
// qDebug() << "row is checked";
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -350,7 +365,7 @@ 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<T> tmpRow = Nut::create<T>();
|
Row<T> tmpRow = create<T>();
|
||||||
row = tmpRow.template objectCast<Table>();
|
row = tmpRow.template objectCast<Table>();
|
||||||
|
|
||||||
row->init();
|
row->init();
|
||||||
|
|
@ -363,8 +378,13 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Table *table;
|
Table *table;
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
auto childMetaObject = QMetaType(data.table->typeId()).metaObject();
|
||||||
|
#else
|
||||||
const QMetaObject *childMetaObject
|
const QMetaObject *childMetaObject
|
||||||
= QMetaType::metaObjectForType(data.table->typeId());
|
= QMetaType::metaObjectForType(data.table->typeId());
|
||||||
|
#endif
|
||||||
table = qobject_cast<Table *>(childMetaObject->newInstance());
|
table = qobject_cast<Table *>(childMetaObject->newInstance());
|
||||||
// table = dynamic_cast<Table *>(QMetaType::create(data.table->typeId()));
|
// table = dynamic_cast<Table *>(QMetaType::create(data.table->typeId()));
|
||||||
if (!table)
|
if (!table)
|
||||||
|
|
@ -374,7 +394,7 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<FieldModel*> childFields = data.table->fields();
|
QList<FieldModel*> childFields = data.table->fields();
|
||||||
Q_FOREACH (FieldModel *field, childFields)
|
for (auto &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,
|
||||||
|
|
@ -399,6 +419,8 @@ Q_OUTOFLINE_TEMPLATE RowList<T> Query<T>::toList(int count)
|
||||||
Q_ARG(Nut::Row<Nut::Table>,
|
Q_ARG(Nut::Row<Nut::Table>,
|
||||||
levels[master].lastRow));
|
levels[master].lastRow));
|
||||||
|
|
||||||
|
if (Q_UNLIKELY(!ok))
|
||||||
|
qWarning("Unable to invoke method %s on object", qPrintable(setterName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -419,17 +441,20 @@ 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(AbstractQuery);
|
|
||||||
QList<F> ret;
|
QList<F> ret;
|
||||||
|
|
||||||
d->joins.prepend(d->tableName);
|
if (!d->hasCustomCommand) {
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->joins.prepend(d->tableName);
|
||||||
d->tableName,
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
AbstractSqlGenerator::SingleField, f.data->toString(),
|
AbstractSqlGenerator::SingleField,
|
||||||
d->wherePhrase,
|
f.data->toString(),
|
||||||
d->relations,
|
d->wherePhrase,
|
||||||
d->skip, d->take);
|
d->relations,
|
||||||
|
d->skip,
|
||||||
|
d->take);
|
||||||
|
|
||||||
|
printSql(d->sql);
|
||||||
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
while (q.next()) {
|
while (q.next()) {
|
||||||
|
|
@ -455,16 +480,16 @@ 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(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
|
d->joins.prepend(d->tableName);
|
||||||
d->joins.prepend(d->tableName);
|
d->select = QStringLiteral("COUNT(*)");
|
||||||
d->select = QStringLiteral("COUNT(*)");
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
AbstractSqlGenerator::Count,
|
||||||
d->tableName,
|
QStringLiteral("*"),
|
||||||
AbstractSqlGenerator::Count,
|
d->wherePhrase,
|
||||||
QStringLiteral("*"),
|
d->relations);
|
||||||
d->wherePhrase,
|
printSql(d->sql);
|
||||||
d->relations);
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (q.next())
|
if (q.next())
|
||||||
|
|
@ -475,14 +500,15 @@ 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(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
|
d->joins.prepend(d->tableName);
|
||||||
d->joins.prepend(d->tableName);
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
AbstractSqlGenerator::Max,
|
||||||
d->tableName,
|
f.data->toString(),
|
||||||
AbstractSqlGenerator::Max, f.data->toString(),
|
d->wherePhrase,
|
||||||
d->wherePhrase,
|
d->relations);
|
||||||
d->relations);
|
printSql(d->sql);
|
||||||
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (q.next())
|
if (q.next())
|
||||||
|
|
@ -493,14 +519,15 @@ 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(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
|
d->joins.prepend(d->tableName);
|
||||||
d->joins.prepend(d->tableName);
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
AbstractSqlGenerator::Min,
|
||||||
d->tableName,
|
f.data->toString(),
|
||||||
AbstractSqlGenerator::Min, f.data->toString(),
|
d->wherePhrase,
|
||||||
d->wherePhrase,
|
d->relations);
|
||||||
d->relations);
|
printSql(d->sql);
|
||||||
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (q.next())
|
if (q.next())
|
||||||
|
|
@ -511,14 +538,15 @@ 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(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
|
d->joins.prepend(d->tableName);
|
||||||
d->joins.prepend(d->tableName);
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
AbstractSqlGenerator::Sum,
|
||||||
d->tableName,
|
f.data->toString(),
|
||||||
AbstractSqlGenerator::Sum, f.data->toString(),
|
d->wherePhrase,
|
||||||
d->wherePhrase,
|
d->relations);
|
||||||
d->relations);
|
printSql(d->sql);
|
||||||
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (q.next())
|
if (q.next())
|
||||||
|
|
@ -529,14 +557,15 @@ 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(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
|
d->joins.prepend(d->tableName);
|
||||||
d->joins.prepend(d->tableName);
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
AbstractSqlGenerator::Average,
|
||||||
d->tableName,
|
f.data->toString(),
|
||||||
AbstractSqlGenerator::Average, f.data->toString(),
|
d->wherePhrase,
|
||||||
d->wherePhrase,
|
d->relations);
|
||||||
d->relations);
|
printSql(d->sql);
|
||||||
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
if (q.next())
|
if (q.next())
|
||||||
|
|
@ -547,9 +576,10 @@ 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(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
d->sql = d->database->sqlGenerator()
|
d->sql = d->database->sqlGenerator()->insertCommand(d->tableName, p);
|
||||||
->insertCommand(d->tableName, p);
|
printSql(d->sql);
|
||||||
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
return q.lastInsertId();
|
return q.lastInsertId();
|
||||||
|
|
@ -558,8 +588,6 @@ 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(AbstractQuery);
|
|
||||||
|
|
||||||
RelationModel *rel = d->database->model()
|
RelationModel *rel = d->database->model()
|
||||||
.relationByClassNames(d->className, className);
|
.relationByClassNames(d->className, className);
|
||||||
if (!rel)
|
if (!rel)
|
||||||
|
|
@ -587,7 +615,6 @@ Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::join(Table *c)
|
||||||
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(AbstractQuery);
|
|
||||||
if (d->wherePhrase.data)
|
if (d->wherePhrase.data)
|
||||||
d->wherePhrase = d->wherePhrase && ph;
|
d->wherePhrase = d->wherePhrase && ph;
|
||||||
else
|
else
|
||||||
|
|
@ -598,7 +625,6 @@ Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::where(const ConditionalPhrase &ph)
|
||||||
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(AbstractQuery);
|
|
||||||
d->wherePhrase = ph;
|
d->wherePhrase = ph;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -606,7 +632,6 @@ Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::setWhere(const ConditionalPhrase &ph)
|
||||||
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(AbstractQuery);
|
|
||||||
d->skip = n;
|
d->skip = n;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -614,7 +639,6 @@ Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::skip(int n)
|
||||||
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(AbstractQuery);
|
|
||||||
d->take = n;
|
d->take = n;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -622,24 +646,13 @@ Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::take(int n)
|
||||||
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(AbstractQuery);
|
|
||||||
d->fieldPhrase = ph;
|
d->fieldPhrase = ph;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//template <class T>
|
|
||||||
//Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::orderBy(QString fieldName,
|
|
||||||
// QString type)
|
|
||||||
//{
|
|
||||||
// //Q_D(AbstractQuery);
|
|
||||||
// d->orderPhrases.append(fieldName, type);
|
|
||||||
// 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(AbstractQuery);
|
|
||||||
d->orderPhrase = ph;
|
d->orderPhrase = ph;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -647,13 +660,10 @@ Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::orderBy(const PhraseList &ph)
|
||||||
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(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
|
d->sql = d->database->sqlGenerator()->updateCommand(d->tableName, ph, d->wherePhrase);
|
||||||
d->sql = d->database->sqlGenerator()->updateCommand(
|
printSql(d->sql);
|
||||||
d->tableName,
|
}
|
||||||
ph,
|
|
||||||
d->wherePhrase);
|
|
||||||
|
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
return q.numRowsAffected();
|
return q.numRowsAffected();
|
||||||
|
|
@ -662,10 +672,10 @@ Q_OUTOFLINE_TEMPLATE int Query<T>::update(const AssignmentPhraseList &ph)
|
||||||
template <class T>
|
template <class T>
|
||||||
Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
|
Q_OUTOFLINE_TEMPLATE int Query<T>::remove()
|
||||||
{
|
{
|
||||||
//Q_D(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
|
d->sql = d->database->sqlGenerator()->deleteCommand(d->tableName, d->wherePhrase);
|
||||||
d->sql = d->database->sqlGenerator()->deleteCommand(
|
printSql(d->sql);
|
||||||
d->tableName, d->wherePhrase);
|
}
|
||||||
QSqlQuery q = d->database->exec(d->sql);
|
QSqlQuery q = d->database->exec(d->sql);
|
||||||
|
|
||||||
return q.numRowsAffected();
|
return q.numRowsAffected();
|
||||||
|
|
@ -682,36 +692,33 @@ 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(AbstractQuery);
|
if (!d->hasCustomCommand) {
|
||||||
|
d->sql = d->database->sqlGenerator()->selectCommand(d->tableName,
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->fieldPhrase,
|
||||||
d->tableName,
|
d->wherePhrase,
|
||||||
d->fieldPhrase,
|
d->orderPhrase,
|
||||||
d->wherePhrase, d->orderPhrase, d->relations,
|
d->relations,
|
||||||
d->skip, d->take);
|
d->skip,
|
||||||
|
d->take);
|
||||||
|
printSql(d->sql);
|
||||||
|
}
|
||||||
DatabaseModel dbModel = d->database->model();
|
DatabaseModel dbModel = d->database->model();
|
||||||
model->setQuery(d->sql, d->database->database());
|
model->setQuery(d->sql, d->database->database());
|
||||||
|
|
||||||
int fieldIndex = 0;
|
int fieldIndex = 0;
|
||||||
|
|
||||||
if (d->fieldPhrase.data.count()) {
|
if (d->fieldPhrase.data.count()) {
|
||||||
Q_FOREACH (const PhraseData *pd, d->fieldPhrase.data) {
|
for (const auto &pd : qAsConst(d->fieldPhrase.data)) {
|
||||||
QString displayName = dbModel
|
QString displayName = dbModel.tableByClassName(QString::fromUtf8(pd->className))
|
||||||
.tableByClassName(QString::fromUtf8(pd->className))
|
|
||||||
->field(QString::fromUtf8(pd->fieldName))
|
->field(QString::fromUtf8(pd->fieldName))
|
||||||
->displayName;
|
->displayName;
|
||||||
|
|
||||||
model->setHeaderData(fieldIndex++,
|
model->setHeaderData(fieldIndex++, Qt::Horizontal, displayName);
|
||||||
Qt::Horizontal,
|
|
||||||
displayName);
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TableModel *tbl = d->database->model().tableByName(d->tableName);
|
TableModel *tbl = d->database->model().tableByName(d->tableName);
|
||||||
Q_FOREACH (FieldModel *f, tbl->fields()) {
|
for (auto &f : tbl->fields()) {
|
||||||
model->setHeaderData(fieldIndex++,
|
model->setHeaderData(fieldIndex++, Qt::Horizontal, f->displayName);
|
||||||
Qt::Horizontal,
|
|
||||||
f->displayName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -719,38 +726,15 @@ 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(AbstractQuery);
|
|
||||||
|
|
||||||
d->sql = d->database->sqlGenerator()->selectCommand(
|
d->sql = d->database->sqlGenerator()->selectCommand(
|
||||||
d->tableName,
|
d->tableName,
|
||||||
d->fieldPhrase,
|
d->fieldPhrase,
|
||||||
d->wherePhrase, d->orderPhrase, d->relations,
|
d->wherePhrase, d->orderPhrase, d->relations,
|
||||||
d->skip, d->take);
|
d->skip, d->take);
|
||||||
|
|
||||||
|
printSql(d->sql);
|
||||||
|
|
||||||
model->setTable(toList());
|
model->setTable(toList());
|
||||||
/*
|
|
||||||
DatabaseModel dbModel = d->database->model();
|
|
||||||
model->setQuery(d->sql, d->database->database());
|
|
||||||
|
|
||||||
int fieldIndex = 0;
|
|
||||||
|
|
||||||
if (d->fieldPhrase.data.count()) {
|
|
||||||
Q_FOREACH (const PhraseData *pd, d->fieldPhrase.data) {
|
|
||||||
QString displayName = dbModel.tableByClassName(pd->className)
|
|
||||||
->field(pd->fieldName)->displayName;
|
|
||||||
|
|
||||||
model->setHeaderData(fieldIndex++,
|
|
||||||
Qt::Horizontal,
|
|
||||||
displayName);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TableModel *tbl = d->database->model().tableByName(d->tableName);
|
|
||||||
Q_FOREACH (FieldModel *f, tbl->fields()) {
|
|
||||||
model->setHeaderData(fieldIndex++,
|
|
||||||
Qt::Horizontal,
|
|
||||||
f->displayName);
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
@ -760,15 +744,15 @@ Q_OUTOFLINE_TEMPLATE QString Query<T>::sqlCommand() const
|
||||||
return d->sql;
|
return d->sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: complete this class later
|
template<class T>
|
||||||
//class RawQuery : public Query<void>
|
Q_OUTOFLINE_TEMPLATE Query<T> &Query<T>::setSqlCommand(const QString &command)
|
||||||
//{
|
{
|
||||||
//public:
|
d->hasCustomCommand = true;
|
||||||
// void setRawCommand(const QString &sql) {
|
d->sql = command;
|
||||||
|
}
|
||||||
// }
|
|
||||||
//};
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_QUERY_H
|
#endif // NUT_QUERY_H
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,694 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 "sqlserializer.h"
|
||||||
|
|
||||||
|
#include <QtCore/QUuid>
|
||||||
|
#include <QtCore/QPoint>
|
||||||
|
#include <QtCore/QPointF>
|
||||||
|
#include <QtCore/QSizeF>
|
||||||
|
#include <QtCore/QSize>
|
||||||
|
#include <QtCore/QRect>
|
||||||
|
#include <QtCore/QRectF>
|
||||||
|
#include <QtCore/QDate>
|
||||||
|
#include <QtCore/QTime>
|
||||||
|
#include <QtCore/QDateTime>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QUrl>
|
||||||
|
#include <QtCore/QLineF>
|
||||||
|
#include <QtCore/QJsonDocument>
|
||||||
|
#include <QtCore/QJsonArray>
|
||||||
|
#include <QtCore/QJsonObject>
|
||||||
|
#include <QtCore/QBitArray>
|
||||||
|
#include <QtCore/QBuffer>
|
||||||
|
#include "nut_p.h"
|
||||||
|
#include "nut_global.h"
|
||||||
|
|
||||||
|
#ifdef QT_GUI_LIB
|
||||||
|
#include <QtGui/QFont>
|
||||||
|
#include <QtGui/QPolygon>
|
||||||
|
#include <QtGui/QPolygonF>
|
||||||
|
#include <QtGui/QColor>
|
||||||
|
#include <QtGui/QImage>
|
||||||
|
#include <QtGui/QVector2D>
|
||||||
|
#include <QtGui/QVector3D>
|
||||||
|
#include <QtGui/QVector4D>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DATE_FORMAT QStringLiteral("yyyy-MM-dd")
|
||||||
|
#define TIME_FORMAT QStringLiteral("HH:mm:ss.zzz")
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
SqlSerializer::SqlSerializer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SqlSerializer::~SqlSerializer()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SqlSerializer::fromString(const QString &value, const QMetaType::Type &type) const
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case QMetaType::Bool: return !value.compare(QStringLiteral("true"), Qt::CaseInsensitive) || value == QStringLiteral("1");
|
||||||
|
case QMetaType::Char:
|
||||||
|
case QMetaType::SChar:
|
||||||
|
case QMetaType::Int: return value.toInt();
|
||||||
|
case QMetaType::UChar:
|
||||||
|
case QMetaType::UInt: return value.toUInt();
|
||||||
|
case QMetaType::Short: return value.toShort();
|
||||||
|
case QMetaType::UShort: return value.toUShort();
|
||||||
|
case QMetaType::Long: return QVariant::fromValue(value.toLong());
|
||||||
|
case QMetaType::ULong: return QVariant::fromValue(value.toULong());
|
||||||
|
case QMetaType::LongLong: return value.toLongLong();
|
||||||
|
case QMetaType::ULongLong: return QVariant::fromValue(value.toULongLong());
|
||||||
|
case QMetaType::Float: return value.toFloat();
|
||||||
|
case QMetaType::Double: return value.toDouble();
|
||||||
|
case QMetaType::QString: return unescapeString(value);
|
||||||
|
case QMetaType::QDate: return QDate::fromString(value, DATE_FORMAT);
|
||||||
|
case QMetaType::QTime: return QTime::fromString(value, TIME_FORMAT);
|
||||||
|
case QMetaType::QDateTime: return QDateTime::fromString(value, DATE_FORMAT + QStringLiteral(" ") + TIME_FORMAT);
|
||||||
|
case QMetaType::QUrl: return QUrl(value);
|
||||||
|
case QMetaType::QChar: return value.at(0);
|
||||||
|
case QMetaType::QStringList: {
|
||||||
|
QStringList ret;
|
||||||
|
QString copy(value);
|
||||||
|
QString out;
|
||||||
|
|
||||||
|
while (readString(copy, out) )
|
||||||
|
ret.append(out);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QPoint: {
|
||||||
|
QList<int> parts = toListInt(value);
|
||||||
|
if (parts.size() != 2)
|
||||||
|
return QPoint();
|
||||||
|
|
||||||
|
return QPoint(parts.at(0), parts.at(1));
|
||||||
|
}
|
||||||
|
case QMetaType::QSize: {
|
||||||
|
QList<int> parts = toListInt(value);
|
||||||
|
if (parts.size() != 2)
|
||||||
|
return QSize();
|
||||||
|
|
||||||
|
return QSize(parts.at(0), parts.at(1));
|
||||||
|
}
|
||||||
|
case QMetaType::QRect: {
|
||||||
|
QList<int> parts = toListInt(value);
|
||||||
|
if (parts.size() != 4)
|
||||||
|
return QRect();
|
||||||
|
|
||||||
|
return QRect(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
|
||||||
|
}
|
||||||
|
case QMetaType::QLine: {
|
||||||
|
QList<int> parts = toListInt(value);
|
||||||
|
if (parts.size() != 4)
|
||||||
|
return QLine();
|
||||||
|
|
||||||
|
return QLine(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
|
||||||
|
}
|
||||||
|
case QMetaType::QPointF: {
|
||||||
|
QList<qreal> parts = toListReal(value);
|
||||||
|
if (parts.size() != 2)
|
||||||
|
return QPointF();
|
||||||
|
|
||||||
|
return QPointF(parts.at(0), parts.at(1));
|
||||||
|
}
|
||||||
|
case QMetaType::QSizeF: {
|
||||||
|
QList<qreal> parts = toListReal(value);
|
||||||
|
if (parts.size() != 2)
|
||||||
|
return QSizeF();
|
||||||
|
|
||||||
|
return QSizeF(parts.at(0), parts.at(1));
|
||||||
|
}
|
||||||
|
case QMetaType::QRectF: {
|
||||||
|
QList<qreal> parts = toListReal(value);
|
||||||
|
if (parts.size() != 4)
|
||||||
|
return QRectF();
|
||||||
|
|
||||||
|
return QRectF(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
|
||||||
|
}
|
||||||
|
case QMetaType::QLineF: {
|
||||||
|
QList<qreal> parts = toListReal(value);
|
||||||
|
if (parts.size() != 4)
|
||||||
|
return QLineF();
|
||||||
|
|
||||||
|
return QLineF(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QUuid:
|
||||||
|
return QUuid(value);
|
||||||
|
|
||||||
|
case QMetaType::QByteArray:
|
||||||
|
return value.toUtf8();
|
||||||
|
|
||||||
|
case QMetaType::QJsonDocument:
|
||||||
|
return QJsonDocument::fromJson(value.toUtf8());
|
||||||
|
|
||||||
|
case QMetaType::QJsonObject:
|
||||||
|
return QJsonDocument::fromJson(value.toUtf8()).object();
|
||||||
|
|
||||||
|
case QMetaType::QJsonArray:
|
||||||
|
return QJsonDocument::fromJson(value.toUtf8()).array();
|
||||||
|
|
||||||
|
case QMetaType::QJsonValue: {
|
||||||
|
if (value == QStringLiteral("true"))
|
||||||
|
return QJsonValue(true);
|
||||||
|
else if (value == QStringLiteral("false"))
|
||||||
|
return QJsonValue(false);
|
||||||
|
bool ok;
|
||||||
|
int n = value.toInt(&ok);
|
||||||
|
if (ok)
|
||||||
|
return QJsonValue(n);
|
||||||
|
|
||||||
|
double d = value.toDouble(&ok);
|
||||||
|
if (ok)
|
||||||
|
return QJsonValue(d);
|
||||||
|
|
||||||
|
return QJsonValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QBitArray: {
|
||||||
|
QBitArray bita(value.size());
|
||||||
|
for (int i = 0; i < value.size(); ++i) {
|
||||||
|
if (value.at(i) == QStringLiteral("0"))
|
||||||
|
bita.setBit(i, false);
|
||||||
|
else
|
||||||
|
bita.setBit(i, true);
|
||||||
|
}
|
||||||
|
return bita;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QVariantMap: {
|
||||||
|
QVariantMap ret;
|
||||||
|
QStringList parts = value.split(QStringLiteral("\n"));
|
||||||
|
for (auto &p: parts) {
|
||||||
|
if (p.isEmpty())
|
||||||
|
continue;
|
||||||
|
QString name;
|
||||||
|
QString value;
|
||||||
|
if (readString(p, name) && readString(p, value))
|
||||||
|
ret.insert(name, value);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QVariantList: {
|
||||||
|
QVariantMap ret;
|
||||||
|
QStringList parts = value.split(QStringLiteral("\n"));
|
||||||
|
for (auto &p: parts) {
|
||||||
|
if (p.isEmpty())
|
||||||
|
continue;
|
||||||
|
QString name;
|
||||||
|
QString value;
|
||||||
|
if (readString(p, name) && readString(p, value))
|
||||||
|
ret.insert(name, value);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QT_GUI_LIB
|
||||||
|
case QMetaType::QVector2D: {
|
||||||
|
QList<float> parts = toListFloat(value);
|
||||||
|
if (parts.size() != 2)
|
||||||
|
return QVector2D();
|
||||||
|
|
||||||
|
return QVector2D(parts.at(0), parts.at(1));
|
||||||
|
}
|
||||||
|
case QMetaType::QVector3D: {
|
||||||
|
QList<float> parts = toListFloat(value);
|
||||||
|
if (parts.size() != 3)
|
||||||
|
return QVector3D();
|
||||||
|
|
||||||
|
return QVector3D(parts.at(0), parts.at(1), parts.at(2));
|
||||||
|
}
|
||||||
|
case QMetaType::QVector4D: {
|
||||||
|
QList<float> parts = toListFloat(value);
|
||||||
|
if (parts.size() != 4)
|
||||||
|
return QVector4D();
|
||||||
|
|
||||||
|
return QVector4D(parts.at(0), parts.at(1), parts.at(2), parts.at(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QImage: {
|
||||||
|
QImage image;
|
||||||
|
image.loadFromData(QByteArray::fromBase64(value.toLocal8Bit()));
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QColor:
|
||||||
|
return QColor(value);
|
||||||
|
|
||||||
|
case QMetaType::QPolygon: {
|
||||||
|
QStringList parts = value.split(QStringLiteral(" "));
|
||||||
|
QPolygon pol;
|
||||||
|
for (int i = 0; i < parts.count(); i++)
|
||||||
|
pol.append(fromString(parts.at(i), QMetaType::QPoint).toPoint());
|
||||||
|
return pol;
|
||||||
|
}
|
||||||
|
case QMetaType::QPolygonF: {
|
||||||
|
QStringList parts = value.split(QStringLiteral(" "));
|
||||||
|
QPolygonF pol;
|
||||||
|
for (int i = 0; i < parts.count(); i++)
|
||||||
|
pol.append(fromString(parts.at(i), QMetaType::QPointF).toPointF());
|
||||||
|
return pol;
|
||||||
|
}
|
||||||
|
case QMetaType::QFont: {
|
||||||
|
QFont f;
|
||||||
|
f.fromString(value);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlSerializer::toString(const QVariant &value) const
|
||||||
|
{
|
||||||
|
auto type = METATYPE_ID(value);
|
||||||
|
switch (type) {
|
||||||
|
case QMetaType::Bool:
|
||||||
|
case QMetaType::Char:
|
||||||
|
case QMetaType::Short:
|
||||||
|
case QMetaType::UShort:
|
||||||
|
case QMetaType::Int:
|
||||||
|
case QMetaType::UInt:
|
||||||
|
case QMetaType::Long:
|
||||||
|
case QMetaType::ULong:
|
||||||
|
case QMetaType::LongLong:
|
||||||
|
case QMetaType::ULongLong:
|
||||||
|
case QMetaType::Double:
|
||||||
|
case QMetaType::Float:
|
||||||
|
case QMetaType::QChar:
|
||||||
|
case QMetaType::QUrl:
|
||||||
|
return value.toString();
|
||||||
|
|
||||||
|
case QMetaType::UChar:
|
||||||
|
case QMetaType::SChar:
|
||||||
|
return QString::number(value.toInt());
|
||||||
|
|
||||||
|
case QMetaType::QString:
|
||||||
|
return value.toString();
|
||||||
|
|
||||||
|
case QMetaType::QStringList: {
|
||||||
|
QString ret;
|
||||||
|
QStringList sl = value.toStringList();
|
||||||
|
for (auto &s: sl) {
|
||||||
|
if (!ret.isEmpty())
|
||||||
|
ret.append(QStringLiteral(" "));
|
||||||
|
|
||||||
|
ret.append(QStringLiteral("\"") + escapeString(s) + QStringLiteral("\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QUuid:
|
||||||
|
return value.toUuid().toString();
|
||||||
|
|
||||||
|
case QMetaType::QByteArray:
|
||||||
|
return QString::fromUtf8(value.toByteArray());
|
||||||
|
|
||||||
|
case QMetaType::QDate: return value.toDate().toString(DATE_FORMAT);
|
||||||
|
case QMetaType::QTime: return value.toTime().toString(TIME_FORMAT);
|
||||||
|
case QMetaType::QDateTime: return value.toDateTime().toString(DATE_FORMAT + QStringLiteral(" ") + TIME_FORMAT);
|
||||||
|
|
||||||
|
case QMetaType::QPoint: {
|
||||||
|
QPoint pt = value.toPoint();
|
||||||
|
return fromVariantList({pt.x(), pt.y()});
|
||||||
|
}
|
||||||
|
case QMetaType::QPointF: {
|
||||||
|
QPointF pt = value.toPointF();
|
||||||
|
return fromVariantList({pt.x(), pt.y()});
|
||||||
|
}
|
||||||
|
case QMetaType::QSize: {
|
||||||
|
QSize pt = value.toSize();
|
||||||
|
return fromVariantList({pt.width(), pt.height()});
|
||||||
|
}
|
||||||
|
case QMetaType::QSizeF: {
|
||||||
|
QSizeF pt = value.toSizeF();
|
||||||
|
return fromVariantList({pt.width(), pt.height()});
|
||||||
|
}
|
||||||
|
case QMetaType::QRect: {
|
||||||
|
QRect rc = value.toRect();
|
||||||
|
return fromVariantList({rc.x(), rc.y(), rc.width(), rc.height()});
|
||||||
|
}
|
||||||
|
case QMetaType::QRectF: {
|
||||||
|
QRectF rc = value.toRectF();
|
||||||
|
return fromVariantList({rc.x(), rc.y(), rc.width(), rc.height()});
|
||||||
|
}
|
||||||
|
case QMetaType::QLine: {
|
||||||
|
QLine rc = value.toLine();
|
||||||
|
return fromVariantList({rc.x1(), rc.y1(), rc.x2(), rc.y2()});
|
||||||
|
}
|
||||||
|
case QMetaType::QLineF: {
|
||||||
|
QLineF rc = value.toLineF();
|
||||||
|
return fromVariantList({rc.x1(), rc.y1(), rc.x2(), rc.y2()});
|
||||||
|
}
|
||||||
|
case QMetaType::QJsonDocument:
|
||||||
|
return QString::fromUtf8(value.toJsonDocument().toJson(QJsonDocument::Compact));
|
||||||
|
|
||||||
|
case QMetaType::QJsonObject: {
|
||||||
|
QJsonDocument doc;
|
||||||
|
doc.setObject(value.toJsonObject());
|
||||||
|
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QJsonArray: {
|
||||||
|
QJsonDocument doc;
|
||||||
|
doc.setArray(value.toJsonArray());
|
||||||
|
return QString::fromUtf8(doc.toJson(QJsonDocument::Compact));
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QJsonValue:
|
||||||
|
return value.toJsonValue().toVariant().toString();
|
||||||
|
|
||||||
|
case QMetaType::QBitArray: {
|
||||||
|
QString ret;
|
||||||
|
QBitArray bita = value.toBitArray();
|
||||||
|
for (int i = 0; i < bita.size(); ++i)
|
||||||
|
ret.append(bita.at(i) ? QStringLiteral("1") : QStringLiteral("0"));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
case QMetaType::QVariantMap: {
|
||||||
|
QString ret;
|
||||||
|
QVariantMap map = value.toMap();
|
||||||
|
for (auto i = map.begin(); i != map.end(); ++i) {
|
||||||
|
if (!ret.isEmpty())
|
||||||
|
ret.append(QStringLiteral("\n"));
|
||||||
|
QVariant v = map.value(i.key());
|
||||||
|
QString str = toString(v);
|
||||||
|
ret.append(QStringLiteral("\"%1\" \"%2\"")
|
||||||
|
.arg(escapeString(i.key()), escapeString(str)));
|
||||||
|
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef QT_GUI_LIB
|
||||||
|
case QMetaType::QVector2D: {
|
||||||
|
QVector2D vec = value.value<QVector2D>();
|
||||||
|
return fromList(QList<float>() << vec.x() << vec.y());
|
||||||
|
}
|
||||||
|
case QMetaType::QVector3D: {
|
||||||
|
QVector3D vec = value.value<QVector3D>();
|
||||||
|
return fromList(QList<float>() << vec.x() << vec.y() << vec.z());
|
||||||
|
}
|
||||||
|
case QMetaType::QVector4D: {
|
||||||
|
QVector4D vec = value.value<QVector4D>();
|
||||||
|
return fromList(QList<float>() << vec.x() << vec.y() << vec.z() << vec.w());
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QImage: {
|
||||||
|
QImage image = value.value<QImage>();
|
||||||
|
QByteArray byteArray;
|
||||||
|
QBuffer buffer(&byteArray);
|
||||||
|
image.save(&buffer, "PNG");
|
||||||
|
QString base64 = QString::fromLatin1(byteArray.toBase64().data());
|
||||||
|
return base64;
|
||||||
|
}
|
||||||
|
|
||||||
|
case QMetaType::QColor:
|
||||||
|
return value.value<QColor>().name();
|
||||||
|
|
||||||
|
case QMetaType::QPolygon: {
|
||||||
|
QStringList list;
|
||||||
|
QPolygon pol = value.value<QPolygon>();
|
||||||
|
QPoint pt;
|
||||||
|
for (int i = 0; i < pol.size(); ++i) {
|
||||||
|
pt = pol.at(i);
|
||||||
|
list.append(toString(pt));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.join(QStringLiteral(" "));
|
||||||
|
}
|
||||||
|
case QMetaType::QPolygonF: {
|
||||||
|
QStringList list;
|
||||||
|
QPolygonF pol = value.value<QPolygonF>();
|
||||||
|
QPointF pt;
|
||||||
|
for (int i = 0; i < pol.size(); ++i) {
|
||||||
|
pt = pol.at(i);
|
||||||
|
list.append(toString(pt));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list.join(QStringLiteral(" "));
|
||||||
|
}
|
||||||
|
case QMetaType::QFont:
|
||||||
|
return value.value<QFont>().toString();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case QMetaType::QVariantList: {
|
||||||
|
auto l = value.toList();
|
||||||
|
QString ret;
|
||||||
|
|
||||||
|
for (auto &v: l) {
|
||||||
|
if (!ret.isEmpty())
|
||||||
|
ret.append(QStringLiteral(", "));
|
||||||
|
ret.append(toString(v));
|
||||||
|
}
|
||||||
|
|
||||||
|
return QStringLiteral("(") + ret + QStringLiteral(")");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
qWarning("The type (%s) does not supported",
|
||||||
|
METATYPE_TO_NAME(type));
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> SqlSerializer::toListInt(const QString &s) const
|
||||||
|
{
|
||||||
|
return toListInt(s, QStringLiteral(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<int> SqlSerializer::toListInt(const QString &s, const QString &sep) const
|
||||||
|
{
|
||||||
|
auto parts = s.split(sep);
|
||||||
|
QList<int> ret;
|
||||||
|
for (auto &p: parts) {
|
||||||
|
bool ok;
|
||||||
|
ret.append(p.toInt(&ok));
|
||||||
|
if (!ok)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<qreal> SqlSerializer::toListReal(const QString &s) const
|
||||||
|
{
|
||||||
|
return toListReal(s, QStringLiteral(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlSerializer::fromList(const QList<int> &list) const
|
||||||
|
{
|
||||||
|
QString ret;
|
||||||
|
for (auto &n: list) {
|
||||||
|
if (!ret.isEmpty())
|
||||||
|
ret.append(QStringLiteral(","));
|
||||||
|
ret.append(QString::number(n));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<qreal> SqlSerializer::toListReal(const QString &s, const QString &sep) const
|
||||||
|
{
|
||||||
|
auto parts = s.split(sep);
|
||||||
|
QList<qreal> ret;
|
||||||
|
for (auto &p: parts) {
|
||||||
|
bool ok;
|
||||||
|
ret.append(p.toDouble(&ok));
|
||||||
|
if (!ok)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<float> SqlSerializer::toListFloat(const QString &s) const
|
||||||
|
{
|
||||||
|
auto parts = s.split(QStringLiteral(","));
|
||||||
|
QList<float> ret;
|
||||||
|
for (auto &p: parts) {
|
||||||
|
bool ok;
|
||||||
|
ret.append(p.toFloat(&ok));
|
||||||
|
if (!ok)
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlSerializer::fromList(const QList<qreal> &list) const
|
||||||
|
{
|
||||||
|
QString ret;
|
||||||
|
for (auto &n: list) {
|
||||||
|
if (!ret.isEmpty())
|
||||||
|
ret.append(QStringLiteral(","));
|
||||||
|
ret.append(QString::number(n, 'f', -1));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlSerializer::fromList(const QList<float> &list) const
|
||||||
|
{
|
||||||
|
QString ret;
|
||||||
|
for (auto &n: list) {
|
||||||
|
if (!ret.isEmpty())
|
||||||
|
ret.append(QStringLiteral(","));
|
||||||
|
ret.append(QString::number(static_cast<double>(n)));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlSerializer::fromVariantList(const QVariantList &list) const
|
||||||
|
{
|
||||||
|
QString ret;
|
||||||
|
for (auto &n: list) {
|
||||||
|
if (!ret.isEmpty())
|
||||||
|
ret.append(QStringLiteral(","));
|
||||||
|
ret.append(n.toString());
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CASE_W(o, r) \
|
||||||
|
case o: \
|
||||||
|
ret.append(QStringLiteral(r)); \
|
||||||
|
break;
|
||||||
|
QString SqlSerializer::escapeString(const QString &str) const
|
||||||
|
{
|
||||||
|
// QString ret;
|
||||||
|
// for (int i = 0; i < str.length(); ++i) {
|
||||||
|
// switch (str.at(i).cell()) {
|
||||||
|
// CASE_W('\\', "\\\\")
|
||||||
|
// CASE_W('\r', "\\r")
|
||||||
|
// CASE_W('\n', "\\n")
|
||||||
|
// CASE_W('\a', "\\a")
|
||||||
|
// CASE_W('\b', "\\b")
|
||||||
|
// CASE_W('\f', "\\f")
|
||||||
|
// // CASE_W('\'', "\\'")
|
||||||
|
// CASE_W('\t', "\\t")
|
||||||
|
// CASE_W('\v', "\\v")
|
||||||
|
// CASE_W('\"', "\\\"")
|
||||||
|
|
||||||
|
// default:
|
||||||
|
// ret.append(str.at(i));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return ret;
|
||||||
|
QString ret(str);
|
||||||
|
return ret.replace(QStringLiteral("'"), QStringLiteral("''"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlSerializer::unescapeString(const QString &str) const
|
||||||
|
{
|
||||||
|
// QString ret;
|
||||||
|
// for (int i = 0; i < str.length(); ++i) {
|
||||||
|
// if (str.at(i) == '\\' && str.length() > i) {
|
||||||
|
// switch (str.at(++i).cell()) {
|
||||||
|
// case '\\':
|
||||||
|
// ret.append(QStringLiteral("\\"));
|
||||||
|
// break;
|
||||||
|
// case 'r':
|
||||||
|
// ret.append(QStringLiteral("\r"));
|
||||||
|
// break;
|
||||||
|
// case 'n':
|
||||||
|
// ret.append(QStringLiteral("\n"));
|
||||||
|
// break;
|
||||||
|
// case 'a':
|
||||||
|
// ret.append(QStringLiteral("\a"));
|
||||||
|
// break;
|
||||||
|
// case 'b':
|
||||||
|
// ret.append(QStringLiteral("b"));
|
||||||
|
// break;
|
||||||
|
// case 'f':
|
||||||
|
// ret.append(QStringLiteral("\f"));
|
||||||
|
// break;
|
||||||
|
// // case '\'':
|
||||||
|
// // ret.append(QStringLiteral("\\'"));
|
||||||
|
// // break;
|
||||||
|
// case 't':
|
||||||
|
// ret.append(QStringLiteral("\t"));
|
||||||
|
// break;
|
||||||
|
// case 'v':
|
||||||
|
// ret.append(QStringLiteral("\v"));
|
||||||
|
// break;
|
||||||
|
// case '"':
|
||||||
|
// ret.append(QStringLiteral("\\\""));
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// default:
|
||||||
|
// ret.append(str.at(i));
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// ret.append(str.at(i));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return ret;
|
||||||
|
QString ret(str);
|
||||||
|
return ret.replace(QStringLiteral("''"), QStringLiteral("'"));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SqlSerializer::readString(QString &text, QString &out) const
|
||||||
|
{
|
||||||
|
int start = -1;
|
||||||
|
int end = -1;
|
||||||
|
|
||||||
|
for (int i = 0; i < text.length(); ++i) {
|
||||||
|
if (text.at(i) == QLatin1Char('"') && (i == 0 || text.at(i - 1) != QStringLiteral("\\"))) {
|
||||||
|
if (start == -1)
|
||||||
|
start = i;
|
||||||
|
else
|
||||||
|
end = i;
|
||||||
|
}
|
||||||
|
if (end != -1){
|
||||||
|
out = text.mid(start + 1, end - start - 1);
|
||||||
|
text = text.mid(end + 1);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant SqlSerializer::deserialize(const QString &value, const QMetaType::Type &type) const
|
||||||
|
{
|
||||||
|
return fromString(unescapeString(value), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SqlSerializer::serialize(const QVariant &value) const
|
||||||
|
{
|
||||||
|
return escapeString(toString(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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 SQLSERIALIZER_H
|
||||||
|
#define SQLSERIALIZER_H
|
||||||
|
|
||||||
|
#include <QVariant>
|
||||||
|
#include <QtNut/NutGlobal>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class SqlSerializer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SqlSerializer();
|
||||||
|
virtual ~SqlSerializer();
|
||||||
|
|
||||||
|
bool readString(QString &text, QString &out) const;
|
||||||
|
|
||||||
|
QVariant fromString(const QString &value, const QMetaType::Type &type) const;
|
||||||
|
QString toString(const QVariant &value) const;
|
||||||
|
QList<int> toListInt(const QString &s) const;
|
||||||
|
QList<int> toListInt(const QString &s, const QString &sep) const;
|
||||||
|
QList<qreal> toListReal(const QString &s) const;
|
||||||
|
QList<qreal> toListReal(const QString &s, const QString &sep) const;
|
||||||
|
QList<float> toListFloat(const QString &s) const;
|
||||||
|
|
||||||
|
QString fromList(const QList<int> &list) const;
|
||||||
|
QString fromList(const QList<qreal> &list) const;
|
||||||
|
QString fromList(const QList<float> &list) const;
|
||||||
|
QString fromVariantList(const QVariantList &list) const;
|
||||||
|
|
||||||
|
QVariant deserialize(const QString &value, const QMetaType::Type &type) const;
|
||||||
|
QString serialize(const QVariant &value) const;
|
||||||
|
private:
|
||||||
|
QString escapeString(const QString &str) const;
|
||||||
|
QString unescapeString(const QString &str) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // SQLSERIALIZER_H
|
||||||
|
|
@ -30,6 +30,8 @@
|
||||||
#include "abstracttableset.h"
|
#include "abstracttableset.h"
|
||||||
#include "propertysignalmapper.h"
|
#include "propertysignalmapper.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -89,17 +91,6 @@ void Table::add(AbstractTableSet *t)
|
||||||
|
|
||||||
void Table::propertyChanged(const QString &propName)
|
void Table::propertyChanged(const QString &propName)
|
||||||
{
|
{
|
||||||
//Q_D(Table);
|
|
||||||
// if (!d->model)
|
|
||||||
// d->model = TableModel::findByClassName(metaObject()->className());
|
|
||||||
|
|
||||||
// if (!d->model)
|
|
||||||
// qFatal ("model for class '%s' not found", qPrintable(metaObject()->className()));
|
|
||||||
|
|
||||||
// Q_FOREACH (FieldModel *f, d->model->fields())
|
|
||||||
// if(f->isPrimaryKey && propName == f->name && f->isAutoIncrement)
|
|
||||||
// return;
|
|
||||||
|
|
||||||
d.detach();
|
d.detach();
|
||||||
d->changedProperties.insert(propName);
|
d->changedProperties.insert(propName);
|
||||||
if (d->status == FetchedFromDB)
|
if (d->status == FetchedFromDB)
|
||||||
|
|
@ -121,7 +112,7 @@ void Table::clear()
|
||||||
d->changedProperties.clear();
|
d->changedProperties.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
QSet<QString> Table::changedProperties() const
|
const QSet<QString> &Table::changedProperties() const
|
||||||
{
|
{
|
||||||
//Q_D(const Table);
|
//Q_D(const Table);
|
||||||
return d->changedProperties;
|
return d->changedProperties;
|
||||||
|
|
@ -138,7 +129,7 @@ bool Table::setParentTable(Table *master, TableModel *masterModel, TableModel *m
|
||||||
// if (!d->model)
|
// if (!d->model)
|
||||||
// d->model = TableModel::findByClassName(metaObject()->className());
|
// d->model = TableModel::findByClassName(metaObject()->className());
|
||||||
|
|
||||||
Q_FOREACH (RelationModel *r, model->foreignKeys())
|
for (auto &r: model->foreignKeys())
|
||||||
if(r->masterClassName == masterClassName)
|
if(r->masterClassName == masterClassName)
|
||||||
{
|
{
|
||||||
setProperty(QString(r->localColumn).toLatin1().data(),
|
setProperty(QString(r->localColumn).toLatin1().data(),
|
||||||
|
|
@ -179,7 +170,7 @@ void Table::setParentTableSet(AbstractTableSet *parent)
|
||||||
AbstractTableSet *Table::childTableSet(const QString &name) const
|
AbstractTableSet *Table::childTableSet(const QString &name) const
|
||||||
{
|
{
|
||||||
//Q_D(const Table);
|
//Q_D(const Table);
|
||||||
Q_FOREACH (AbstractTableSet *t, d->childTableSets)
|
for (auto &t: qAsConst(d->childTableSets))
|
||||||
if (t->childClassName() == name)
|
if (t->childClassName() == name)
|
||||||
return t;
|
return t;
|
||||||
return Q_NULLPTR;
|
return Q_NULLPTR;
|
||||||
|
|
@ -230,3 +221,5 @@ void TablePrivate::refreshModel()
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
#include <QtNut/tablemodel.h>
|
#include <QtNut/tablemodel.h>
|
||||||
#include <QtNut/phrase.h>
|
#include <QtNut/phrase.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
@ -66,7 +68,7 @@ public:
|
||||||
|
|
||||||
AbstractTableSet *childTableSet(const QString &name) const;
|
AbstractTableSet *childTableSet(const QString &name) const;
|
||||||
|
|
||||||
QSet<QString> changedProperties() const;
|
const QSet<QString> &changedProperties() const;
|
||||||
|
|
||||||
bool setParentTable(Table *master, TableModel *masterModel, TableModel *model);
|
bool setParentTable(Table *master, TableModel *masterModel, TableModel *model);
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
@ -103,4 +105,9 @@ private:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(NUT_WRAP_NAMESPACE(Table)*)
|
||||||
|
Q_DECLARE_METATYPE(NUT_WRAP_NAMESPACE(Row<NUT_WRAP_NAMESPACE(Table)>))
|
||||||
|
|
||||||
#endif // TABLE_H
|
#endif // TABLE_H
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,33 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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/>.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Nut API. This header
|
||||||
|
// file may change from version to version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
#ifndef TABLEPRIVATE_H
|
#ifndef TABLEPRIVATE_H
|
||||||
#define TABLEPRIVATE_H
|
#define TABLEPRIVATE_H
|
||||||
|
|
||||||
|
|
@ -7,6 +37,8 @@
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
#include <QtNut/table.h>
|
#include <QtNut/table.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class TableModel;
|
class TableModel;
|
||||||
|
|
@ -31,4 +63,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // TABLEPRIVATE_H
|
#endif // TABLEPRIVATE_H
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,8 @@
|
||||||
#include <QtNut/databasemodel.h>
|
#include <QtNut/databasemodel.h>
|
||||||
#include <QtNut/abstracttablesetdata.h>
|
#include <QtNut/abstracttablesetdata.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
@ -98,16 +100,16 @@ Q_OUTOFLINE_TEMPLATE BulkInserter TableSet<T>::bulkInserter()
|
||||||
template<class T>
|
template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE int TableSet<T>::length() const
|
Q_OUTOFLINE_TEMPLATE int TableSet<T>::length() const
|
||||||
{
|
{
|
||||||
return data->childs.count();
|
return data->children.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
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_RAW_POINTER
|
#ifdef NUT_RAW_POINTER
|
||||||
return reinterpret_cast<T*>(data->childs.at(i));
|
return reinterpret_cast<T*>(data->children.at(i));
|
||||||
#else
|
#else
|
||||||
return data->childs.at(i).template objectCast<T>();
|
return data->children.at(i).template objectCast<T>();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -136,7 +138,7 @@ template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::append(Row<T> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
data->childs.append(t);
|
data->children.append(t);
|
||||||
// data->tables.insert(t.data());
|
// data->tables.insert(t.data());
|
||||||
// data->childRows.append(t.data());
|
// data->childRows.append(t.data());
|
||||||
|
|
||||||
|
|
@ -151,7 +153,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)
|
||||||
{
|
{
|
||||||
Q_FOREACH (Row<T> i, t)
|
for (auto &i: t)
|
||||||
append(i);
|
append(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -159,19 +161,21 @@ template<class T>
|
||||||
Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(Row<T> t)
|
Q_OUTOFLINE_TEMPLATE void TableSet<T>::remove(Row<T> t)
|
||||||
{
|
{
|
||||||
data.detach();
|
data.detach();
|
||||||
// data->childs.removeOne(t.data());
|
// data->children.removeOne(t.data());
|
||||||
// data->tables.remove(t.data());
|
// data->tables.remove(t.data());
|
||||||
data->childs.removeOne(t);
|
data->children.removeOne(t);
|
||||||
t->setStatus(Table::Deleted);
|
t->setStatus(Table::Deleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
Q_FOREACH (Row<T> i, t)
|
for (auto &i: t)
|
||||||
remove(i);
|
remove(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // TABLESET_H
|
#endif // TABLESET_H
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,9 @@
|
||||||
#include "databasemodel.h"
|
#include "databasemodel.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
#include "sqlserializer.h"
|
#include "sqlserializer.h"
|
||||||
|
#include "nut_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -114,7 +117,7 @@ QString AbstractSqlGenerator::recordsPhrase(TableModel *table)
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
QString ret = QString();
|
QString ret = QString();
|
||||||
Q_FOREACH (FieldModel *f, table->fields()) {
|
for (auto &f: table->fields()) {
|
||||||
if (!ret.isEmpty())
|
if (!ret.isEmpty())
|
||||||
ret.append(QLatin1String(", "));
|
ret.append(QLatin1String(", "));
|
||||||
ret.append(QStringLiteral("%1.%2 AS \"%1.%2\"").arg(table->name(), f->name));
|
ret.append(QStringLiteral("%1.%2 AS \"%1.%2\"").arg(table->name(), f->name));
|
||||||
|
|
@ -125,9 +128,9 @@ QString AbstractSqlGenerator::recordsPhrase(TableModel *table)
|
||||||
QString AbstractSqlGenerator::insertBulk(const QString &tableName, const PhraseList &ph, const QList<QVariantList> &vars)
|
QString AbstractSqlGenerator::insertBulk(const QString &tableName, const PhraseList &ph, const QList<QVariantList> &vars)
|
||||||
{
|
{
|
||||||
QString sql;
|
QString sql;
|
||||||
Q_FOREACH (QVariantList list, vars) {
|
for (auto &list: vars) {
|
||||||
QStringList values;
|
QStringList values;
|
||||||
Q_FOREACH (QVariant v, list)
|
for (auto &v: list)
|
||||||
values.append(escapeValue(v));
|
values.append(escapeValue(v));
|
||||||
|
|
||||||
if (!sql.isEmpty())
|
if (!sql.isEmpty())
|
||||||
|
|
@ -147,7 +150,7 @@ QString AbstractSqlGenerator::fieldDeclare(FieldModel *field)
|
||||||
if (type.isEmpty())
|
if (type.isEmpty())
|
||||||
return type;
|
return type;
|
||||||
|
|
||||||
QString ret = escaleFieldName(field->name) + QStringLiteral(" ") + type;
|
QString ret = escapeFieldName(field->name) + QStringLiteral(" ") + type;
|
||||||
if (field->notNull)
|
if (field->notNull)
|
||||||
ret.append(QStringLiteral(" NOT NULL"));
|
ret.append(QStringLiteral(" NOT NULL"));
|
||||||
|
|
||||||
|
|
@ -157,7 +160,7 @@ QString AbstractSqlGenerator::fieldDeclare(FieldModel *field)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AbstractSqlGenerator::escaleFieldName(const QString &fieldName) const
|
QString AbstractSqlGenerator::escapeFieldName(const QString &fieldName) const
|
||||||
{
|
{
|
||||||
return fieldName;
|
return fieldName;
|
||||||
}
|
}
|
||||||
|
|
@ -174,7 +177,7 @@ QString AbstractSqlGenerator::relationDeclare(const RelationModel *relation)
|
||||||
.arg(relation->localColumn, relation->slaveTable->name());
|
.arg(relation->localColumn, relation->slaveTable->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList AbstractSqlGenerator::diff(const DatabaseModel &lastModel,
|
QStringList AbstractSqlGenerator::diffDatabase(const DatabaseModel &lastModel,
|
||||||
const DatabaseModel &newModel)
|
const DatabaseModel &newModel)
|
||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
|
|
@ -185,7 +188,7 @@ QStringList AbstractSqlGenerator::diff(const DatabaseModel &lastModel,
|
||||||
for (i = unionModel.begin(); i != unionModel.end(); ++i) {
|
for (i = unionModel.begin(); i != unionModel.end(); ++i) {
|
||||||
TableModel *oldTable = lastModel.tableByName((*i)->name());
|
TableModel *oldTable = lastModel.tableByName((*i)->name());
|
||||||
TableModel *newTable = newModel.tableByName((*i)->name());
|
TableModel *newTable = newModel.tableByName((*i)->name());
|
||||||
QStringList sql = diff(oldTable, newTable);
|
QStringList sql = diffTable(oldTable, newTable);
|
||||||
if (!sql.isEmpty())
|
if (!sql.isEmpty())
|
||||||
ret << sql;
|
ret << sql;
|
||||||
|
|
||||||
|
|
@ -197,13 +200,16 @@ QStringList AbstractSqlGenerator::diff(const DatabaseModel &lastModel,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AbstractSqlGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
QString AbstractSqlGenerator::diffField(FieldModel *oldField, FieldModel *newField)
|
||||||
{
|
{
|
||||||
QString sql = QString();
|
if (!oldField && !newField)
|
||||||
|
return QString();
|
||||||
|
|
||||||
if (oldField && newField)
|
if (oldField && newField)
|
||||||
if (*oldField == *newField)
|
if (*oldField == *newField)
|
||||||
return sql;
|
return QString();
|
||||||
|
|
||||||
|
QString sql = QString();
|
||||||
if (!newField) {
|
if (!newField) {
|
||||||
sql = QStringLiteral("DROP COLUMN ") + oldField->name;
|
sql = QStringLiteral("DROP COLUMN ") + oldField->name;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -216,7 +222,7 @@ QString AbstractSqlGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList AbstractSqlGenerator::diff(TableModel *oldTable, TableModel *newTable)
|
QStringList AbstractSqlGenerator::diffTable(TableModel *oldTable, TableModel *newTable)
|
||||||
{
|
{
|
||||||
if (!newTable && !oldTable)
|
if (!newTable && !oldTable)
|
||||||
return QStringList();
|
return QStringList();
|
||||||
|
|
@ -232,28 +238,28 @@ QStringList AbstractSqlGenerator::diff(TableModel *oldTable, TableModel *newTabl
|
||||||
QList<QString> relations;
|
QList<QString> relations;
|
||||||
|
|
||||||
if (oldTable) {
|
if (oldTable) {
|
||||||
Q_FOREACH (FieldModel *f, oldTable->fields())
|
for (auto &f: oldTable->fields())
|
||||||
if (!fieldNames.contains(f->name))
|
if (!fieldNames.contains(f->name))
|
||||||
fieldNames.append(f->name);
|
fieldNames.append(f->name);
|
||||||
Q_FOREACH (RelationModel *r, oldTable->foreignKeys())
|
for (auto &r: oldTable->foreignKeys())
|
||||||
if (!relations.contains(r->localColumn))
|
if (!relations.contains(r->localColumn))
|
||||||
relations.append(r->localColumn);
|
relations.append(r->localColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH (FieldModel *f, newTable->fields())
|
for (auto &f: newTable->fields())
|
||||||
if (!fieldNames.contains(f->name))
|
if (!fieldNames.contains(f->name))
|
||||||
fieldNames.append(f->name);
|
fieldNames.append(f->name);
|
||||||
Q_FOREACH (RelationModel *r, newTable->foreignKeys())
|
for (auto &r: newTable->foreignKeys())
|
||||||
if (!relations.contains(r->localColumn))
|
if (!relations.contains(r->localColumn))
|
||||||
relations.append(r->localColumn);
|
relations.append(r->localColumn);
|
||||||
|
|
||||||
QStringList columnSql;
|
QStringList columnSql;
|
||||||
Q_FOREACH (QString fieldName, fieldNames) {
|
for (auto &fieldName: fieldNames) {
|
||||||
FieldModel *newField = newTable->field(fieldName);
|
FieldModel *newField = newTable->field(fieldName);
|
||||||
if (oldTable) {
|
if (oldTable) {
|
||||||
FieldModel *oldField = oldTable->field(fieldName);
|
FieldModel *oldField = oldTable->field(fieldName);
|
||||||
|
|
||||||
QString buffer = diff(oldField, newField);
|
QString buffer = diffField(oldField, newField);
|
||||||
if (!buffer.isEmpty())
|
if (!buffer.isEmpty())
|
||||||
columnSql << buffer;
|
columnSql << buffer;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -303,23 +309,23 @@ QStringList AbstractSqlGenerator::diffRelation(TableModel *oldTable, TableModel
|
||||||
QList<QString> relations;
|
QList<QString> relations;
|
||||||
|
|
||||||
if (oldTable) {
|
if (oldTable) {
|
||||||
Q_FOREACH (RelationModel *r, oldTable->foreignKeys())
|
for (auto &r: oldTable->foreignKeys())
|
||||||
if (!relations.contains(r->localColumn))
|
if (!relations.contains(r->localColumn))
|
||||||
relations.append(r->localColumn);
|
relations.append(r->localColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH (RelationModel *r, newTable->foreignKeys())
|
for (auto &r: newTable->foreignKeys())
|
||||||
if (!relations.contains(r->localColumn))
|
if (!relations.contains(r->localColumn))
|
||||||
relations.append(r->localColumn);
|
relations.append(r->localColumn);
|
||||||
|
|
||||||
QStringList columnSql;
|
QStringList columnSql;
|
||||||
Q_FOREACH (QString fieldName, relations) {
|
for (auto &fieldName: relations) {
|
||||||
RelationModel *newRelation = newTable->foreignKeyByField(fieldName);
|
RelationModel *newRelation = newTable->foreignKeyByField(fieldName);
|
||||||
RelationModel *oldRelation = nullptr;
|
RelationModel *oldRelation = nullptr;
|
||||||
if (oldTable)
|
if (oldTable)
|
||||||
oldRelation = oldTable->foreignKeyByField(fieldName);
|
oldRelation = oldTable->foreignKeyByField(fieldName);
|
||||||
|
|
||||||
QStringList buffer = diff(oldRelation, newRelation);
|
QStringList buffer = diffRelation2(oldRelation, newRelation);
|
||||||
if (!buffer.isEmpty())
|
if (!buffer.isEmpty())
|
||||||
columnSql << buffer.at(0);
|
columnSql << buffer.at(0);
|
||||||
}
|
}
|
||||||
|
|
@ -332,7 +338,7 @@ QStringList AbstractSqlGenerator::diffRelation(TableModel *oldTable, TableModel
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList AbstractSqlGenerator::diff(RelationModel *oldRel, RelationModel *newRel)
|
QStringList AbstractSqlGenerator::diffRelation2(RelationModel *oldRel, RelationModel *newRel)
|
||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
/*
|
/*
|
||||||
|
|
@ -478,7 +484,7 @@ QString AbstractSqlGenerator::insertRecord(Table *t, QString tableName)
|
||||||
|
|
||||||
if (changedPropertiesText != QLatin1String(""))
|
if (changedPropertiesText != QLatin1String(""))
|
||||||
changedPropertiesText.append(QStringLiteral(", "));
|
changedPropertiesText.append(QStringLiteral(", "));
|
||||||
changedPropertiesText.append(escaleFieldName(f));
|
changedPropertiesText.append(escapeFieldName(f));
|
||||||
}
|
}
|
||||||
sql = QStringLiteral("INSERT INTO %1 (%2) VALUES (%3)")
|
sql = QStringLiteral("INSERT INTO %1 (%2) VALUES (%3)")
|
||||||
.arg(tableName, changedPropertiesText, values.join(QStringLiteral(", ")));
|
.arg(tableName, changedPropertiesText, values.join(QStringLiteral(", ")));
|
||||||
|
|
@ -495,9 +501,9 @@ QString AbstractSqlGenerator::updateRecord(Table *t, QString tableName)
|
||||||
QString key = model->primaryKey();
|
QString key = model->primaryKey();
|
||||||
QStringList values;
|
QStringList values;
|
||||||
|
|
||||||
for (auto &f : t->changedProperties())
|
for (const auto &f : t->changedProperties())
|
||||||
if (f != key)
|
if (f != key)
|
||||||
values.append(f + QStringLiteral("=")
|
values.append(escapeFieldName(f) + QStringLiteral("=")
|
||||||
+ escapeValue(t->property(f.toLatin1().data())));
|
+ escapeValue(t->property(f.toLatin1().data())));
|
||||||
|
|
||||||
sql = QStringLiteral("UPDATE %1 SET %2 WHERE %3=%4")
|
sql = QStringLiteral("UPDATE %1 SET %2 WHERE %3=%4")
|
||||||
|
|
@ -600,11 +606,11 @@ QString AbstractSqlGenerator::selectCommand(const QString &tableName,
|
||||||
if (fields.data.count() == 0) {
|
if (fields.data.count() == 0) {
|
||||||
QSet<TableModel*> tables;
|
QSet<TableModel*> tables;
|
||||||
tables.insert(_database->model().tableByName(tableName));
|
tables.insert(_database->model().tableByName(tableName));
|
||||||
Q_FOREACH (RelationModel *rel, joins)
|
for (auto &rel: joins)
|
||||||
tables << rel->masterTable << rel->slaveTable;
|
tables << rel->masterTable << rel->slaveTable;
|
||||||
|
|
||||||
selectText = QString();
|
selectText = QString();
|
||||||
Q_FOREACH (TableModel *t, tables) {
|
for (auto &t: qAsConst(tables)) {
|
||||||
if (!selectText.isEmpty())
|
if (!selectText.isEmpty())
|
||||||
selectText.append(QStringLiteral(", "));
|
selectText.append(QStringLiteral(", "));
|
||||||
selectText.append(recordsPhrase(t));
|
selectText.append(recordsPhrase(t));
|
||||||
|
|
@ -689,8 +695,8 @@ QString AbstractSqlGenerator::updateCommand(const QString &tableName,
|
||||||
const ConditionalPhrase &where)
|
const ConditionalPhrase &where)
|
||||||
{
|
{
|
||||||
QString assigmentTexts = QString();
|
QString assigmentTexts = QString();
|
||||||
Q_FOREACH (PhraseData *d, assigments.data) {
|
for (auto &d: assigments.data) {
|
||||||
if (assigmentTexts != QStringLiteral(""))
|
if (assigmentTexts != QLatin1String())
|
||||||
assigmentTexts.append(QStringLiteral(", "));
|
assigmentTexts.append(QStringLiteral(", "));
|
||||||
|
|
||||||
assigmentTexts.append(createConditionalPhrase(d));
|
assigmentTexts.append(createConditionalPhrase(d));
|
||||||
|
|
@ -717,92 +723,23 @@ QString AbstractSqlGenerator::insertCommand(const QString &tableName, const Assi
|
||||||
|
|
||||||
QString fieldNames;
|
QString fieldNames;
|
||||||
QString values;
|
QString values;
|
||||||
Q_FOREACH (PhraseData *d, assigments.data) {
|
for (auto &d: assigments.data) {
|
||||||
if (!fieldNames.isEmpty())
|
if (!fieldNames.isEmpty())
|
||||||
fieldNames.append(QStringLiteral(", "));
|
fieldNames.append(QStringLiteral(", "));
|
||||||
|
|
||||||
if (!values.isEmpty())
|
if (!values.isEmpty())
|
||||||
values.append(QStringLiteral(", "));
|
values.append(QStringLiteral(", "));
|
||||||
|
|
||||||
fieldNames.append(escaleFieldName(QString::fromUtf8(d->left->fieldName)));
|
fieldNames.append(escapeFieldName(QString::fromUtf8(d->left->fieldName)));
|
||||||
values.append(escapeValue(d->operand));
|
values.append(escapeValue(d->operand));
|
||||||
}
|
}
|
||||||
return QStringLiteral("INSERT INTO %1 (%2) VALUES (%3);")
|
return QStringLiteral("INSERT INTO %1 (%2) VALUES (%3);")
|
||||||
.arg(tableName, fieldNames, values);
|
.arg(tableName, fieldNames, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
//QString SqlGeneratorBase::selectCommand(SqlGeneratorBase::AgregateType t,
|
|
||||||
// QString agregateArg,
|
|
||||||
// QString tableName,
|
|
||||||
// QList<WherePhrase> &wheres,
|
|
||||||
// QList<WherePhrase> &orders,
|
|
||||||
// QList<RelationModel*> joins,
|
|
||||||
// int skip, int take)
|
|
||||||
//{
|
|
||||||
// Q_UNUSED(take)
|
|
||||||
// Q_UNUSED(skip)
|
|
||||||
|
|
||||||
// QStringList joinedOrders;
|
|
||||||
// QString select = agregateText(t, agregateArg);
|
|
||||||
|
|
||||||
// //TODO: temporatory disabled
|
|
||||||
// if (t == SelectAll) {
|
|
||||||
// QSet<TableModel*> tables;
|
|
||||||
// tables.insert(_database->model().tableByName(tableName));
|
|
||||||
// Q_FOREACH (RelationModel *rel, joins)
|
|
||||||
// tables << rel->masterTable << rel->slaveTable;
|
|
||||||
|
|
||||||
// select = "";
|
|
||||||
// Q_FOREACH (TableModel *t, tables) {
|
|
||||||
// if (!select.isEmpty())
|
|
||||||
// select.append(", ");
|
|
||||||
// select.append(recordsPhrase(t));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// QString from = join(tableName, joins, &joinedOrders);
|
|
||||||
// QString where = createWhere(wheres);
|
|
||||||
// QString orderText = joinedOrders.join(", ");
|
|
||||||
|
|
||||||
// Q_FOREACH (WherePhrase p, orders) {
|
|
||||||
// if (orderText != "")
|
|
||||||
// orderText.append(", ");
|
|
||||||
// orderText.append(phraseOrder(p.data()));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// QString sql = "SELECT " + select + " FROM " + from;
|
|
||||||
|
|
||||||
// if (where != "")
|
|
||||||
// sql.append(" WHERE " + where);
|
|
||||||
|
|
||||||
// if (orderText != "")
|
|
||||||
// sql.append(" ORDER BY " + orderText);
|
|
||||||
|
|
||||||
// for (int i = 0; i < _database->model().count(); i++)
|
|
||||||
// sql = sql.replace(_database->model().at(i)->className() + ".",
|
|
||||||
// _database->model().at(i)->name() + ".");
|
|
||||||
|
|
||||||
// replaceTableNames(sql);
|
|
||||||
|
|
||||||
// return sql + " ";
|
|
||||||
//}
|
|
||||||
|
|
||||||
//QString SqlGeneratorBase::createWhere(QList<WherePhrase> &wheres)
|
|
||||||
//{
|
|
||||||
// QString whereText = "";
|
|
||||||
|
|
||||||
// Q_FOREACH (WherePhrase w, wheres) {
|
|
||||||
// if (whereText != "")
|
|
||||||
// whereText.append(" AND ");
|
|
||||||
|
|
||||||
// whereText.append(phrase(w.data()));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return whereText;
|
|
||||||
//}
|
|
||||||
|
|
||||||
void AbstractSqlGenerator::replaceTableNames(QString &command)
|
void AbstractSqlGenerator::replaceTableNames(QString &command)
|
||||||
{
|
{
|
||||||
Q_FOREACH (TableModel *m, _database->model())
|
for (auto &m: _database->model())
|
||||||
command = command
|
command = command
|
||||||
.replace(QStringLiteral("[") + m->className()
|
.replace(QStringLiteral("[") + m->className()
|
||||||
+ QStringLiteral("]"), m->name());
|
+ QStringLiteral("]"), m->name());
|
||||||
|
|
@ -810,10 +747,10 @@ void AbstractSqlGenerator::replaceTableNames(QString &command)
|
||||||
|
|
||||||
void AbstractSqlGenerator::removeTableNames(QString &command)
|
void AbstractSqlGenerator::removeTableNames(QString &command)
|
||||||
{
|
{
|
||||||
Q_FOREACH (TableModel *m, _database->model())
|
for (auto &m: _database->model())
|
||||||
command = command.replace(QStringLiteral("[")
|
command = command.replace(QStringLiteral("[")
|
||||||
+ m->className()
|
+ m->className()
|
||||||
+ QStringLiteral("]."), QStringLiteral(""));
|
+ QStringLiteral("]."), QLatin1String());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AbstractSqlGenerator::dateTimePartName(const PhraseData::Condition &op) const
|
QString AbstractSqlGenerator::dateTimePartName(const PhraseData::Condition &op) const
|
||||||
|
|
@ -891,13 +828,13 @@ QString AbstractSqlGenerator::dateTimePartName(const PhraseData::Condition &op)
|
||||||
|
|
||||||
QString AbstractSqlGenerator::escapeValue(const QVariant &v) const
|
QString AbstractSqlGenerator::escapeValue(const QVariant &v) const
|
||||||
{
|
{
|
||||||
if (v.type() == QVariant::String && v.toString().isEmpty())
|
if (VARIANT_TYPE_COMPARE(v, String) && v.toString().isEmpty())
|
||||||
return QStringLiteral("''");
|
return QStringLiteral("''");
|
||||||
|
|
||||||
if (v.type() == QVariant::List) {
|
if (VARIANT_TYPE_COMPARE_X(v, QVariant::List, QMetaType::QVariantList)) {
|
||||||
auto list = v.toList();
|
auto list = v.toList();
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
Q_FOREACH (QVariant vi, list) {
|
for (auto &vi: list) {
|
||||||
ret.append(QStringLiteral("'")
|
ret.append(QStringLiteral("'")
|
||||||
+ _serializer->serialize(vi)
|
+ _serializer->serialize(vi)
|
||||||
+ QStringLiteral("'"));
|
+ QStringLiteral("'"));
|
||||||
|
|
@ -1121,7 +1058,7 @@ QString AbstractSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
QString AbstractSqlGenerator::createOrderPhrase(const PhraseList &ph)
|
QString AbstractSqlGenerator::createOrderPhrase(const PhraseList &ph)
|
||||||
{
|
{
|
||||||
QString ret = QString();
|
QString ret = QString();
|
||||||
Q_FOREACH (const PhraseData *d, ph.data) {
|
for (const auto &d: ph.data) {
|
||||||
if (!ret.isEmpty())
|
if (!ret.isEmpty())
|
||||||
ret.append(QStringLiteral(", "));
|
ret.append(QStringLiteral(", "));
|
||||||
ret.append(d->toString());
|
ret.append(d->toString());
|
||||||
|
|
@ -1135,10 +1072,10 @@ QString AbstractSqlGenerator::createOrderPhrase(const PhraseList &ph)
|
||||||
QString AbstractSqlGenerator::createFieldPhrase(const PhraseList &ph)
|
QString AbstractSqlGenerator::createFieldPhrase(const PhraseList &ph)
|
||||||
{
|
{
|
||||||
QString ret = QString();
|
QString ret = QString();
|
||||||
Q_FOREACH (const PhraseData *d, ph.data) {
|
for (const auto &d: ph.data) {
|
||||||
if (!ret.isEmpty())
|
if (!ret.isEmpty())
|
||||||
ret.append(QStringLiteral(", "));
|
ret.append(QStringLiteral(", "));
|
||||||
ret.append(d->toString());
|
ret.append("`" + d->toString() + "`");
|
||||||
if (d->isNot)
|
if (d->isNot)
|
||||||
qDebug() << "Operator ! is ignored in fields phrase";
|
qDebug() << "Operator ! is ignored in fields phrase";
|
||||||
}
|
}
|
||||||
|
|
@ -1147,7 +1084,7 @@ QString AbstractSqlGenerator::createFieldPhrase(const PhraseList &ph)
|
||||||
|
|
||||||
void AbstractSqlGenerator::createInsertPhrase(const AssignmentPhraseList &ph, QString &fields, QString &values)
|
void AbstractSqlGenerator::createInsertPhrase(const AssignmentPhraseList &ph, QString &fields, QString &values)
|
||||||
{
|
{
|
||||||
Q_FOREACH (PhraseData *d, ph.data) {
|
for (auto &d: ph.data) {
|
||||||
if (!fields.isEmpty())
|
if (!fields.isEmpty())
|
||||||
fields.append(QStringLiteral(", "));
|
fields.append(QStringLiteral(", "));
|
||||||
|
|
||||||
|
|
@ -1175,3 +1112,5 @@ void AbstractSqlGenerator::createInsertPhrase(const AssignmentPhraseList &ph, QS
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,8 @@
|
||||||
|
|
||||||
#include <QtNut/phrase.h>
|
#include <QtNut/phrase.h>
|
||||||
|
|
||||||
class SqlSerializer;
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -37,6 +38,7 @@ class DatabaseModel;
|
||||||
class TableModel;
|
class TableModel;
|
||||||
class Database;
|
class Database;
|
||||||
struct RelationModel;
|
struct RelationModel;
|
||||||
|
class SqlSerializer;
|
||||||
class NUT_EXPORT AbstractSqlGenerator : public QObject
|
class NUT_EXPORT AbstractSqlGenerator : public QObject
|
||||||
{
|
{
|
||||||
// Q_OBJECT
|
// Q_OBJECT
|
||||||
|
|
@ -80,7 +82,7 @@ public:
|
||||||
//fields
|
//fields
|
||||||
virtual QString fieldType(FieldModel *field) = 0;
|
virtual QString fieldType(FieldModel *field) = 0;
|
||||||
virtual QString fieldDeclare(FieldModel *field);
|
virtual QString fieldDeclare(FieldModel *field);
|
||||||
virtual QString escaleFieldName(const QString &fieldName) const;
|
virtual QString escapeFieldName(const QString &fieldName) const;
|
||||||
virtual QStringList constraints(TableModel *table);
|
virtual QStringList constraints(TableModel *table);
|
||||||
virtual QString escapeValue(const QVariant &v) const;
|
virtual QString escapeValue(const QVariant &v) const;
|
||||||
virtual QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue);
|
virtual QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue);
|
||||||
|
|
@ -91,11 +93,11 @@ public:
|
||||||
|
|
||||||
virtual QString relationDeclare(const RelationModel *relation);
|
virtual QString relationDeclare(const RelationModel *relation);
|
||||||
|
|
||||||
virtual QStringList diff(const DatabaseModel &lastModel, const DatabaseModel &newModel);
|
virtual QStringList diffDatabase(const DatabaseModel &lastModel, const DatabaseModel &newModel);
|
||||||
virtual QString diff(FieldModel *oldField, FieldModel *newField);
|
virtual QString diffField(FieldModel *oldField, FieldModel *newField);
|
||||||
virtual QStringList diff(TableModel *oldTable, TableModel *newTable);
|
virtual QStringList diffTable(TableModel *oldTable, TableModel *newTable);
|
||||||
virtual QStringList diffRelation(TableModel *oldTable, TableModel *newTable);
|
virtual QStringList diffRelation(TableModel *oldTable, TableModel *newTable);
|
||||||
virtual QStringList diff(RelationModel *oldRel, RelationModel *newRel);
|
virtual QStringList diffRelation2(RelationModel *oldRel, RelationModel *newRel);
|
||||||
|
|
||||||
virtual QString join(const QString &mainTable,
|
virtual QString join(const QString &mainTable,
|
||||||
const QList<RelationModel*> &list,
|
const QList<RelationModel*> &list,
|
||||||
|
|
@ -169,4 +171,6 @@ protected:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_ABSTRACTSQLGENERATOR_H
|
#endif // NUT_ABSTRACTSQLGENERATOR_H
|
||||||
|
|
|
||||||
|
|
@ -26,12 +26,17 @@
|
||||||
#include <QtCore/QTime>
|
#include <QtCore/QTime>
|
||||||
#include <QtCore/QDate>
|
#include <QtCore/QDate>
|
||||||
#include <QtCore/QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
|
#include <QtCore/QUuid>
|
||||||
|
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
# include <QtGui/QPolygon>
|
# include <QtGui/QPolygon>
|
||||||
# include <QtGui/QPolygonF>
|
# include <QtGui/QPolygonF>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "sqlserializer.h"
|
#include "sqlserializer.h"
|
||||||
|
#include "nut_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -83,15 +88,15 @@ QString MySqlGenerator::fieldType(FieldModel *field)
|
||||||
dbType = QStringLiteral("TEXT");
|
dbType = QStringLiteral("TEXT");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case QMetaType::QUuid:
|
||||||
|
dbType = QStringLiteral("VARCHAR(38)");
|
||||||
|
break;
|
||||||
|
|
||||||
case QMetaType::QPolygon:
|
case QMetaType::QPolygon:
|
||||||
case QMetaType::QPolygonF:
|
case QMetaType::QPolygonF:
|
||||||
// dbType = "POLYGON";
|
// dbType = "POLYGON";
|
||||||
// break;
|
// break;
|
||||||
|
|
||||||
case QMetaType::QUuid:
|
|
||||||
// dbType = "VARCHAR(64)";
|
|
||||||
// break;
|
|
||||||
|
|
||||||
case QMetaType::QPoint:
|
case QMetaType::QPoint:
|
||||||
case QMetaType::QPointF:
|
case QMetaType::QPointF:
|
||||||
|
|
@ -114,7 +119,7 @@ QString MySqlGenerator::fieldType(FieldModel *field)
|
||||||
default:
|
default:
|
||||||
qWarning("Type %s::%s(%d) is not supported",
|
qWarning("Type %s::%s(%d) is not supported",
|
||||||
qPrintable(field->name),
|
qPrintable(field->name),
|
||||||
QMetaType::typeName(field->type),
|
METATYPE_TO_NAME(field->type),
|
||||||
field->type);
|
field->type);
|
||||||
dbType = QString();
|
dbType = QString();
|
||||||
}
|
}
|
||||||
|
|
@ -127,18 +132,21 @@ 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 (VARIANT_TYPE_COMPARE_X(v, Bool, Bool))
|
||||||
return v.toBool() ? QStringLiteral("1") : QStringLiteral("0");
|
return v.toBool() ? QStringLiteral("1") : QStringLiteral("0");
|
||||||
|
|
||||||
if (v.type() == QVariant::Time)
|
if (VARIANT_TYPE_COMPARE(v, Time))
|
||||||
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::Date)
|
if (VARIANT_TYPE_COMPARE(v, Date))
|
||||||
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::DateTime)
|
if (VARIANT_TYPE_COMPARE(v, DateTime))
|
||||||
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
||||||
|
|
||||||
|
if (VARIANT_TYPE_COMPARE(v, Uuid))
|
||||||
|
return QStringLiteral("'") + v.toUuid().toString() + QStringLiteral("'");
|
||||||
|
|
||||||
//#ifdef QT_GUI_LIB
|
//#ifdef QT_GUI_LIB
|
||||||
// if (v.type() == QVariant::Polygon) {
|
// if (v.type() == QVariant::Polygon) {
|
||||||
// QString ret;
|
// QString ret;
|
||||||
|
|
@ -194,7 +202,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(",");
|
||||||
// Q_FOREACH (QString v, parts) {
|
// for (auto &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 +218,7 @@ QVariant MySqlGenerator::unescapeValue(const QMetaType::Type &type, const QVaria
|
||||||
// return pol;
|
// return pol;
|
||||||
|
|
||||||
// QStringList parts = p.split(",");
|
// QStringList parts = p.split(",");
|
||||||
// Q_FOREACH (QString v, parts) {
|
// for (auto &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,6 +237,9 @@ QVariant MySqlGenerator::unescapeValue(const QMetaType::Type &type, const QVaria
|
||||||
if (type == QMetaType::QDate)
|
if (type == QMetaType::QDate)
|
||||||
return dbValue.toDate();
|
return dbValue.toDate();
|
||||||
|
|
||||||
|
if (type == QMetaType::QUuid)
|
||||||
|
return QUuid::fromString(dbValue.toString());
|
||||||
|
|
||||||
return AbstractSqlGenerator::unescapeValue(type, dbValue);
|
return AbstractSqlGenerator::unescapeValue(type, dbValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,12 +251,12 @@ bool MySqlGenerator::readInsideParentese(QString &text, QString &out)
|
||||||
for (int i = 0; i < text.length(); ++i) {
|
for (int i = 0; i < text.length(); ++i) {
|
||||||
QChar ch = text.at(i);
|
QChar ch = text.at(i);
|
||||||
|
|
||||||
if (ch == '(') {
|
if (ch == QLatin1Char('(')) {
|
||||||
if (start == -1)
|
if (start == -1)
|
||||||
start = i;
|
start = i;
|
||||||
pc++;
|
pc++;
|
||||||
}
|
}
|
||||||
if (ch == ')') {
|
if (ch == QLatin1Char(')')) {
|
||||||
pc--;
|
pc--;
|
||||||
|
|
||||||
if (!pc && end == -1)
|
if (!pc && end == -1)
|
||||||
|
|
@ -315,11 +326,20 @@ QString MySqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
case PhraseData::AddMinutes:
|
case PhraseData::AddMinutes:
|
||||||
case PhraseData::AddMinutesDateTime:
|
case PhraseData::AddMinutesDateTime:
|
||||||
case PhraseData::AddSeconds:
|
case PhraseData::AddSeconds:
|
||||||
case PhraseData::AddSecondsDateTime:
|
case PhraseData::AddSecondsDateTime: {
|
||||||
return QStringLiteral("DATE_ADD(%1, INTERVAL %2 %3)")
|
auto interval = d->operand.toInt();
|
||||||
.arg(createConditionalPhrase(d->left),
|
|
||||||
d->operand.toString(),
|
if (interval < 0)
|
||||||
AbstractSqlGenerator::dateTimePartName(op));
|
return QStringLiteral("DATE_SUB(%1, INTERVAL %2 %3)")
|
||||||
|
.arg(createConditionalPhrase(d->left))
|
||||||
|
.arg(-interval)
|
||||||
|
.arg(AbstractSqlGenerator::dateTimePartName(op));
|
||||||
|
else
|
||||||
|
return QStringLiteral("DATE_ADD(%1, INTERVAL %2 %3)")
|
||||||
|
.arg(createConditionalPhrase(d->left))
|
||||||
|
.arg(interval)
|
||||||
|
.arg(AbstractSqlGenerator::dateTimePartName(op));
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -362,8 +382,11 @@ QString MySqlGenerator::primaryKeyConstraint(const TableModel *table) const
|
||||||
.arg(table->primaryKey());
|
.arg(table->primaryKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MySqlGenerator::escaleFieldName(const QString &fieldName) const
|
QString MySqlGenerator::escapeFieldName(const QString &fieldName) const
|
||||||
{
|
{
|
||||||
return "`" + fieldName + "`";
|
return "`" + fieldName + "`";
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#include <QtNut/abstractsqlgenerator.h>
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT MySqlGenerator : public AbstractSqlGenerator
|
class NUT_EXPORT MySqlGenerator : public AbstractSqlGenerator
|
||||||
|
|
@ -40,7 +42,7 @@ public:
|
||||||
QString createConditionalPhrase(const PhraseData *d) const override;
|
QString createConditionalPhrase(const PhraseData *d) const override;
|
||||||
void appendSkipTake(QString &sql, int skip, int take) override;
|
void appendSkipTake(QString &sql, int skip, int take) override;
|
||||||
QString primaryKeyConstraint(const TableModel *table) const override;
|
QString primaryKeyConstraint(const TableModel *table) const override;
|
||||||
QString escaleFieldName(const QString &fieldName) const override;
|
QString escapeFieldName(const QString &fieldName) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool readInsideParentese(QString &text, QString &out);
|
bool readInsideParentese(QString &text, QString &out);
|
||||||
|
|
@ -48,4 +50,6 @@ private:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // MYSQLGENERATOR_H
|
#endif // MYSQLGENERATOR_H
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
#include "sqlserializer.h"
|
#include "sqlserializer.h"
|
||||||
|
#include "nut_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -43,12 +46,12 @@ bool PostgreSqlGenerator::readInsideParentese(QString &text, QString &out)
|
||||||
for (int i = 0; i < text.length(); ++i) {
|
for (int i = 0; i < text.length(); ++i) {
|
||||||
QChar ch = text.at(i);
|
QChar ch = text.at(i);
|
||||||
|
|
||||||
if (ch == '(') {
|
if (ch == QLatin1Char('(')) {
|
||||||
if (start == -1)
|
if (start == -1)
|
||||||
start = i;
|
start = i;
|
||||||
pc++;
|
pc++;
|
||||||
}
|
}
|
||||||
if (ch == ')') {
|
if (ch == QLatin1Char(')')) {
|
||||||
pc--;
|
pc--;
|
||||||
|
|
||||||
if (!pc && end == -1)
|
if (!pc && end == -1)
|
||||||
|
|
@ -63,14 +66,14 @@ bool PostgreSqlGenerator::readInsideParentese(QString &text, QString &out)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PostgreSqlGenerator::isPostGisType(const QVariant::Type &t) const
|
bool PostgreSqlGenerator::isPostGisType(const QMetaType::Type &t) const
|
||||||
{
|
{
|
||||||
return t == QVariant::Point
|
return t == QMetaType::QPoint
|
||||||
|| t == QVariant::PointF
|
|| t == QMetaType::QPointF
|
||||||
|| t == QVariant::Rect
|
|| t == QMetaType::QRect
|
||||||
|| t == QVariant::RectF
|
|| t == QMetaType::QRectF
|
||||||
|| t == QVariant::Polygon
|
|| t == QMetaType::QPolygon
|
||||||
|| t == QVariant::PolygonF;
|
|| t == QMetaType::QPolygonF;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostgreSqlGenerator::PostgreSqlGenerator(Database *parent) : AbstractSqlGenerator (parent)
|
PostgreSqlGenerator::PostgreSqlGenerator(Database *parent) : AbstractSqlGenerator (parent)
|
||||||
|
|
@ -189,13 +192,16 @@ QString PostgreSqlGenerator::fieldType(FieldModel *field)
|
||||||
return dbType;
|
return dbType;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString PostgreSqlGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
QString PostgreSqlGenerator::diffField(FieldModel *oldField, FieldModel *newField)
|
||||||
{
|
{
|
||||||
QString sql = QString();
|
if(!oldField && !newField)
|
||||||
|
return QString();
|
||||||
|
|
||||||
if(oldField && newField)
|
if(oldField && newField)
|
||||||
if(*oldField == *newField)
|
if(*oldField == *newField)
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
|
QString sql = QString();
|
||||||
if(!newField){
|
if(!newField){
|
||||||
sql = QStringLiteral("DROP COLUMN ") + oldField->name;
|
sql = QStringLiteral("DROP COLUMN ") + oldField->name;
|
||||||
}else{
|
}else{
|
||||||
|
|
@ -212,25 +218,25 @@ 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 (VARIANT_TYPE_COMPARE(v, Time))
|
||||||
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::Date)
|
if (VARIANT_TYPE_COMPARE(v, Date))
|
||||||
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::DateTime)
|
if (VARIANT_TYPE_COMPARE(v, DateTime))
|
||||||
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::StringList)
|
if (VARIANT_TYPE_COMPARE(v, StringList))
|
||||||
return QStringLiteral("'{")
|
return QStringLiteral("'{")
|
||||||
+ v.toStringList().join(QStringLiteral(","))
|
+ v.toStringList().join(QStringLiteral(","))
|
||||||
+ QStringLiteral("}'");
|
+ QStringLiteral("}'");
|
||||||
|
|
||||||
if (v.type() == QVariant::Point) {
|
if (VARIANT_TYPE_COMPARE(v, Point)) {
|
||||||
QPoint pt = v.toPoint();
|
QPoint pt = v.toPoint();
|
||||||
return QStringLiteral("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 (VARIANT_TYPE_COMPARE(v, PointF)) {
|
||||||
QPointF pt = v.toPointF();
|
QPointF pt = v.toPointF();
|
||||||
return QStringLiteral("point(%1, %2)").arg(pt.x()).arg(pt.y());
|
return QStringLiteral("point(%1, %2)").arg(pt.x()).arg(pt.y());
|
||||||
}
|
}
|
||||||
|
|
@ -241,7 +247,7 @@ QString PostgreSqlGenerator::escapeValue(const QVariant &v) const
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
if (v.type() == QVariant::Polygon) {
|
if (VARIANT_TYPE_COMPARE(v, Polygon)) {
|
||||||
QString ret;
|
QString ret;
|
||||||
QPoint pt;
|
QPoint pt;
|
||||||
QPolygon pol = v.value<QPolygon>();
|
QPolygon pol = v.value<QPolygon>();
|
||||||
|
|
@ -254,7 +260,7 @@ QString PostgreSqlGenerator::escapeValue(const QVariant &v) const
|
||||||
}
|
}
|
||||||
return QStringLiteral("'((") + ret + QStringLiteral("))'");
|
return QStringLiteral("'((") + ret + QStringLiteral("))'");
|
||||||
}
|
}
|
||||||
if (v.type() == QVariant::PolygonF) {
|
if (VARIANT_TYPE_COMPARE(v, PolygonF)) {
|
||||||
QString ret;
|
QString ret;
|
||||||
QPointF pt;
|
QPointF pt;
|
||||||
QPolygonF pol = v.value<QPolygonF>();
|
QPolygonF pol = v.value<QPolygonF>();
|
||||||
|
|
@ -287,20 +293,20 @@ QVariant PostgreSqlGenerator::unescapeValue(const QMetaType::Type &type, const Q
|
||||||
return AbstractSqlGenerator::unescapeValue(QMetaType::QPoint,
|
return AbstractSqlGenerator::unescapeValue(QMetaType::QPoint,
|
||||||
dbValue.toString()
|
dbValue.toString()
|
||||||
.replace(QStringLiteral("("),
|
.replace(QStringLiteral("("),
|
||||||
QStringLiteral(""))
|
QLatin1String())
|
||||||
.replace(QStringLiteral(")"),
|
.replace(QStringLiteral(")"),
|
||||||
QStringLiteral("")));
|
QLatin1String()));
|
||||||
if (type == QMetaType::QPointF)
|
if (type == QMetaType::QPointF)
|
||||||
return AbstractSqlGenerator::unescapeValue(QMetaType::QPointF,
|
return AbstractSqlGenerator::unescapeValue(QMetaType::QPointF,
|
||||||
dbValue.toString()
|
dbValue.toString()
|
||||||
.replace(QStringLiteral("("),
|
.replace(QStringLiteral("("),
|
||||||
QStringLiteral(""))
|
QLatin1String())
|
||||||
.replace(QStringLiteral(")"),
|
.replace(QStringLiteral(")"),
|
||||||
QStringLiteral("")));
|
QLatin1String()));
|
||||||
if (type == QMetaType::QStringList)
|
if (type == QMetaType::QStringList)
|
||||||
return dbValue.toString()
|
return dbValue.toString()
|
||||||
.replace(QStringLiteral("{"), QStringLiteral(""))
|
.replace(QStringLiteral("{"), QLatin1String())
|
||||||
.replace(QStringLiteral("}"), QStringLiteral(""))
|
.replace(QStringLiteral("}"), QLatin1String())
|
||||||
.split(QStringLiteral(","));
|
.split(QStringLiteral(","));
|
||||||
|
|
||||||
#ifdef QT_GUI_LIB
|
#ifdef QT_GUI_LIB
|
||||||
|
|
@ -340,6 +346,17 @@ QVariant PostgreSqlGenerator::unescapeValue(const QMetaType::Type &type, const Q
|
||||||
return AbstractSqlGenerator::unescapeValue(type, dbValue);
|
return AbstractSqlGenerator::unescapeValue(type, dbValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PostgreSqlGenerator::appendSkipTake(QString &sql, int skip, int take)
|
||||||
|
{
|
||||||
|
if (take > 0 && skip > 0) {
|
||||||
|
sql.append(QStringLiteral(" LIMIT %1 OFFSET %2")
|
||||||
|
.arg(take)
|
||||||
|
.arg(skip));
|
||||||
|
} else if (take > 0) {
|
||||||
|
sql.append(QStringLiteral(" LIMIT %1").arg(take));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
{
|
{
|
||||||
if (!d)
|
if (!d)
|
||||||
|
|
@ -353,7 +370,7 @@ 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(METATYPE_ID(d->operand)) && d->operatorCond == PhraseData::Equal) {
|
||||||
return QStringLiteral("%1 ~= %2")
|
return QStringLiteral("%1 ~= %2")
|
||||||
.arg(AbstractSqlGenerator::createConditionalPhrase(d->left),
|
.arg(AbstractSqlGenerator::createConditionalPhrase(d->left),
|
||||||
escapeValue(d->operand));
|
escapeValue(d->operand));
|
||||||
|
|
@ -402,3 +419,5 @@ QString PostgreSqlGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -25,30 +25,33 @@
|
||||||
|
|
||||||
#include <QtNut/abstractsqlgenerator.h>
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT PostgreSqlGenerator : public AbstractSqlGenerator
|
class NUT_EXPORT PostgreSqlGenerator : public AbstractSqlGenerator
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool readInsideParentese(QString &text, QString &out);
|
bool readInsideParentese(QString &text, QString &out);
|
||||||
bool isPostGisType(const QVariant::Type &t) const;
|
bool isPostGisType(const QMetaType::Type &t) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PostgreSqlGenerator(Database *parent = nullptr);
|
explicit PostgreSqlGenerator(Database *parent = nullptr);
|
||||||
|
|
||||||
QString fieldType(FieldModel *field) override;
|
QString fieldType(FieldModel *field) override;
|
||||||
|
|
||||||
QString diff(FieldModel *oldField, FieldModel *newField) override;
|
QString diffField(FieldModel *oldField, FieldModel *newField) override;
|
||||||
|
|
||||||
// SqlGeneratorBase interface
|
|
||||||
public:
|
|
||||||
QString escapeValue(const QVariant &v) const override;
|
QString escapeValue(const QVariant &v) const override;
|
||||||
QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue) override;
|
QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue) override;
|
||||||
|
void appendSkipTake(QString &sql, int skip = -1, int take = -1) override;
|
||||||
|
|
||||||
// SqlGeneratorBase interface
|
|
||||||
protected:
|
protected:
|
||||||
QString createConditionalPhrase(const PhraseData *d) const override;
|
QString createConditionalPhrase(const PhraseData *d) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // POSTGRESQLGENERATOR_H
|
#endif // POSTGRESQLGENERATOR_H
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@
|
||||||
#include "sqlitegenerator.h"
|
#include "sqlitegenerator.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
|
#include "nut_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -116,15 +119,18 @@ bool SqliteGenerator::supportAutoIncrement(const QMetaType::Type &type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QStringList SqliteGenerator::diff(TableModel *oldTable, TableModel *newTable)
|
QStringList SqliteGenerator::diffTable(TableModel *oldTable, TableModel *newTable)
|
||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
|
|
||||||
|
if (!oldTable && !newTable)
|
||||||
|
return ret;
|
||||||
|
|
||||||
if (oldTable && newTable)
|
if (oldTable && newTable)
|
||||||
if (*oldTable == *newTable)
|
if (*oldTable == *newTable)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
QStringList newTableSql = AbstractSqlGenerator::diff(nullptr, newTable);
|
QStringList newTableSql = AbstractSqlGenerator::diffTable(nullptr, newTable);
|
||||||
|
|
||||||
if (!newTable)
|
if (!newTable)
|
||||||
return QStringList() << QStringLiteral("DROP TABLE ") + oldTable->name();
|
return QStringList() << QStringLiteral("DROP TABLE ") + oldTable->name();
|
||||||
|
|
@ -135,22 +141,22 @@ QStringList SqliteGenerator::diff(TableModel *oldTable, TableModel *newTable)
|
||||||
QList<QString> fieldNames;
|
QList<QString> fieldNames;
|
||||||
QList<QString> relations;
|
QList<QString> relations;
|
||||||
|
|
||||||
Q_FOREACH (FieldModel *f, oldTable->fields())
|
for (auto &f: oldTable->fields())
|
||||||
if (!fieldNames.contains(f->name))
|
if (!fieldNames.contains(f->name))
|
||||||
fieldNames.append(f->name);
|
fieldNames.append(f->name);
|
||||||
Q_FOREACH (RelationModel *r, oldTable->foreignKeys())
|
for (auto &r: oldTable->foreignKeys())
|
||||||
if (!relations.contains(r->localColumn))
|
if (!relations.contains(r->localColumn))
|
||||||
relations.append(r->localColumn);
|
relations.append(r->localColumn);
|
||||||
|
|
||||||
Q_FOREACH (FieldModel *f, newTable->fields())
|
for (auto &f: newTable->fields())
|
||||||
if (!fieldNames.contains(f->name))
|
if (!fieldNames.contains(f->name))
|
||||||
fieldNames.append(f->name);
|
fieldNames.append(f->name);
|
||||||
Q_FOREACH (RelationModel *r, newTable->foreignKeys())
|
for (auto &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;
|
||||||
Q_FOREACH (FieldModel *f, oldTable->fields()) {
|
for (auto &f: oldTable->fields()) {
|
||||||
if (!newTable->field(f->name))
|
if (!newTable->field(f->name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -238,9 +244,8 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
int i = d->operand.toInt();
|
int i = d->operand.toInt();
|
||||||
return QStringLiteral("DATE(%1,'%2 %3')")
|
return QStringLiteral("DATE(%1,'%2 %3')")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
(i < 0 ? QStringLiteral("") : QStringLiteral("+")) + QString::number(i),
|
(i < 0 ? QLatin1String() : QStringLiteral("+")) + QString::number(i),
|
||||||
dateTimePartName(op));
|
dateTimePartName(op));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case PhraseData::AddHours:
|
case PhraseData::AddHours:
|
||||||
case PhraseData::AddMinutes:
|
case PhraseData::AddMinutes:
|
||||||
|
|
@ -248,9 +253,8 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
int i = d->operand.toInt();
|
int i = d->operand.toInt();
|
||||||
return QStringLiteral("TIME(%1,'%2 %3')")
|
return QStringLiteral("TIME(%1,'%2 %3')")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
(i < 0 ? QStringLiteral("") : QStringLiteral("+")) + QString::number(i),
|
(i < 0 ? QLatin1String() : QStringLiteral("+")) + QString::number(i),
|
||||||
dateTimePartName(op));
|
dateTimePartName(op));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case PhraseData::AddYearsDateTime:
|
case PhraseData::AddYearsDateTime:
|
||||||
case PhraseData::AddMonthsDateTime:
|
case PhraseData::AddMonthsDateTime:
|
||||||
|
|
@ -261,7 +265,7 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
int i = d->operand.toInt();
|
int i = d->operand.toInt();
|
||||||
return QStringLiteral("DATETIME(%1,'%2 %3')")
|
return QStringLiteral("DATETIME(%1,'%2 %3')")
|
||||||
.arg(createConditionalPhrase(d->left),
|
.arg(createConditionalPhrase(d->left),
|
||||||
(i < 0 ? QStringLiteral("") : QStringLiteral("+")) + QString::number(i),
|
(i < 0 ? QLatin1String() : QStringLiteral("+")) + QString::number(i),
|
||||||
dateTimePartName(op));
|
dateTimePartName(op));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -308,13 +312,13 @@ QString SqliteGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
|
|
||||||
QString SqliteGenerator::escapeValue(const QVariant &v) const
|
QString SqliteGenerator::escapeValue(const QVariant &v) const
|
||||||
{
|
{
|
||||||
if (v.type() == QVariant::Time)
|
if (VARIANT_TYPE_COMPARE(v, Time))
|
||||||
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::Date)
|
if (VARIANT_TYPE_COMPARE(v, Date))
|
||||||
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
||||||
|
|
||||||
if (v.type() == QVariant::DateTime)
|
if (VARIANT_TYPE_COMPARE(v, DateTime))
|
||||||
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
||||||
|
|
||||||
return AbstractSqlGenerator::escapeValue(v);
|
return AbstractSqlGenerator::escapeValue(v);
|
||||||
|
|
@ -335,3 +339,5 @@ QVariant SqliteGenerator::unescapeValue(const QMetaType::Type &type, const QVari
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#include <QtNut/abstractsqlgenerator.h>
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT SqliteGenerator : public AbstractSqlGenerator
|
class NUT_EXPORT SqliteGenerator : public AbstractSqlGenerator
|
||||||
|
|
@ -40,7 +42,7 @@ public:
|
||||||
void appendSkipTake(QString &sql, int skip, int take) override;
|
void appendSkipTake(QString &sql, int skip, int take) override;
|
||||||
|
|
||||||
QString primaryKeyConstraint(const TableModel *table) const override;
|
QString primaryKeyConstraint(const TableModel *table) const override;
|
||||||
QStringList diff(TableModel *oldTable, TableModel *newTable) override;
|
QStringList diffTable(TableModel *oldTable, TableModel *newTable) override;
|
||||||
|
|
||||||
QString createConditionalPhrase(const PhraseData *d) const override;
|
QString createConditionalPhrase(const PhraseData *d) const override;
|
||||||
|
|
||||||
|
|
@ -50,4 +52,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // SQLITEGENERATOR_H
|
#endif // SQLITEGENERATOR_H
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,13 @@
|
||||||
#include "sqlservergenerator.h"
|
#include "sqlservergenerator.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
|
#include "nut_p.h"
|
||||||
|
|
||||||
#include <QtCore/QPoint>
|
#include <QtCore/QPoint>
|
||||||
#include <QtCore/QRegularExpression>
|
#include <QtCore/QRegularExpression>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
SqlServerGenerator::SqlServerGenerator(Database *parent)
|
SqlServerGenerator::SqlServerGenerator(Database *parent)
|
||||||
|
|
@ -37,7 +40,7 @@ QString SqlServerGenerator::masterDatabaseName(QString databaseName)
|
||||||
return databaseName.replace(
|
return databaseName.replace(
|
||||||
QRegularExpression(QStringLiteral("DATABASE\\=(\\w+)"),
|
QRegularExpression(QStringLiteral("DATABASE\\=(\\w+)"),
|
||||||
QRegularExpression::CaseInsensitiveOption),
|
QRegularExpression::CaseInsensitiveOption),
|
||||||
QStringLiteral("DATABASE="));
|
QStringLiteral("DATABASE=master"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlServerGenerator::fieldType(FieldModel *field)
|
QString SqlServerGenerator::fieldType(FieldModel *field)
|
||||||
|
|
@ -130,13 +133,16 @@ QString SqlServerGenerator::fieldType(FieldModel *field)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString SqlServerGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
QString SqlServerGenerator::diffField(FieldModel *oldField, FieldModel *newField)
|
||||||
{
|
{
|
||||||
QString sql = QString();
|
if (!oldField && !newField)
|
||||||
|
return QString();
|
||||||
|
|
||||||
if (oldField && newField)
|
if (oldField && newField)
|
||||||
if (*oldField == *newField)
|
if (*oldField == *newField)
|
||||||
return sql;
|
return QString();
|
||||||
|
|
||||||
|
QString sql = QString();
|
||||||
if (!newField) {
|
if (!newField) {
|
||||||
sql = QStringLiteral("DROP COLUMN ") + oldField->name;
|
sql = QStringLiteral("DROP COLUMN ") + oldField->name;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -152,44 +158,44 @@ QString SqlServerGenerator::diff(FieldModel *oldField, FieldModel *newField)
|
||||||
|
|
||||||
QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
QString SqlServerGenerator::escapeValue(const QVariant &v) const
|
||||||
{
|
{
|
||||||
switch (v.type()) {
|
switch (METATYPE_ID(v)) {
|
||||||
case QVariant::String:
|
case QMetaType::QString:
|
||||||
case QVariant::Char:
|
case QMetaType::QChar:
|
||||||
case QVariant::Polygon:
|
case QMetaType::QPolygon:
|
||||||
case QVariant::PolygonF:
|
case QMetaType::QPolygonF:
|
||||||
case QVariant::Size:
|
case QMetaType::QSize:
|
||||||
case QVariant::SizeF:
|
case QMetaType::QSizeF:
|
||||||
case QVariant::Rect:
|
case QMetaType::QRect:
|
||||||
case QVariant::RectF:
|
case QMetaType::QRectF:
|
||||||
case QVariant::Line:
|
case QMetaType::QLine:
|
||||||
case QVariant::LineF:
|
case QMetaType::QLineF:
|
||||||
case QVariant::Color:
|
case QMetaType::QColor:
|
||||||
case QVariant::StringList:
|
case QMetaType::QStringList:
|
||||||
// case QVariant::JsonArray:
|
// case QMetaType::QJsonArray:
|
||||||
// case QVariant::JsonValue:
|
// case QMetaType::QJsonValue:
|
||||||
// case QVariant::JsonObject:
|
// case QMetaType::QJsonObject:
|
||||||
// case QVariant::JsonDocument:
|
// case QMetaType::QJsonDocument:
|
||||||
case QVariant::Url:
|
case QMetaType::QUrl:
|
||||||
return QStringLiteral("N") + AbstractSqlGenerator::escapeValue(v);
|
return QStringLiteral("N") + AbstractSqlGenerator::escapeValue(v);
|
||||||
|
|
||||||
// case QVariant::Point: {
|
// case QMetaType::QPoint: {
|
||||||
// QPoint pt = v.toPoint();
|
// QPoint pt = v.toPoint();
|
||||||
// return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
// return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
||||||
// pt.y());
|
// pt.y());
|
||||||
// }
|
// }
|
||||||
// case QVariant::PointF: {
|
// case QMetaType::QPointF: {
|
||||||
// QPointF pt = v.toPointF();
|
// QPointF pt = v.toPointF();
|
||||||
// return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
// return QString("geography::POINT(%1, %2, 4326)").arg(pt.x()).arg(
|
||||||
// pt.y());
|
// pt.y());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
case QVariant::Time:
|
case QMetaType::QTime:
|
||||||
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
return v.toTime().toString(QStringLiteral("''HH:mm:ss''"));
|
||||||
|
|
||||||
case QVariant::Date:
|
case QMetaType::QDate:
|
||||||
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
return v.toDate().toString(QStringLiteral("''yyyy-MM-dd''"));
|
||||||
|
|
||||||
case QVariant::DateTime:
|
case QMetaType::QDateTime:
|
||||||
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
return v.toDateTime().toString(QStringLiteral("''yyyy-MM-dd HH:mm:ss''"));
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -279,3 +285,5 @@ QString SqlServerGenerator::createConditionalPhrase(const PhraseData *d) const
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#include <QtNut/abstractsqlgenerator.h>
|
#include <QtNut/abstractsqlgenerator.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT SqlServerGenerator : public AbstractSqlGenerator
|
class NUT_EXPORT SqlServerGenerator : public AbstractSqlGenerator
|
||||||
|
|
@ -35,7 +37,7 @@ public:
|
||||||
QString masterDatabaseName(QString databaseName) override;
|
QString masterDatabaseName(QString databaseName) override;
|
||||||
|
|
||||||
QString fieldType(FieldModel *field) override;
|
QString fieldType(FieldModel *field) override;
|
||||||
QString diff(FieldModel *oldField, FieldModel *newField) override;
|
QString diffField(FieldModel *oldField, FieldModel *newField) override;
|
||||||
|
|
||||||
QString escapeValue(const QVariant &v) const override;
|
QString escapeValue(const QVariant &v) const override;
|
||||||
QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue) override;
|
QVariant unescapeValue(const QMetaType::Type &type, const QVariant &dbValue) override;
|
||||||
|
|
@ -48,4 +50,6 @@ protected:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // SQLSERVERGENERATOR_H
|
#endif // SQLSERVERGENERATOR_H
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include <QtCore/QJsonArray>
|
#include <QtCore/QJsonArray>
|
||||||
#include <QtCore/QJsonObject>
|
#include <QtCore/QJsonObject>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QMap<QString, DatabaseModel*> DatabaseModel::_models;
|
QMap<QString, DatabaseModel*> DatabaseModel::_models;
|
||||||
|
|
@ -48,7 +50,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();
|
||||||
Q_FOREACH (QString key, tables.keys()) {
|
for (auto &key: tables.keys()) {
|
||||||
if(!tables.value(key).isObject())
|
if(!tables.value(key).isObject())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -146,7 +148,7 @@ RelationModel *DatabaseModel::relationByClassNames(const QString &masterClassNam
|
||||||
if(!childTable)
|
if(!childTable)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Q_FOREACH (RelationModel *rel, childTable->foreignKeys())
|
for (auto &rel: childTable->foreignKeys())
|
||||||
if(rel->masterClassName == masterClassName)
|
if(rel->masterClassName == masterClassName)
|
||||||
return rel;
|
return rel;
|
||||||
|
|
||||||
|
|
@ -160,7 +162,7 @@ RelationModel *DatabaseModel::relationByTableNames(const QString &masterTableNam
|
||||||
if(!childTable)
|
if(!childTable)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
Q_FOREACH (RelationModel *rel, childTable->foreignKeys())
|
for (auto &rel: childTable->foreignKeys())
|
||||||
if(rel->masterTable->name() == masterTableName)
|
if(rel->masterTable->name() == masterTableName)
|
||||||
return rel;
|
return rel;
|
||||||
|
|
||||||
|
|
@ -174,7 +176,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();
|
||||||
Q_FOREACH (QString key, tables.keys()) {
|
for (auto &key: tables.keys()) {
|
||||||
if(!json.value(key).isObject())
|
if(!json.value(key).isObject())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
@ -209,8 +211,8 @@ bool DatabaseModel::remove(const QString &tableName)
|
||||||
void DatabaseModel::fixRelations()
|
void DatabaseModel::fixRelations()
|
||||||
{
|
{
|
||||||
/*TODO: fixme
|
/*TODO: fixme
|
||||||
Q_FOREACH (TableModel *table, currentModel)
|
for (auto &table: currentModel)
|
||||||
Q_FOREACH (RelationModel *fk, table->foreignKeys())
|
for (auto &fk: table->foreignKeys())
|
||||||
fk->masterTable = currentModel.tableByClassName(fk->masterClassName);
|
fk->masterTable = currentModel.tableByClassName(fk->masterClassName);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
@ -238,12 +240,11 @@ void DatabaseModel::deleteAllModels()
|
||||||
DatabaseModel operator +(const DatabaseModel &l, const DatabaseModel &r)
|
DatabaseModel operator +(const DatabaseModel &l, const DatabaseModel &r)
|
||||||
{
|
{
|
||||||
DatabaseModel model;
|
DatabaseModel model;
|
||||||
DatabaseModel::const_iterator i;
|
|
||||||
|
|
||||||
for (i = r.constBegin(); i != r.constEnd(); ++i)
|
for (auto i = r.constBegin(); i != r.constEnd(); ++i)
|
||||||
model.append(*i);
|
model.append(*i);
|
||||||
|
|
||||||
for (i = l.constBegin(); i != l.constEnd(); ++i)
|
for (auto i = l.constBegin(); i != l.constEnd(); ++i)
|
||||||
model.append(*i);
|
model.append(*i);
|
||||||
|
|
||||||
return model;
|
return model;
|
||||||
|
|
@ -252,17 +253,16 @@ DatabaseModel operator +(const DatabaseModel &l, const DatabaseModel &r)
|
||||||
DatabaseModel operator |(const DatabaseModel &l, const DatabaseModel &r)
|
DatabaseModel operator |(const DatabaseModel &l, const DatabaseModel &r)
|
||||||
{
|
{
|
||||||
DatabaseModel ret;
|
DatabaseModel ret;
|
||||||
DatabaseModel::const_iterator i;
|
|
||||||
QSet<QString> tables;
|
QSet<QString> tables;
|
||||||
|
|
||||||
for (i = r.constBegin(); i != r.constEnd(); ++i) {
|
for (auto i = r.constBegin(); i != r.constEnd(); ++i) {
|
||||||
if (tables.contains((*i)->name()))
|
if (tables.contains((*i)->name()))
|
||||||
continue;
|
continue;
|
||||||
ret.append(*i);
|
ret.append(*i);
|
||||||
tables.insert((*i)->name());
|
tables.insert((*i)->name());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = l.constBegin(); i != l.constEnd(); ++i) {
|
for (auto i = l.constBegin(); i != l.constEnd(); ++i) {
|
||||||
if (tables.contains((*i)->name()))
|
if (tables.contains((*i)->name()))
|
||||||
continue;
|
continue;
|
||||||
ret.append(*i);
|
ret.append(*i);
|
||||||
|
|
@ -273,3 +273,5 @@ DatabaseModel operator |(const DatabaseModel &l, const DatabaseModel &r)
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,8 @@
|
||||||
**
|
**
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#ifndef DATABASEMODEL_H
|
#ifndef DATABASE_MODEL_H
|
||||||
#define DATABASEMODEL_H
|
#define DATABASE_MODEL_H
|
||||||
|
|
||||||
#include <QtCore/QList>
|
#include <QtCore/QList>
|
||||||
#include <QtCore/QMap>
|
#include <QtCore/QMap>
|
||||||
|
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class TableModel;
|
class TableModel;
|
||||||
|
|
@ -66,7 +68,7 @@ public:
|
||||||
|
|
||||||
bool remove(const QString &tableName);
|
bool remove(const QString &tableName);
|
||||||
|
|
||||||
//TODO: may be private (called from DatabasePrivate::getCurrectSchema only)
|
//TODO: may be private (called from DatabasePrivate::getCurrentSchema only)
|
||||||
void fixRelations();
|
void fixRelations();
|
||||||
|
|
||||||
static DatabaseModel *modelByName(const QString &name);
|
static DatabaseModel *modelByName(const QString &name);
|
||||||
|
|
@ -78,4 +80,6 @@ DatabaseModel operator |(const DatabaseModel &l, const DatabaseModel &r);
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // DATABASEMODEL_H
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
|
#endif // DATABASE_MODEL_H
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
#include "sqlmodel.h"
|
#include "sqlmodel.h"
|
||||||
#include "query.h"
|
#include "query.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
SqlModelPrivate::SqlModelPrivate(SqlModel *parent) : q_ptr(parent)
|
SqlModelPrivate::SqlModelPrivate(SqlModel *parent) : q_ptr(parent)
|
||||||
|
|
@ -124,3 +126,5 @@ Row<Table> SqlModel::at(const int &i) const
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class Database;
|
class Database;
|
||||||
|
|
@ -44,9 +46,10 @@ public:
|
||||||
// explicit SqlModel(Query *q);
|
// explicit SqlModel(Query *q);
|
||||||
explicit SqlModel(Database *database, AbstractTableSet *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 override;
|
||||||
int columnCount(const QModelIndex &parent) const;
|
int columnCount(const QModelIndex &parent) const override;
|
||||||
QVariant data(const QModelIndex &index, int role) const;
|
QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
void setTable(RowList<T> rows);
|
void setTable(RowList<T> rows);
|
||||||
|
|
@ -54,7 +57,6 @@ public:
|
||||||
void setRows(RowList<Table> rows);
|
void setRows(RowList<Table> rows);
|
||||||
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;
|
|
||||||
Row<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);
|
||||||
|
|
@ -67,12 +69,13 @@ 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;
|
||||||
Q_FOREACH (auto t, rows)
|
for (auto t: rows)
|
||||||
tab.append(t);
|
tab.append(t);
|
||||||
setRows(tab);
|
setRows(tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // SQLMODEL_H
|
#endif // SQLMODEL_H
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,33 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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/>.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Nut API. This header
|
||||||
|
// file may change from version to version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
#ifndef SQLMODEL_P_H
|
#ifndef SQLMODEL_P_H
|
||||||
#define SQLMODEL_P_H
|
#define SQLMODEL_P_H
|
||||||
|
|
||||||
|
|
@ -8,6 +38,8 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class SqlModel;
|
class SqlModel;
|
||||||
|
|
@ -29,4 +61,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // SQLMODEL_P_H
|
#endif // SQLMODEL_P_H
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@
|
||||||
|
|
||||||
#include "tablemodel.h"
|
#include "tablemodel.h"
|
||||||
#include "nut_global.h"
|
#include "nut_global.h"
|
||||||
|
#include "nut_p.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -74,7 +77,7 @@ FieldModel *TableModel::field(int n) const
|
||||||
|
|
||||||
FieldModel *TableModel::field(const QString &name) const
|
FieldModel *TableModel::field(const QString &name) const
|
||||||
{
|
{
|
||||||
Q_FOREACH (FieldModel *f, _fields)
|
for (auto &f: _fields)
|
||||||
if(f->name == name)
|
if(f->name == name)
|
||||||
return f;
|
return f;
|
||||||
|
|
||||||
|
|
@ -94,7 +97,7 @@ QList<RelationModel *> TableModel::foreignKeys() const
|
||||||
QStringList TableModel::fieldsNames() const
|
QStringList TableModel::fieldsNames() const
|
||||||
{
|
{
|
||||||
QStringList ret;
|
QStringList ret;
|
||||||
Q_FOREACH (FieldModel *f, _fields)
|
for (auto &f: _fields)
|
||||||
ret.append(f->name);
|
ret.append(f->name);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
@ -106,7 +109,7 @@ bool TableModel::operator ==(const TableModel &t) const{
|
||||||
if(fields().count() != t.fields().count())
|
if(fields().count() != t.fields().count())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
Q_FOREACH (FieldModel *f, _fields) {
|
for (auto &f: _fields) {
|
||||||
FieldModel *tf = t.field(f->name);
|
FieldModel *tf = t.field(f->name);
|
||||||
if(!tf)
|
if(!tf)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -129,7 +132,7 @@ TableModel::TableModel(int typeId, const QString &tableName)
|
||||||
// if (findByTypeId(typeId))
|
// if (findByTypeId(typeId))
|
||||||
// return;
|
// return;
|
||||||
|
|
||||||
const QMetaObject *tableMetaObject = QMetaType::metaObjectForType(typeId);
|
const QMetaObject *tableMetaObject = QMetaType(typeId).metaObject();
|
||||||
|
|
||||||
_typeId = typeId;
|
_typeId = typeId;
|
||||||
_name = tableName;
|
_name = tableName;
|
||||||
|
|
@ -162,12 +165,16 @@ TableModel::TableModel(int typeId, const QString &tableName)
|
||||||
QMetaProperty fieldProperty = tableMetaObject->property(j);
|
QMetaProperty fieldProperty = tableMetaObject->property(j);
|
||||||
auto name = QString::fromUtf8(fieldProperty.name());
|
auto name = QString::fromUtf8(fieldProperty.name());
|
||||||
FieldModel *fieldObj = field(name);
|
FieldModel *fieldObj = field(name);
|
||||||
Q_FOREACH (FieldModel *f, _fields)
|
for (auto &f: _fields)
|
||||||
if(f->name == name)
|
if(f->name == name)
|
||||||
f = fieldObj;
|
fieldObj = f;
|
||||||
if(!fieldObj)
|
if(!fieldObj)
|
||||||
continue;
|
continue;
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
fieldObj->type = static_cast<QMetaType::Type>(fieldProperty.metaType().id());
|
||||||
|
#else
|
||||||
fieldObj->type = static_cast<QMetaType::Type>(fieldProperty.type());
|
fieldObj->type = static_cast<QMetaType::Type>(fieldProperty.type());
|
||||||
|
#endif
|
||||||
fieldObj->typeName = QString::fromUtf8(fieldProperty.typeName());
|
fieldObj->typeName = QString::fromUtf8(fieldProperty.typeName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -244,13 +251,17 @@ TableModel::TableModel(const QJsonObject &json, const QString &tableName) : _typ
|
||||||
|
|
||||||
QJsonObject fields = json.value(QStringLiteral(__FIELDS)).toObject();
|
QJsonObject fields = json.value(QStringLiteral(__FIELDS)).toObject();
|
||||||
QJsonObject relations = json.value(QStringLiteral(__FOREIGN_KEYS)).toObject();
|
QJsonObject relations = json.value(QStringLiteral(__FOREIGN_KEYS)).toObject();
|
||||||
Q_FOREACH (QString key, fields.keys()) {
|
for (auto &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(QStringLiteral(__NAME)).toString();
|
f->name = fieldObject.value(QStringLiteral(__NAME)).toString();
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
f->type = static_cast<QMetaType::Type>(QMetaType::fromName(fieldObject.value(QStringLiteral(__TYPE)).toString().toLatin1()).id());
|
||||||
|
#else
|
||||||
f->type = static_cast<QMetaType::Type>(QMetaType::type(fieldObject.value(QStringLiteral(__TYPE)).toString().toLatin1().data()));
|
f->type = static_cast<QMetaType::Type>(QMetaType::type(fieldObject.value(QStringLiteral(__TYPE)).toString().toLatin1().data()));
|
||||||
f->typeName = QString::fromUtf8(QMetaType::typeName(f->type));
|
#endif
|
||||||
|
f->typeName = QString::fromUtf8(METATYPE_TO_NAME(f->type));
|
||||||
|
|
||||||
if(fieldObject.contains(QStringLiteral(__nut_NOT_NULL)))
|
if(fieldObject.contains(QStringLiteral(__nut_NOT_NULL)))
|
||||||
f->notNull = fieldObject.value(QStringLiteral(__nut_NOT_NULL)).toBool();
|
f->notNull = fieldObject.value(QStringLiteral(__nut_NOT_NULL)).toBool();
|
||||||
|
|
@ -266,7 +277,7 @@ TableModel::TableModel(const QJsonObject &json, const QString &tableName) : _typ
|
||||||
_fields.append(f);
|
_fields.append(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH (QString key, relations.keys()) {
|
for (auto &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));
|
||||||
}
|
}
|
||||||
|
|
@ -284,10 +295,10 @@ QJsonObject TableModel::toJson() const
|
||||||
QJsonObject fieldsObj;
|
QJsonObject fieldsObj;
|
||||||
QJsonObject foreignKeysObj;
|
QJsonObject foreignKeysObj;
|
||||||
|
|
||||||
Q_FOREACH (FieldModel *f, _fields) {
|
for (auto &f: _fields) {
|
||||||
QJsonObject fieldObj;
|
QJsonObject fieldObj;
|
||||||
fieldObj.insert(QStringLiteral(__NAME), f->name);
|
fieldObj.insert(QStringLiteral(__NAME), f->name);
|
||||||
fieldObj.insert(QStringLiteral(__TYPE), QString::fromUtf8(QVariant::typeToName(f->type)));
|
fieldObj.insert(QStringLiteral(__TYPE), QString::fromUtf8(METATYPE_TO_NAME(f->type)));
|
||||||
|
|
||||||
if(f->length)
|
if(f->length)
|
||||||
fieldObj.insert(QStringLiteral(__nut_LEN), f->length);
|
fieldObj.insert(QStringLiteral(__nut_LEN), f->length);
|
||||||
|
|
@ -309,7 +320,7 @@ QJsonObject TableModel::toJson() const
|
||||||
|
|
||||||
fieldsObj.insert(f->name, fieldObj);
|
fieldsObj.insert(f->name, fieldObj);
|
||||||
}
|
}
|
||||||
Q_FOREACH (RelationModel *rel, _foreignKeys)
|
for (auto &rel: _foreignKeys)
|
||||||
foreignKeysObj.insert(rel->localColumn, rel->toJson());
|
foreignKeysObj.insert(rel->localColumn, rel->toJson());
|
||||||
|
|
||||||
obj.insert(QStringLiteral(__FIELDS), fieldsObj);
|
obj.insert(QStringLiteral(__FIELDS), fieldsObj);
|
||||||
|
|
@ -320,7 +331,7 @@ QJsonObject TableModel::toJson() const
|
||||||
|
|
||||||
RelationModel *TableModel::foreignKey(const QString &otherTable) const
|
RelationModel *TableModel::foreignKey(const QString &otherTable) const
|
||||||
{
|
{
|
||||||
Q_FOREACH (RelationModel *fk, _foreignKeys)
|
for (auto &fk: _foreignKeys)
|
||||||
if(fk->masterClassName == otherTable)
|
if(fk->masterClassName == otherTable)
|
||||||
return fk;
|
return fk;
|
||||||
|
|
||||||
|
|
@ -329,7 +340,7 @@ RelationModel *TableModel::foreignKey(const QString &otherTable) const
|
||||||
|
|
||||||
RelationModel *TableModel::foreignKeyByField(const QString &fieldName) const
|
RelationModel *TableModel::foreignKeyByField(const QString &fieldName) const
|
||||||
{
|
{
|
||||||
Q_FOREACH (RelationModel *fk, _foreignKeys)
|
for (auto &fk: _foreignKeys)
|
||||||
if(fk->localColumn == fieldName)
|
if(fk->localColumn == fieldName)
|
||||||
return fk;
|
return fk;
|
||||||
|
|
||||||
|
|
@ -339,9 +350,9 @@ RelationModel *TableModel::foreignKeyByField(const QString &fieldName) const
|
||||||
QString TableModel::toString() const
|
QString TableModel::toString() const
|
||||||
{
|
{
|
||||||
QStringList sl;
|
QStringList sl;
|
||||||
Q_FOREACH (FieldModel *f, _fields)
|
for (auto &f: _fields)
|
||||||
sl.append(f->name + QStringLiteral(" ")
|
sl.append(f->name + QStringLiteral(" ")
|
||||||
+ QString::fromUtf8(QVariant::typeToName(f->type)));
|
+ QString::fromUtf8(METATYPE_TO_NAME(f->type)));
|
||||||
|
|
||||||
QString ret = QStringLiteral("%1 (%2)")
|
QString ret = QStringLiteral("%1 (%2)")
|
||||||
.arg(_name, sl.join(QStringLiteral(", ")));
|
.arg(_name, sl.join(QStringLiteral(", ")));
|
||||||
|
|
@ -350,7 +361,7 @@ QString TableModel::toString() const
|
||||||
|
|
||||||
QString TableModel::primaryKey() const
|
QString TableModel::primaryKey() const
|
||||||
{
|
{
|
||||||
Q_FOREACH (FieldModel *f, _fields)
|
for (auto &f: _fields)
|
||||||
if(f->isPrimaryKey)
|
if(f->isPrimaryKey)
|
||||||
return f->name;
|
return f->name;
|
||||||
return QString();
|
return QString();
|
||||||
|
|
@ -381,7 +392,7 @@ QJsonObject FieldModel::toJson() const
|
||||||
{
|
{
|
||||||
QJsonObject fieldObj;
|
QJsonObject fieldObj;
|
||||||
fieldObj.insert(QStringLiteral(__NAME), name);
|
fieldObj.insert(QStringLiteral(__NAME), name);
|
||||||
fieldObj.insert(QStringLiteral(__TYPE), QString::fromUtf8(QVariant::typeToName(type)));
|
fieldObj.insert(QStringLiteral(__TYPE), QString::fromUtf8(METATYPE_TO_NAME(type)));
|
||||||
fieldObj.insert(QStringLiteral(__nut_LEN), length);
|
fieldObj.insert(QStringLiteral(__nut_LEN), length);
|
||||||
fieldObj.insert(QStringLiteral(__nut_NOT_NULL), notNull);
|
fieldObj.insert(QStringLiteral(__nut_NOT_NULL), notNull);
|
||||||
fieldObj.insert(QStringLiteral(__nut_UNIQUE), isUnique);
|
fieldObj.insert(QStringLiteral(__nut_UNIQUE), isUnique);
|
||||||
|
|
@ -424,3 +435,5 @@ bool operator !=(const RelationModel &l, const RelationModel &r)
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
class QJsonObject;
|
class QJsonObject;
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class TableModel;
|
class TableModel;
|
||||||
|
|
@ -135,4 +137,6 @@ private:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // TABLEMODEL_H
|
#endif // TABLEMODEL_H
|
||||||
|
|
|
||||||
|
|
@ -16,4 +16,3 @@ HEADERS += \
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/phrase.cpp
|
$$PWD/phrase.cpp
|
||||||
|
|
||||||
include($$PWD/3rdparty/serializer/src/src.pri)
|
|
||||||
|
|
|
||||||
|
|
@ -17,11 +17,11 @@ include(phrases/phrases.pri)
|
||||||
include(models/models.pri)
|
include(models/models.pri)
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
$$PWD/phrase.h
|
$$PWD/phrase.h \
|
||||||
|
$$PWD/nut_p.h
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
$$PWD/phrase.cpp
|
$$PWD/phrase.cpp
|
||||||
|
|
||||||
load(qt_module)
|
load(qt_module)
|
||||||
|
|
||||||
include($$PWD/3rdparty/serializer/src/src.pri)
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** 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/>.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
//
|
||||||
|
// W A R N I N G
|
||||||
|
// -------------
|
||||||
|
//
|
||||||
|
// This file is not part of the Nut API. This header
|
||||||
|
// file may change from version to version without notice, or even be removed.
|
||||||
|
//
|
||||||
|
// We mean it.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef NUT_P_H
|
||||||
|
#define NUT_P_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
# define VARIANT_TYPE_COMPARE(v, t) v.typeId() == QMetaType::Q##t
|
||||||
|
# define VARIANT_TYPE_COMPARE_X(v, vt, mt) v.typeId() == QMetaType::mt
|
||||||
|
# define METATYPE_TO_NAME(type) QMetaType(type).name()
|
||||||
|
# define METATYPE_ID(v) static_cast<QMetaType::Type>(v.typeId())
|
||||||
|
#else
|
||||||
|
# define VARIANT_TYPE_COMPARE(v, t) v.type() == QVariant::t
|
||||||
|
# define VARIANT_TYPE_COMPARE_X(v, vt, mt) v.type() == QVariant::vt
|
||||||
|
# define METATYPE_TO_NAME(type) QMetaType::typeName(type)
|
||||||
|
# define METATYPE_ID(v) static_cast<QMetaType::Type>(v.type())
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -19,3 +19,6 @@
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "phrase.h"
|
#include "phrase.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,9 @@
|
||||||
#ifndef PHRASE_H
|
#ifndef PHRASE_H
|
||||||
#define PHRASE_H
|
#define PHRASE_H
|
||||||
|
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
#include <QtNut/conditionalphrase.h>
|
#include <QtNut/conditionalphrase.h>
|
||||||
#include <QtNut/abstractfieldphrase.h>
|
#include <QtNut/abstractfieldphrase.h>
|
||||||
|
|
@ -35,4 +38,7 @@
|
||||||
#include <QtNut/fieldphrase_qstring.h>
|
#include <QtNut/fieldphrase_qstring.h>
|
||||||
#include <QtNut/fieldphrase_bool.h>
|
#include <QtNut/fieldphrase_bool.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // PHRASE_H
|
#endif // PHRASE_H
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
#include "abstractfieldphrase.h"
|
#include "abstractfieldphrase.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
AbstractFieldPhrase::AbstractFieldPhrase(PhraseData *d) : data(d)
|
AbstractFieldPhrase::AbstractFieldPhrase(PhraseData *d) : data(d)
|
||||||
|
|
@ -137,3 +139,5 @@ AbstractFieldPhrase AbstractFieldPhrase::operator !()
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
#include <QtNut/conditionalphrase.h>
|
#include <QtNut/conditionalphrase.h>
|
||||||
#include <QtNut/phraselist.h>
|
#include <QtNut/phraselist.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class PhraseData;
|
class PhraseData;
|
||||||
|
|
@ -46,7 +48,7 @@ public:
|
||||||
ConditionalPhrase in(QList<T> list)
|
ConditionalPhrase in(QList<T> list)
|
||||||
{
|
{
|
||||||
QVariantList vlist;
|
QVariantList vlist;
|
||||||
Q_FOREACH (T t, list)
|
for (auto &t: list)
|
||||||
vlist.append(QVariant::fromValue(t));
|
vlist.append(QVariant::fromValue(t));
|
||||||
|
|
||||||
return ConditionalPhrase(this, PhraseData::In, vlist);
|
return ConditionalPhrase(this, PhraseData::In, vlist);
|
||||||
|
|
@ -87,4 +89,6 @@ protected:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // ABSTRACTFIELDPHRASE_H
|
#endif // ABSTRACTFIELDPHRASE_H
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,8 @@
|
||||||
#include "assignmentphrase.h"
|
#include "assignmentphrase.h"
|
||||||
#include "phrasedata.h"
|
#include "phrasedata.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
AssignmentPhrase::AssignmentPhrase(PhraseData *d) : data(d)
|
AssignmentPhrase::AssignmentPhrase(PhraseData *d) : data(d)
|
||||||
|
|
@ -61,3 +63,5 @@ AssignmentPhrase::~AssignmentPhrase()
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,9 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
#include <QtNut/assignmentphraselist.h>
|
#include <QtNut/assignmentphraselist.h>
|
||||||
|
#include <QtNut/NutGlobal>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
@ -45,5 +48,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // ASSIGNMENTPHRASE_H
|
#endif // ASSIGNMENTPHRASE_H
|
||||||
|
|
|
||||||
|
|
@ -22,8 +22,9 @@
|
||||||
#include "phrasedata.h"
|
#include "phrasedata.h"
|
||||||
#include "assignmentphrase.h"
|
#include "assignmentphrase.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
AssignmentPhraseList AssignmentPhrase::operator &(const AssignmentPhrase &other)
|
AssignmentPhraseList AssignmentPhrase::operator &(const AssignmentPhrase &other)
|
||||||
{
|
{
|
||||||
|
|
@ -68,18 +69,14 @@ AssignmentPhraseList AssignmentPhraseList::operator &(const AssignmentPhrase
|
||||||
|
|
||||||
AssignmentPhraseList::~AssignmentPhraseList()
|
AssignmentPhraseList::~AssignmentPhraseList()
|
||||||
{
|
{
|
||||||
// Q_FOREACH (PhraseData *d, data)
|
|
||||||
// if (!d->ref.deref())
|
|
||||||
// delete d;
|
|
||||||
// qDeleteAll(data);
|
|
||||||
// data.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignmentPhraseList::incAllDataParents()
|
void AssignmentPhraseList::incAllDataParents()
|
||||||
{
|
{
|
||||||
Q_FOREACH (PhraseData *d, data)
|
for (auto &d: data)
|
||||||
d->ref.ref();
|
d->ref.ref();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class PhraseData;
|
class PhraseData;
|
||||||
|
|
@ -47,4 +49,6 @@ private:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // ASSIGNMENTPHRASELIST_H
|
#endif // ASSIGNMENTPHRASELIST_H
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include "conditionalphrase.h"
|
#include "conditionalphrase.h"
|
||||||
#include "phrasedata.h"
|
#include "phrasedata.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
ConditionalPhrase::ConditionalPhrase() : data(nullptr)
|
ConditionalPhrase::ConditionalPhrase() : data(nullptr)
|
||||||
|
|
@ -232,3 +234,5 @@ ConditionalPhrase operator >=(ConditionalPhrase &&l, ConditionalPhrase &&r)
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#include <QtNut/phrasedata.h>
|
#include <QtNut/phrasedata.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class PhraseData;
|
class PhraseData;
|
||||||
|
|
@ -89,7 +91,8 @@ ConditionalPhrase NUT_EXPORT operator <=(ConditionalPhrase &&l, ConditionalPhras
|
||||||
ConditionalPhrase NUT_EXPORT operator >(ConditionalPhrase &&l, ConditionalPhrase &&r);
|
ConditionalPhrase NUT_EXPORT operator >(ConditionalPhrase &&l, ConditionalPhrase &&r);
|
||||||
ConditionalPhrase NUT_EXPORT operator >=(ConditionalPhrase &&l, ConditionalPhrase &&r);
|
ConditionalPhrase NUT_EXPORT operator >=(ConditionalPhrase &&l, ConditionalPhrase &&r);
|
||||||
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // CONDITIONALPHRASE_H
|
#endif // CONDITIONALPHRASE_H
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
#include <QtNut/abstractfieldphrase.h>
|
#include <QtNut/abstractfieldphrase.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -60,4 +62,6 @@ Q_OUTOFLINE_TEMPLATE ConditionalPhrase FieldPhrase<T>::operator ==(const QVarian
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // FIELDPHRASE_H
|
#endif // FIELDPHRASE_H
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include "fieldphrase_bool.h"
|
#include "fieldphrase_bool.h"
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QtNut/fieldphrase.h>
|
#include <QtNut/fieldphrase.h>
|
||||||
#include <QtNut/fieldphrase.h>
|
#include <QtNut/fieldphrase.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -35,4 +37,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_FIELDPHRASE_BOOL_H
|
#endif // NUT_FIELDPHRASE_BOOL_H
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "fieldphrase_date.h"
|
#include "fieldphrase_date.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
FieldPhrase<QDate>::FieldPhrase(const char *className, const char *s) :
|
FieldPhrase<QDate>::FieldPhrase(const char *className, const char *s) :
|
||||||
|
|
@ -145,3 +147,5 @@ COMMON_OPERATORS_IMPL(QTime)
|
||||||
COMMON_OPERATORS_IMPL(QDateTime)
|
COMMON_OPERATORS_IMPL(QDateTime)
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include <QtNut/fieldphrase.h>
|
#include <QtNut/fieldphrase.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#define COMMON_OPERATORS_DECL(T) \
|
#define COMMON_OPERATORS_DECL(T) \
|
||||||
|
|
@ -121,4 +123,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // DATEPHRASE_H
|
#endif // DATEPHRASE_H
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
#include <QtNut/abstractfieldphrase.h>
|
#include <QtNut/abstractfieldphrase.h>
|
||||||
#include <QtNut/fieldphrase.h>
|
#include <QtNut/fieldphrase.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
@ -36,4 +38,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUT_FIELDPHRASE_QSTRING_H
|
#endif // NUT_FIELDPHRASE_QSTRING_H
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@
|
||||||
|
|
||||||
#include <QtNut/fieldphrase.h>
|
#include <QtNut/fieldphrase.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
#define SPECIALIZATION_NUMERIC_MEMBER(type, op, cond) \
|
#define SPECIALIZATION_NUMERIC_MEMBER(type, op, cond) \
|
||||||
|
|
@ -85,4 +87,6 @@ SPECIALIZATION_NUMERIC_TYPE(float)
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // NUMERICPHRASE_H
|
#endif // NUMERICPHRASE_H
|
||||||
|
|
|
||||||
|
|
@ -20,18 +20,20 @@
|
||||||
|
|
||||||
#include "phrasedata.h"
|
#include "phrasedata.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
PhraseData::PhraseData()
|
PhraseData::PhraseData()
|
||||||
: className(""), fieldName(""), type(Field), operatorCond(NotAssign),
|
: className(""), fieldName(""), type(Field), operatorCond(NotAssign),
|
||||||
left(nullptr), right(nullptr), operand(QVariant::Invalid), isNot(false),
|
left(nullptr), right(nullptr), operand(), isNot(false),
|
||||||
ref(1)
|
ref(1)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
PhraseData::PhraseData(const char *className, const char *fieldName)
|
PhraseData::PhraseData(const char *className, const char *fieldName)
|
||||||
: className(className), fieldName(fieldName), type(Field),
|
: className(className), fieldName(fieldName), type(Field),
|
||||||
operatorCond(NotAssign), left(nullptr), right(nullptr),
|
operatorCond(NotAssign), left(nullptr), right(nullptr),
|
||||||
operand(QVariant::Invalid), isNot(false), ref(1)
|
operand(), isNot(false), ref(1)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o)
|
PhraseData::PhraseData(PhraseData *l, PhraseData::Condition o)
|
||||||
|
|
@ -115,3 +117,5 @@ void PhraseData::cleanUp(PhraseData *d)
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT PhraseData
|
class NUT_EXPORT PhraseData
|
||||||
|
|
@ -122,4 +124,6 @@ private:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // PHRASEDATA_H
|
#endif // PHRASEDATA_H
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "phrasedatalist.h"
|
#include "phrasedatalist.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
PhraseDataList::PhraseDataList() : QList<PhraseData*>()
|
PhraseDataList::PhraseDataList() : QList<PhraseData*>()
|
||||||
|
|
@ -43,7 +45,7 @@ void PhraseDataList::append(PhraseData *d)
|
||||||
|
|
||||||
void PhraseDataList::append(QList<PhraseData *> &dl)
|
void PhraseDataList::append(QList<PhraseData *> &dl)
|
||||||
{
|
{
|
||||||
Q_FOREACH (PhraseData *d, dl)
|
for (auto &d: dl)
|
||||||
d->ref.ref();
|
d->ref.ref();
|
||||||
QList<PhraseData*>::append(dl);
|
QList<PhraseData*>::append(dl);
|
||||||
}
|
}
|
||||||
|
|
@ -59,3 +61,5 @@ PhraseDataList::~PhraseDataList()
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#include <QtNut/phrasedata.h>
|
#include <QtNut/phrasedata.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT PhraseDataList : public QList<PhraseData*>
|
class NUT_EXPORT PhraseDataList : public QList<PhraseData*>
|
||||||
|
|
@ -37,4 +39,6 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // PHRASEDATALIST_H
|
#endif // PHRASEDATALIST_H
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@
|
||||||
#include "abstractfieldphrase.h"
|
#include "abstractfieldphrase.h"
|
||||||
#include "phraselist.h"
|
#include "phraselist.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
PhraseList::PhraseList() : isValid(false)
|
PhraseList::PhraseList() : isValid(false)
|
||||||
|
|
@ -83,7 +85,7 @@ PhraseList PhraseList::operator |(const AbstractFieldPhrase &other) {
|
||||||
|
|
||||||
void PhraseList::incAllDataParents()
|
void PhraseList::incAllDataParents()
|
||||||
{
|
{
|
||||||
// Q_FOREACH (PhraseData *d, data)
|
// for (auto &d: data)
|
||||||
// d->parents++;
|
// d->parents++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,3 +94,5 @@ PhraseList PhraseList::operator |(PhraseList &other) {
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
#include <QtNut/phrasedatalist.h>
|
#include <QtNut/phrasedatalist.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class AbstractFieldPhrase;
|
class AbstractFieldPhrase;
|
||||||
|
|
@ -51,4 +53,6 @@ private:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // PHRASELIST_H
|
#endif // PHRASELIST_H
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include "dbgeography.h"
|
#include "dbgeography.h"
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
DbGeography::DbGeography() : m_longitude(0), m_latitude(0)
|
DbGeography::DbGeography() : m_longitude(0), m_latitude(0)
|
||||||
|
|
@ -79,3 +81,5 @@ DbGeography::operator QVariant()
|
||||||
}
|
}
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include <QtNut/nut_global.h>
|
#include <QtNut/nut_global.h>
|
||||||
|
|
||||||
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
NUT_BEGIN_NAMESPACE
|
NUT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
class NUT_EXPORT DbGeography
|
class NUT_EXPORT DbGeography
|
||||||
|
|
@ -50,6 +52,8 @@ public:
|
||||||
|
|
||||||
NUT_END_NAMESPACE
|
NUT_END_NAMESPACE
|
||||||
|
|
||||||
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(NUT_WRAP_NAMESPACE(DbGeography))
|
Q_DECLARE_METATYPE(NUT_WRAP_NAMESPACE(DbGeography))
|
||||||
|
|
||||||
#endif // DBGEOGRAPHY_H
|
#endif // DBGEOGRAPHY_H
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Generated from tests.pro.
|
||||||
|
|
||||||
|
if(QT_BUILD_STANDALONE_TESTS)
|
||||||
|
# Add qt_find_package calls for extra dependencies that need to be found when building
|
||||||
|
# the standalone tests here.
|
||||||
|
endif()
|
||||||
|
qt_build_tests()
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Generated from auto.pro.
|
||||||
|
|
||||||
|
add_subdirectory(tst_basic)
|
||||||
|
add_subdirectory(tst_benckmark)
|
||||||
|
add_subdirectory(tst_datatypes)
|
||||||
|
add_subdirectory(tst_phrases)
|
||||||
|
add_subdirectory(tst_properties)
|
||||||
|
add_subdirectory(tst_qttypes)
|
||||||
|
add_subdirectory(tst_quuid)
|
||||||
|
add_subdirectory(tst_generators)
|
||||||
|
add_subdirectory(tst_upgrades)
|
||||||
|
add_subdirectory(tst_json)
|
||||||
|
add_subdirectory(tst_datetime)
|
||||||
|
|
@ -4,13 +4,19 @@
|
||||||
#include <QtCore/qglobal.h>
|
#include <QtCore/qglobal.h>
|
||||||
#include <QtCore/QDateTime>
|
#include <QtCore/QDateTime>
|
||||||
#include <QtNut/table.h>
|
#include <QtNut/table.h>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
#ifdef NUT_NAMESPACE
|
#ifdef NUT_NAMESPACE
|
||||||
using namespace NUT_NAMESPACE;
|
using namespace NUT_NAMESPACE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Post;
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
Q_MOC_INCLUDE("user.h")
|
||||||
|
Q_MOC_INCLUDE("post.h")
|
||||||
|
#endif
|
||||||
|
|
||||||
class User;
|
class User;
|
||||||
|
class Post;
|
||||||
class Comment : public Table
|
class Comment : public Table
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
||||||
|
|
@ -13,18 +13,17 @@
|
||||||
.arg(QString::fromUtf8(__func__))
|
.arg(QString::fromUtf8(__func__))
|
||||||
|
|
||||||
|
|
||||||
/*#define DRIVER QStringLiteral("QSQLITE")
|
#define DATABASE QStringLiteral("nut_test_%1_db") \
|
||||||
#define HOST QString()
|
.arg(QString::fromUtf8(metaObject()->className())).toLower()
|
||||||
#define USERNAME QString()
|
#include "test_params.h"
|
||||||
#define PASSWORD QString()
|
|
||||||
*/
|
/*
|
||||||
#define DRIVER QStringLiteral("QMYSQL")
|
#define DRIVER QStringLiteral("QMYSQL")
|
||||||
#define HOST QStringLiteral("192.168.10.2")
|
#define HOST QStringLiteral("192.168.10.2")
|
||||||
#define USERNAME QStringLiteral("root")
|
#define USERNAME QStringLiteral("root")
|
||||||
#define PASSWORD QStringLiteral("lDexDJGvQwx20sfgtsetDSupmn9")
|
#define PASSWORD QStringLiteral("lDexDJGvQwx20sfgtsetDSupmn9")
|
||||||
|
*/
|
||||||
|
|
||||||
#define DATABASE QStringLiteral("nut_test_%1_db") \
|
|
||||||
.arg(QString::fromUtf8(metaObject()->className())).toLower()
|
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
# define OS "Linux"
|
# define OS "Linux"
|
||||||
|
|
|
||||||
|
|
@ -1,54 +1,54 @@
|
||||||
contains(debug_and_release, CONFIG): message(debug_and_release)
|
contains(debug_and_release, CONFIG): message(debug_and_release)
|
||||||
|
|
||||||
debug_and_release:!ReleaseBuild:!DebugBuild {
|
debug_and_release:!ReleaseBuild:!DebugBuild {
|
||||||
runtarget.target = run-tests
|
runtarget.target = run-tests
|
||||||
runtarget.CONFIG = recursive
|
runtarget.CONFIG = recursive
|
||||||
runtarget.recurse_target = run-tests
|
runtarget.recurse_target = run-tests
|
||||||
QMAKE_EXTRA_TARGETS += runtarget
|
QMAKE_EXTRA_TARGETS += runtarget
|
||||||
} else {
|
} else {
|
||||||
oneshell.target = .ONESHELL
|
oneshell.target = .ONESHELL
|
||||||
QMAKE_EXTRA_TARGETS += oneshell
|
QMAKE_EXTRA_TARGETS += oneshell
|
||||||
|
|
||||||
win32:!win32-g++ {
|
win32:!win32-g++ {
|
||||||
CONFIG(debug, debug|release): outdir_helper = debug
|
CONFIG(debug, debug|release): outdir_helper = debug
|
||||||
CONFIG(release, debug|release): outdir_helper = release
|
CONFIG(release, debug|release): outdir_helper = release
|
||||||
runtarget.target = run-tests
|
runtarget.target = run-tests
|
||||||
!compat_test: runtarget.depends += $(DESTDIR_TARGET)
|
!compat_test: runtarget.depends += $(DESTDIR_TARGET)
|
||||||
runtarget.commands += set PATH=$$shell_path($$shadowed($$dirname(_QMAKE_CONF_))/bin);$$shell_path($$[QT_INSTALL_BINS]);$(PATH)
|
runtarget.commands += set PATH=$$shell_path($$shadowed($$dirname(_QMAKE_CONF_))/bin);$$shell_path($$[QT_INSTALL_BINS]);$(PATH)
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)set QT_PLUGIN_PATH=$$shadowed($$dirname(_QMAKE_CONF_))/plugins;$$[QT_INSTALL_PLUGINS];$(QT_PLUGIN_PATH)
|
runtarget.commands += $$escape_expand(\\n\\t)set QT_PLUGIN_PATH=$$shadowed($$dirname(_QMAKE_CONF_))/plugins;$$[QT_INSTALL_PLUGINS];$(QT_PLUGIN_PATH)
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)set QML2_IMPORT_PATH=$$shadowed($$dirname(_QMAKE_CONF_))/qml;$$[QT_INSTALL_QML];$(QML2_IMPORT_PATH)
|
runtarget.commands += $$escape_expand(\\n\\t)set QML2_IMPORT_PATH=$$shadowed($$dirname(_QMAKE_CONF_))/qml;$$[QT_INSTALL_QML];$(QML2_IMPORT_PATH)
|
||||||
!isEmpty(LOGGING_RULES): runtarget.commands += $$escape_expand(\\n\\t)set \"QT_LOGGING_RULES=$$LOGGING_RULES\"
|
!isEmpty(LOGGING_RULES): runtarget.commands += $$escape_expand(\\n\\t)set \"QT_LOGGING_RULES=$$LOGGING_RULES\"
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)if exist $${outdir_helper}\\fail del $${outdir_helper}\\fail
|
runtarget.commands += $$escape_expand(\\n\\t)if exist $${outdir_helper}\\fail del $${outdir_helper}\\fail
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)start /w call $(DESTDIR_TARGET) ^> $${outdir_helper}\\test.log ^|^| echo FAIL ^> $${outdir_helper}\\fail ^& exit 0
|
runtarget.commands += $$escape_expand(\\n\\t)start /w call $(DESTDIR_TARGET) ^> $${outdir_helper}\\test.log ^|^| echo FAIL ^> $${outdir_helper}\\fail ^& exit 0
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)type $${outdir_helper}\\test.log
|
runtarget.commands += $$escape_expand(\\n\\t)type $${outdir_helper}\\test.log
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)if exist $${outdir_helper}\\fail exit 42
|
runtarget.commands += $$escape_expand(\\n\\t)if exist $${outdir_helper}\\fail exit 42
|
||||||
QMAKE_EXTRA_TARGETS += runtarget
|
QMAKE_EXTRA_TARGETS += runtarget
|
||||||
} else {
|
} else {
|
||||||
win32-g++: QMAKE_DIRLIST_SEP = ";"
|
win32-g++: QMAKE_DIRLIST_SEP = ";"
|
||||||
runtarget.commands += export PATH=\"$$shell_path($$shadowed($$dirname(_QMAKE_CONF_))/bin):$$shell_path($$[QT_INSTALL_BINS]):$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}PATH\"
|
runtarget.commands += export PATH=\"$$shell_path($$shadowed($$dirname(_QMAKE_CONF_))/bin):$$shell_path($$[QT_INSTALL_BINS]):$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}PATH\"
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)export QT_PLUGIN_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/plugins$${QMAKE_DIRLIST_SEP}$$[QT_INSTALL_PLUGINS]$${QMAKE_DIRLIST_SEP}$(QT_PLUGIN_PATH)\"
|
runtarget.commands += $$escape_expand(\\n\\t)export QT_PLUGIN_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/plugins$${QMAKE_DIRLIST_SEP}$$[QT_INSTALL_PLUGINS]$${QMAKE_DIRLIST_SEP}$(QT_PLUGIN_PATH)\"
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)export QML2_IMPORT_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/qml$${QMAKE_DIRLIST_SEP}$$[QT_INSTALL_QML]$${QMAKE_DIRLIST_SEP}$(QML2_IMPORT_PATH)\"
|
runtarget.commands += $$escape_expand(\\n\\t)export QML2_IMPORT_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/qml$${QMAKE_DIRLIST_SEP}$$[QT_INSTALL_QML]$${QMAKE_DIRLIST_SEP}$(QML2_IMPORT_PATH)\"
|
||||||
!isEmpty(LOGGING_RULES): runtarget.commands += $$escape_expand(\\n\\t)export QT_LOGGING_RULES=\"$$LOGGING_RULES\"
|
!isEmpty(LOGGING_RULES): runtarget.commands += $$escape_expand(\\n\\t)export QT_LOGGING_RULES=\"$$LOGGING_RULES\"
|
||||||
win32-g++: QMAKE_DIRLIST_SEP = ":"
|
win32-g++: QMAKE_DIRLIST_SEP = ":"
|
||||||
|
|
||||||
linux|win32-g++ {
|
linux|win32-g++ {
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)export LD_LIBRARY_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/lib$${QMAKE_DIRLIST_SEP}$$[QT_INSTALL_LIBS]$${QMAKE_DIRLIST_SEP}$(LD_LIBRARY_PATH)\"
|
runtarget.commands += $$escape_expand(\\n\\t)export LD_LIBRARY_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/lib$${QMAKE_DIRLIST_SEP}$$[QT_INSTALL_LIBS]$${QMAKE_DIRLIST_SEP}$(LD_LIBRARY_PATH)\"
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)export QT_QPA_PLATFORM=minimal
|
runtarget.commands += $$escape_expand(\\n\\t)export QT_QPA_PLATFORM=minimal
|
||||||
} else:mac {
|
} else:mac {
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)export DYLD_LIBRARY_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/lib:$$[QT_INSTALL_LIBS]:$(DYLD_LIBRARY_PATH)\"
|
runtarget.commands += $$escape_expand(\\n\\t)export DYLD_LIBRARY_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/lib:$$[QT_INSTALL_LIBS]:$(DYLD_LIBRARY_PATH)\"
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)export DYLD_FRAMEWORK_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/lib:$$[QT_INSTALL_LIBS]:$(DYLD_FRAMEWORK_PATH)\"
|
runtarget.commands += $$escape_expand(\\n\\t)export DYLD_FRAMEWORK_PATH=\"$$shadowed($$dirname(_QMAKE_CONF_))/lib:$$[QT_INSTALL_LIBS]:$(DYLD_FRAMEWORK_PATH)\"
|
||||||
}
|
|
||||||
|
|
||||||
runtarget.target = run-tests
|
|
||||||
win32-g++ {
|
|
||||||
!compat_test: runtarget.depends += $(DESTDIR_TARGET)
|
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)./$(DESTDIR_TARGET)
|
|
||||||
} else {
|
|
||||||
!compat_test: runtarget.depends += $(TARGET)
|
|
||||||
runtarget.commands += $$escape_expand(\\n\\t)./$(TARGET)
|
|
||||||
}
|
|
||||||
QMAKE_EXTRA_TARGETS += runtarget
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
runtarget.target = run-tests
|
||||||
|
win32-g++ {
|
||||||
|
!compat_test: runtarget.depends += $(DESTDIR_TARGET)
|
||||||
|
runtarget.commands += $$escape_expand(\\n\\t)./$(DESTDIR_TARGET)
|
||||||
|
} else {
|
||||||
|
!compat_test: runtarget.depends += $(TARGET)
|
||||||
|
runtarget.commands += $$escape_expand(\\n\\t)./$(TARGET)
|
||||||
|
}
|
||||||
|
QMAKE_EXTRA_TARGETS += runtarget
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
INCLUDEPATH += $$PWD/../common
|
INCLUDEPATH += $$PWD/../common
|
||||||
|
|
@ -57,6 +57,7 @@ QT += nut
|
||||||
CONFIG += testcase
|
CONFIG += testcase
|
||||||
|
|
||||||
DEFINES += NUT_PATH=\\\"$$PWD/../../\\\"
|
DEFINES += NUT_PATH=\\\"$$PWD/../../\\\"
|
||||||
|
DEFINES += NUT_PRINT_DEBUG_INFO
|
||||||
|
|
||||||
runtarget.target = run-tests
|
runtarget.target = run-tests
|
||||||
runtarget.CONFIG = recursive
|
runtarget.CONFIG = recursive
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,17 @@
|
||||||
#include <QtNut/table.h>
|
#include <QtNut/table.h>
|
||||||
#include <QtNut/database.h>
|
#include <QtNut/database.h>
|
||||||
#include <QtNut/databasemodel.h>
|
#include <QtNut/databasemodel.h>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
#ifdef NUT_NAMESPACE
|
#ifdef NUT_NAMESPACE
|
||||||
using namespace NUT_NAMESPACE;
|
using namespace NUT_NAMESPACE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
Q_MOC_INCLUDE("comment.h")
|
||||||
|
Q_MOC_INCLUDE("score.h")
|
||||||
|
#endif
|
||||||
|
|
||||||
class Comment;
|
class Comment;
|
||||||
class Score;
|
class Score;
|
||||||
class Post : public Table
|
class Post : public Table
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
#include "post.h"
|
#include "post.h"
|
||||||
|
|
||||||
Score::Score(QObject *parent) : Nut::Table(parent)
|
Score::Score(QObject *parent) : NUT_WRAP_NAMESPACE(Table)(parent)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,17 @@
|
||||||
|
|
||||||
#include <QUuid>
|
#include <QUuid>
|
||||||
#include <QtNut/table.h>
|
#include <QtNut/table.h>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
Q_MOC_INCLUDE("user.h")
|
||||||
|
Q_MOC_INCLUDE("post.h")
|
||||||
|
#endif
|
||||||
|
|
||||||
class User;
|
class User;
|
||||||
class Post;
|
class Post;
|
||||||
class Score : public Nut::Table
|
class Score : public NUT_WRAP_NAMESPACE(Table)
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
@ -15,6 +22,8 @@ class Score : public Nut::Table
|
||||||
|
|
||||||
NUT_DECLARE_FIELD(int, score, score, setScore)
|
NUT_DECLARE_FIELD(int, score, score, setScore)
|
||||||
|
|
||||||
|
NUT_DECLARE_FIELD(int, condition, condition, setCondition)
|
||||||
|
|
||||||
NUT_FOREIGN_KEY_DECLARE(Post, int, post, post, setPost)
|
NUT_FOREIGN_KEY_DECLARE(Post, int, post, post, setPost)
|
||||||
NUT_FOREIGN_KEY_DECLARE(User, QUuid, author, author, setAuthor)
|
NUT_FOREIGN_KEY_DECLARE(User, QUuid, author, author, setAuthor)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
#define DRIVER QStringLiteral("QSQLITE")
|
||||||
|
#define HOST QString()
|
||||||
|
#define USERNAME QString()
|
||||||
|
#define PASSWORD QString()
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
#include <QtGlobal>
|
||||||
|
|
||||||
|
#ifdef DATABASE
|
||||||
|
#undef DATABASE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DATABASE \
|
||||||
|
QStringLiteral("DRIVER={SQL Server Native Client 11.0};Server=localhost;DATABASE=nut_test_%1_db;UID=sa;PWD=NUT_sa_PASS_1_???;") \
|
||||||
|
.arg(QString::fromUtf8(metaObject()->className()).toLower())
|
||||||
|
|
||||||
|
#define DRIVER QStringLiteral("QODBC")
|
||||||
|
#define HOST QLatin1String("")
|
||||||
|
#define USERNAME QLatin1String("")
|
||||||
|
#define PASSWORD QLatin1String("")
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
#define DRIVER QStringLiteral("QMYSQL")
|
||||||
|
#define HOST QStringLiteral("localhost")
|
||||||
|
#define USERNAME QStringLiteral("root")
|
||||||
|
#define PASSWORD QStringLiteral("root")
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
#define DRIVER QStringLiteral("QPSQL")
|
||||||
|
#define HOST QStringLiteral("localhost")
|
||||||
|
#define USERNAME QStringLiteral("postgres")
|
||||||
|
#define PASSWORD QStringLiteral("postgres")
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
#define DRIVER QStringLiteral("QSQLITE")
|
||||||
|
#define HOST QString()
|
||||||
|
#define USERNAME QString()
|
||||||
|
#define PASSWORD QString()
|
||||||
|
|
@ -3,9 +3,9 @@
|
||||||
|
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
|
||||||
User::User(QObject *tableSet) : Table(tableSet),
|
User::User(QObject *tableSet) : Nut::Table(tableSet),
|
||||||
m_comments(new TableSet<Comment>(this)),
|
m_comments(new Nut::TableSet<Comment>(this)),
|
||||||
m_scores(new TableSet<Score>(this))
|
m_scores(new Nut::TableSet<Score>(this))
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,20 @@
|
||||||
|
|
||||||
#include <QtCore/QUuid>
|
#include <QtCore/QUuid>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
#include <QSharedPointer>
|
||||||
|
|
||||||
#ifdef NUT_NAMESPACE
|
#ifdef NUT_NAMESPACE
|
||||||
using namespace NUT_NAMESPACE;
|
using namespace NUT_NAMESPACE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
Q_MOC_INCLUDE("comment.h")
|
||||||
|
Q_MOC_INCLUDE("score.h")
|
||||||
|
#endif
|
||||||
|
|
||||||
class Comment;
|
class Comment;
|
||||||
class Score;
|
class Score;
|
||||||
class User : public Nut::Table
|
class User : public NUT_WRAP_NAMESPACE(Table)
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,13 @@
|
||||||
using namespace NUT_NAMESPACE;
|
using namespace NUT_NAMESPACE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||||
|
Q_MOC_INCLUDE("user.h")
|
||||||
|
Q_MOC_INCLUDE("post.h")
|
||||||
|
Q_MOC_INCLUDE("score.h")
|
||||||
|
Q_MOC_INCLUDE("comment.h")
|
||||||
|
#endif
|
||||||
|
|
||||||
class Post;
|
class Post;
|
||||||
class Comment;
|
class Comment;
|
||||||
class User;
|
class User;
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue