diff --git a/.idea/.gitignore b/.idea/.gitignore
deleted file mode 100644
index 30cf57e..0000000
--- a/.idea/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-# Default ignored files
-/shelf/
-/workspace.xml
-# Editor-based HTTP Client requests
-/httpRequests/
-# Ignored default folder with query files
-/queries/
-# Datasource local storage ignored files
-/dataSources/
-/dataSources.local.xml
diff --git a/.idea/editor.xml b/.idea/editor.xml
deleted file mode 100644
index a3aeb4c..0000000
--- a/.idea/editor.xml
+++ /dev/null
@@ -1,367 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
deleted file mode 100644
index df87cf9..0000000
--- a/.idea/encodings.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
deleted file mode 100644
index 498ae80..0000000
--- a/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/pgLab.iml b/.idea/pgLab.iml
deleted file mode 100644
index 6102194..0000000
--- a/.idea/pgLab.iml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
deleted file mode 100644
index 35eb1dd..0000000
--- a/.idea/vcs.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.junie/skills/reno-release-notes/SKILL.md b/.junie/skills/reno-release-notes/SKILL.md
deleted file mode 100644
index 2a1779f..0000000
--- a/.junie/skills/reno-release-notes/SKILL.md
+++ /dev/null
@@ -1,110 +0,0 @@
----
-name: reno-release-notes
-description: Create, review and lint pgLab release notes with reno (releasenotes/notes YAML fragments). Use whenever the user mentions reno, release notes, releasenotes/notes, "reno new", "reno lint", or asks to add or check a note for a user-visible change in pgLab, even if reno is not named explicitly.
----
-
-# reno release notes in pgLab
-
-pgLab uses [reno](https://docs.openstack.org/reno/latest/) for release notes.
-Each user-visible change adds its own small YAML file in `releasenotes/notes/`,
-committed together with the change. reno derives the release from git tags, so
-never move or rename notes to change releases. Content is reStructuredText, not
-Markdown.
-
-The notes are rendered in the Sphinx user docs through the
-`.. release-notes::` directive in `docs/releasenotes.rst` (docs build:
-`pip install -r docs/requirements.txt && sphinx-build -b html docs userdocs`).
-The About dialog links to the generated `releasenotes.html`.
-
-## When to write a note
-
-Write one for: new features, behaviour changes users will notice (UI, menus,
-shortcuts, query/code generation output, connection handling), bug fixes,
-known issues, and upgrade impact (e.g. changed stored settings or connection
-config format).
-
-Skip: pure refactors, build-system/CI changes, test-only changes, internal
-code cleanup, docs-only edits.
-
-## Sections configured for this project
-
-Defined in `releasenotes/config.yaml` (render order). Only these keys are valid;
-others (`deprecations`, `critical`) are NOT configured here and will not render.
-
-| Key | Rendered title | Use for |
-|------------|------------------|--------------------------------------------|
-| `prelude` | (implicit) | Release-wide summary, single string |
-| `features` | New Features | New functionality |
-| `other` | Changes | Changes to existing behaviour, minor items |
-| `issues` | Known Issues | Known problems / limitations |
-| `upgrade` | Upgrade Notes | What users must do or know when upgrading |
-| `security` | Security Issues | Security fixes |
-| `fixes` | Bug Fixes | Ordinary bug fixes |
-
-Every section except `prelude` is a list of strings. Encoding is utf8.
-
-## Creating a note
-
-From the repo root (`pip install reno` if missing):
-
-```bash
-reno new short-descriptive-slug
-```
-
-This creates `releasenotes/notes/short-descriptive-slug-<16 hex>.yaml`. Keep the
-random suffix. Existing examples: `f5-bindings-…`,
-`connection-details-in-window-title-…`, `dollar-quoted-string-…`.
-Delete all unused template sections, keep only what you need.
-
-```yaml
----
-features:
- - |
- The query tool now executes the current statement with
- :kbd:`F5`.
-fixes:
- - |
- Fixed reconnect dialog that kept popping up after the connection was lost.
-```
-
-Short single-line items may be plain (`- text`), longer ones use `- |`.
-Wrap at roughly 80 columns.
-
-## Writing style
-
-- Write for pgLab users, not patch reviewers: describe the visible effect, not
- the implementation (no class or function names unless users see them).
-- Past or present tense, full sentences, one bullet per distinct change.
-- RST markup: inline literals with double backticks (``` ``pg_catalog`` ```),
- links as `` `text `_ ``, GUI menu paths with
- `:menuselection:` (e.g. `:menuselection:`Help --> About``), keys with
- `:kbd:`. No Markdown, no single-backtick code.
-- Mention the PostgreSQL feature or object type involved when relevant.
-- For `upgrade`, state the action required.
-
-## Validate before committing
-
-```bash
-reno lint
-reno list # note must be tracked by git to appear for tagged history
-```
-
-Common failures: YAML indentation/tabs, misspelled section key, a string where
-a list is required (or a list for `prelude`), an unconfigured section, bad RST.
-Optionally build the docs (command above) to check rendering.
-
-## Commit rules
-
-- `git add releasenotes/notes/` and commit it in the same commit as the
- change, not a follow-up.
-- Commit messages are plain imperative sentences (e.g. "Fix reconnect dialog
- popping up repeatedly.").
-- To correct a note, edit the same file; don't add a second one.
-
-## Troubleshooting
-
-- Note missing in report: not committed, or shallow clone without tags
- (`git fetch --tags --unshallow`).
-- Wrong release: decided by git history/tags; check `reno list`.
-- Broken rendering: almost always RST (single backticks, Markdown links,
- indentation).
diff --git a/AGENTS.md b/AGENTS.md
deleted file mode 100644
index b9c08b0..0000000
--- a/AGENTS.md
+++ /dev/null
@@ -1,32 +0,0 @@
-# AGENTS.md
-
-pgLab: Qt 6 / C++20 desktop GUI for PostgreSQL.
-
-## Layout (link order: core, pgsql -> pglablib -> pglab)
-- `core/` – generic utilities (SQL lexer, CSV writer, `Expected`, JSON); no DB access.
-- `pgsql/` – thin C++ wrapper around libpq (connection, result, params, oids).
-- `pglablib/` – catalog models, code builders, query generation, connection config.
-- `pglab/` – the Qt Widgets application (executable).
-- `tests/` – gtest executables `PgsqlTests` and `pglabtests`, plus `mygtestutils` (Qt `PrintTo` helpers).
-- `docs/` – Sphinx user docs; `releasenotes/notes` – `reno` notes.
-
-## Build and test
-CMake + vcpkg is the active build system (`VCPKG_ROOT` must be set). Qt 6 is not provided by vcpkg; it must be installed on the system.
-```
-cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
-cmake --build build
-ctest --test-dir build --output-on-failure
-```
-- Run one suite: `./build/tests/pglabtests/pglabtests --gtest_filter='SqlLexer*'` (same for `PgsqlTests`).
-- `-DBUILD_TESTS=OFF` skips tests. `build/` is git-ignored; the first configure builds dependencies and is slow.
-- Run the app headless with `QT_QPA_PLATFORM=offscreen ./build/pglab/pglab`. It needs a PostgreSQL server for anything useful.
-
-## Gotchas
-- Tests are registered per executable, so each `ctest` entry covers a whole suite.
-- A new test file must be added to the `add_executable` list in `tests//CMakeLists.txt`. Sources are listed explicitly, with no globbing. The same goes for new sources in each library's `CMakeLists.txt`.
-- `core/test/` is not referenced by any CMake file (its tests are built from `tests/pglabtests`). Don't expect changes there to be compiled.
-- `AUTOMOC`/`AUTOUIC`/`AUTORCC` are on globally, so `.ui` and `.qrc` files only need to be listed as sources.
-- `BOOST_ENABLE_ASSERT_HANDLER` is defined; the handler lives in `core/my_boost_assert_handler.cpp`.
-- Commit messages are plain imperative sentences. User-visible changes need a reno note (`releasenotes/notes`).
-- Docs build: `pip install -r docs/requirements.txt && sphinx-build -b html docs userdocs`.
-- Windows (VS 2022) is also a supported platform. Avoid Linux-only code, and don't break `WIN32_LEAN_AND_MEAN`/`NOMINMAX` assumptions.
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index a172074..0000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-cmake_minimum_required(VERSION 3.21)
-
-project(pgLab LANGUAGES C CXX)
-
-set(CMAKE_CXX_STANDARD 20)
-set(CMAKE_CXX_STANDARD_REQUIRED ON)
-set(CMAKE_CXX_EXTENSIONS OFF)
-
-set(CMAKE_AUTOMOC ON)
-set(CMAKE_AUTOUIC ON)
-set(CMAKE_AUTORCC ON)
-
-add_compile_definitions(BOOST_ENABLE_ASSERT_HANDLER QT_DEPRECATED_WARNINGS)
-if(WIN32)
- add_compile_definitions(WIN32_LEAN_AND_MEAN NOMINMAX)
-endif()
-
-find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Sql Concurrent)
-
-option(BUILD_TESTS "Build the gtest executables and register them with ctest" ON)
-
-add_subdirectory(core)
-add_subdirectory(pgsql)
-add_subdirectory(pglablib)
-add_subdirectory(pglab)
-
-if(BUILD_TESTS)
- enable_testing()
- add_subdirectory(tests)
-endif()
diff --git a/README.md b/README.md
index 7c2eb7e..bdf5ea0 100644
--- a/README.md
+++ b/README.md
@@ -11,41 +11,3 @@ The release notes use collected from git using [reno](https://docs.openstack.org
- googletest
- libpq
-Boost, Botan, libpq and googletest are provided by vcpkg through the manifest in `vcpkg.json`, so you do not install them manually.
-
-## Required tools
-
-- CMake 3.21 or newer
-- A C++20 compiler (GCC or Clang on Linux, Visual Studio 2022 on Windows)
-- Qt 6 with the Core, Gui, Widgets, Sql and Concurrent components
-- vcpkg, with the `VCPKG_ROOT` environment variable pointing to its checkout
-- Ninja or make (optional, for faster builds)
-- A PostgreSQL server (only needed to run the application against a database)
-
-## Building
-
-Configure with the vcpkg toolchain file. The first configure downloads and builds the dependencies, which takes a while:
-
-```
-cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=$VCPKG_ROOT/scripts/buildsystems/vcpkg.cmake
-cmake --build build
-```
-
-To skip the test executables, add `-DBUILD_TESTS=OFF` to the configure command.
-
-## Running the tests
-
-From the build directory, run:
-
-```
-ctest --output-on-failure
-```
-
-## Running the application
-
-The executable is built to `build/pglab/pglab`. On a machine without a display, set `QT_QPA_PLATFORM=offscreen`:
-
-```
-./build/pglab/pglab
-```
-
diff --git a/common.pri b/common.pri
new file mode 100644
index 0000000..dcff145
--- /dev/null
+++ b/common.pri
@@ -0,0 +1,15 @@
+! include( ./local.pri ) {
+error( "Use local.pri.sample to create your own local.pri" )
+}
+
+LIBS += -lUser32 -lws2_32 -llibpq
+
+CONFIG += c++20
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which as been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+DEFINES += BOOST_ENABLE_ASSERT_HANDLER
+DEFINES += WIN32_LEAN_AND_MEAN NOMINMAX _WIN32_WINNT=0x0501
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index ec63cf3..95b09fc 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -1,31 +1,41 @@
+set(CMAKE_AUTOMOC ON)
+
add_library(core STATIC
- my_boost_assert_handler.cpp
- SqlLexer.cpp
- CsvWriter.cpp
BackupFormatModel.cpp
- ExplainTreeModelItem.cpp
- jsoncpp.cpp
- SqlLexer.h
- ScopeGuard.h
- CsvWriter.h
- BackupFormatModel.h
- Expected.h
- ExplainTreeModelItem.h
- json/json.h
- std_utils.h
- IntegerRange.h
- )
-
+ CsvWriter.cpp
+ my_boost_assert_handler.cpp
+ PasswordManager.cpp
+ SqlLexer.cpp)
+
target_link_libraries(core PUBLIC
- Qt6::Core
+ boost
+ botan
+ Qt5::Core
)
-
-target_include_directories(core PUBLIC
+
+target_include_directories(core INTERFACE
$
+)
+
+set_target_properties(core PROPERTIES
+ CXX_STANDARD 14
+ CXX_STANDARD_REQUIRED ON
+ POSITION_INDEPENDENT_CODE True
)
-set_target_properties(core PROPERTIES
- CXX_STANDARD 20
- CXX_STANDARD_REQUIRED ON
- POSITION_INDEPENDENT_CODE ON
+add_executable(runtests
+ test/main.cpp
+ test/tst_CsvWriter.cpp
+ test/tst_expected.cpp
+ test/tst_PasswordManager.cpp
+ test/tst_scopeguard.cpp
+ test/tst_SqlLexer.cpp
)
+
+target_link_libraries(runtests
+ core
+ gtest
+ Threads::Threads
+ )
+
+add_test(tests runtests)
diff --git a/core/core.pro b/core/core.pro
new file mode 100644
index 0000000..0b424f6
--- /dev/null
+++ b/core/core.pro
@@ -0,0 +1,43 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2017-02-26T10:51:14
+#
+#-------------------------------------------------
+
+QT -= gui
+
+TARGET = core
+TEMPLATE = lib
+CONFIG += staticlib
+
+! include( ../common.pri ) {
+error( "Couldn't find the common.pri file!" )
+}
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += my_boost_assert_handler.cpp \
+ SqlLexer.cpp \
+ CsvWriter.cpp \
+ BackupFormatModel.cpp \
+ ExplainTreeModelItem.cpp \
+ jsoncpp.cpp
+
+HEADERS += \
+ SqlLexer.h \
+ ScopeGuard.h \
+ CsvWriter.h \
+ BackupFormatModel.h \
+ Expected.h \
+ ExplainTreeModelItem.h \
+ json/json.h \
+ std_utils.h \
+ IntegerRange.h
+
+unix {
+ target.path = /usr/lib
+ INSTALLS += target
+}
diff --git a/local.pri.sample b/local.pri.sample
new file mode 100644
index 0000000..44b8f1e
--- /dev/null
+++ b/local.pri.sample
@@ -0,0 +1,17 @@
+# Need paths here to find following library headers
+# - botan
+# - boost
+# - libpq
+# ???
+INCLUDEPATH += c:/prog/include
+INCLUDEPATH += c:/prog/include/pgsql
+INCLUDEPATH += c:/VSproj/boost/include/boost-1_68
+
+# Need paths here to find library files for
+# - botan
+# - boost
+# - libpq
+#
+LIBS += -L\VSproj\boost\lib -L/PROG/LIB
+
+GOOGLETEST_DIR = c:/prog/googletest
diff --git a/pglab/CMakeLists.txt b/pglab/CMakeLists.txt
index ab4dda5..d6a1072 100644
--- a/pglab/CMakeLists.txt
+++ b/pglab/CMakeLists.txt
@@ -1,115 +1,69 @@
-set(PGLAB_SOURCES
- main.cpp
- About.cpp
- catalog/delegates/IconColumnDelegate.cpp
- catalog/models/BaseTableModel.cpp
- catalog/models/ColumnTableModel.cpp
- catalog/models/ConstraintModel.cpp
- catalog/models/DatabasesTableModel.cpp
- catalog/models/DependantsTableModel.cpp
- catalog/models/IndexModel.cpp
- catalog/models/ProcTableModel.cpp
- catalog/models/RolesTableModel.cpp
- catalog/models/SequenceModel.cpp
- catalog/models/TriggerTableModel.cpp
- catalog/tables/TablesTableModel.cpp
- catalog/widgets/CatalogConstraintPage.cpp
- catalog/widgets/CatalogFunctionsPage.cpp
- catalog/widgets/CatalogIndexPage.cpp
- catalog/widgets/CatalogInspector.cpp
- catalog/widgets/CatalogNamespacePage.cpp
- catalog/widgets/CatalogPageBase.cpp
- catalog/widgets/CatalogSequencesPage.cpp
- catalog/widgets/CatalogTablesPage.cpp
- catalog/widgets/CatalogTypesPage.cpp
- catalog/widgets/ColumnPage.cpp
- catalog/widgets/DependantsPage.cpp
- catalog/widgets/TriggerPage.cpp
- codeeditor/CodeEditor.cpp
- codeeditor/EditorGutter.cpp
- codeeditor/GutterPainter.cpp
- crud/CrudModel.cpp
- crud/CrudTab.cpp
- querytool/QueryExplainModel.cpp
- querytool/QueryParamListController.cpp
- querytool/QueryResultModel.cpp
- querytool/QueryTool.cpp
- serverinspector/DatabasesPage.cpp
- serverinspector/RolesPage.cpp
- serverinspector/ServerInspector.cpp
- util/Colors.cpp
- util/PgLabItemDelegate.cpp
- util/PgLabTableView.cpp
- util/SqlSyntaxHighlighter.cpp
- ConnectionConfigurationWidget.cpp
- ConnectionController.cpp
- ManagedPage.cpp
- PgDumpOutputHighlighter.cpp
- CreateDatabaseDialog.cpp
- ConnectionManagerWindow.cpp
- ConnectionListModel.cpp
- SslModeModel.cpp
- stopwatch.cpp
- tuplesresultwidget.cpp
- BackupDialog.cpp
- MasterController.cpp
- ParamTypeDelegate.cpp
- OpenDatabase.cpp
- ProcessStdioWidget.cpp
- ResultTableModelUtil.cpp
- NamespaceItemModel.cpp
- PropertyProxyModel.cpp
- CodeGenerator.cpp
- UserConfiguration.cpp
- widgets/SqlCodePreview.cpp
- CustomFilterSortModel.cpp
- PropertiesPage.cpp
- PasswordPromptDialog.cpp
- EditTableWidget.cpp
- EditColumnTableModel.cpp
- DatabaseWindow.cpp
- widgets/SingleRecordModel.cpp
- widgets/SingleRecordWidget.cpp
- )
+cmake_minimum_required(VERSION 3.2)
+project(pglab)
-set(PGLAB_FORMS
- ConnectionManagerWindow.ui
- CreateDatabaseDialog.ui
- DatabaseWindow.ui
- tuplesresultwidget.ui
- querytool/QueryTab.ui
- ProcessStdioWidget.ui
- crud/CrudTab.ui
- CodeGenerator.ui
- widgets/SingleRecordWidget.ui
- )
+set(CMAKE_AUTOMOC ON)
+set(CMAKE_AUTOUIC ON)
+set(CMAKE_AUTORCC ON)
add_executable(pglab
- ${PGLAB_SOURCES}
- ${PGLAB_FORMS}
+ ASyncDBConnection.cpp
+ ASyncWindow.cpp
+ BackupDialog.cpp
+ BackupRestore.cpp
+ CodeBuilderConfiguration.cpp
+ ConnectionConfig.cpp
+ ConnectionList.cpp
+ ConnectionListModel.cpp
+ ConnectionManagerWindow.cpp
+ DatabaseInspectorWidget.cpp
+ DatabasesTableModel.cpp
+ DatabaseWindow.cpp
+ ExplainTreeModelItem.cpp
+ GlobalIoService.cpp
+ jsoncpp.cpp
+ main.cpp
+ MainWindow.cpp
+ MasterController.cpp
+ OpenDatabase.cpp
+ ParamListModel.cpp
+ ParamTypeDelegate.cpp
+ PgAuthIdContainer.cpp
+ PgAuthId.cpp
+ PgClass.cpp
+ PgDatabaseCatalogue.cpp
+ PgDatabaseContainer.cpp
+ PgDatabase.cpp
+ PgNamespace.cpp
+ PgTypeContainer.cpp
+ PgType.cpp
+ ProcessStdioWidget.cpp
+ QueryExplainModel.cpp
+ QueryResultModel.cpp
+ QueryTab.cpp
+ RolesTableModel.cpp
+ ServerWindow.cpp
+ SqlSyntaxHighlighter.cpp
+ stopwatch.cpp
+ tsqueue.cpp
+ tuplesresultwidget.cpp
+ TypeSelectionItemModel.cpp
+ util.cpp
resources.qrc
)
-if(WIN32)
- set_target_properties(pglab PROPERTIES WIN32_EXECUTABLE ON)
+set_target_properties(pglab PROPERTIES
+ CXX_STANDARD 14
+ CXX_STANDARD_REQUIRED ON)
+
+if(CMAKE_COMPILER_IS_GNUCXX)
+ # target_compile_options(pglab PRIVATE -Wall -fpic -march=native )
+ # set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og")
endif()
-target_link_libraries(pglab PRIVATE
- pglablib
+target_link_libraries( pglab
+ core
pgsql
- core
- Qt6::Core
- Qt6::Gui
- Qt6::Widgets
- Qt6::Sql
- Qt6::Concurrent
- )
-
-target_include_directories(pglab PRIVATE
- ${CMAKE_CURRENT_SOURCE_DIR}
- )
-
-set_target_properties(pglab PROPERTIES
- CXX_STANDARD 20
- CXX_STANDARD_REQUIRED ON
+ boost-system
+ Qt5::Widgets
+ pthread
)
diff --git a/pglab/CreateDatabaseDialog.h b/pglab/CreateDatabaseDialog.h
index 74cb209..bcc00af 100644
--- a/pglab/CreateDatabaseDialog.h
+++ b/pglab/CreateDatabaseDialog.h
@@ -3,7 +3,7 @@
#include
-#include "catalog/PgDatabase.h"
+#include "catalog\PgDatabase.h"
class PgDatabaseCatalog;
diff --git a/pglab/CreateDatabaseDialog.ui b/pglab/CreateDatabaseDialog.ui
index a16e077..f17dbac 100644
--- a/pglab/CreateDatabaseDialog.ui
+++ b/pglab/CreateDatabaseDialog.ui
@@ -148,7 +148,7 @@
CodeEditor
QPlainTextEdit
-
+
diff --git a/pglab/catalog/models/DatabasesTableModel.cpp b/pglab/catalog/models/DatabasesTableModel.cpp
index 289eea2..ac10ec5 100644
--- a/pglab/catalog/models/DatabasesTableModel.cpp
+++ b/pglab/catalog/models/DatabasesTableModel.cpp
@@ -169,7 +169,7 @@ QVariant DatabasesTableModel::getData(const QModelIndex &index) const
break;
case SizeCol:
if (d.size.totalBytes >= 0)
- v = QVariant::fromValue(d.size.totalBytes);
+ v = d.size.totalBytes;
break;
case AclCol:
v = db.aclString();
diff --git a/pglab/catalog/models/IndexModel.cpp b/pglab/catalog/models/IndexModel.cpp
index e04f715..7cee4e4 100644
--- a/pglab/catalog/models/IndexModel.cpp
+++ b/pglab/catalog/models/IndexModel.cpp
@@ -114,7 +114,7 @@ QVariant IndexModel::getData(const QModelIndex &index) const
break;
case SizeCol:
- v = QVariant::fromValue(dat.sizeBytes);
+ v = dat.sizeBytes;
break;
case ExplicitIndexCol:
v = !dat.isSupportingIndex();
diff --git a/pglab/catalog/models/SequenceModel.cpp b/pglab/catalog/models/SequenceModel.cpp
index 640b50c..659348f 100644
--- a/pglab/catalog/models/SequenceModel.cpp
+++ b/pglab/catalog/models/SequenceModel.cpp
@@ -102,12 +102,12 @@ QVariant SequenceModel::data(const QModelIndex &index, int role) const
case NameCol: return seq.objectName();
case SchemaCol: return seq.nsName();
case OwnerCol: return seq.ownerName();
- case LastCol: return QVariant::fromValue(seq.last);
- case StartCol: return QVariant::fromValue(seq.start);
- case MinCol: return QVariant::fromValue(seq.min);
- case MaxCol: return QVariant::fromValue(seq.max);
- case IncrementCol: return QVariant::fromValue(seq.increment);
- case CacheCol: return QVariant::fromValue(seq.cache);
+ case LastCol: return seq.last;
+ case StartCol: return seq.start;
+ case MinCol: return seq.min;
+ case MaxCol: return seq.max;
+ case IncrementCol: return seq.increment;
+ case CacheCol: return seq.cache;
case CycledCol: return seq.cycled;
case CalledCol: return seq.called;
case AclCol: return seq.aclString();
diff --git a/pglab/catalog/tables/TablesTableModel.cpp b/pglab/catalog/tables/TablesTableModel.cpp
index d6a4e8b..0df8ff2 100644
--- a/pglab/catalog/tables/TablesTableModel.cpp
+++ b/pglab/catalog/tables/TablesTableModel.cpp
@@ -178,10 +178,10 @@ QVariant TablesTableModel::getData(const QModelIndex &index) const
case OptionsCol: break;
case AclCol: return t.aclString();
case CommentCol: return t.description;
- case TotalSizeCol: return s.oid == 0 ? QVariant() : QVariant::fromValue(s.totalBytes);
- case TableSizeCol: return s.oid == 0 ? QVariant() : QVariant::fromValue(s.totalBytes - s.indexBytes - s.toastBytes);
- case IndexSizeCol: return s.oid == 0 ? QVariant() : QVariant::fromValue(s.indexBytes);
- case ToastSizeCol: return s.oid == 0 ? QVariant() : QVariant::fromValue(s.toastBytes);
+ case TotalSizeCol: return s.oid == 0 ? QVariant() : s.totalBytes;
+ case TableSizeCol: return s.oid == 0 ? QVariant() : s.totalBytes - s.indexBytes - s.toastBytes;
+ case IndexSizeCol: return s.oid == 0 ? QVariant() : s.indexBytes;
+ case ToastSizeCol: return s.oid == 0 ? QVariant() : s.toastBytes;
}
return QVariant();
diff --git a/pglab/crud/CrudModel.cpp b/pglab/crud/CrudModel.cpp
index 8367f32..d688bd6 100644
--- a/pglab/crud/CrudModel.cpp
+++ b/pglab/crud/CrudModel.cpp
@@ -150,7 +150,7 @@ QVariant StringToVariant(const std::string &str, Oid oid)
case Pgsql::oid_oid:
case Pgsql::int8_oid:
- return QVariant::fromValue(static_cast(v));
+ return v.operator int64_t();
case Pgsql::bool_oid:
return v.operator bool();
diff --git a/pglab/pglab.pro b/pglab/pglab.pro
new file mode 100644
index 0000000..93a9186
--- /dev/null
+++ b/pglab/pglab.pro
@@ -0,0 +1,229 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2016-11-11T09:17:13
+#
+#-------------------------------------------------
+
+QT += core gui concurrent
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets sql
+
+
+TARGET = pglab
+TEMPLATE = app
+
+! include( ../common.pri ) {
+error( "Couldn't find the common.pri file!" )
+}
+
+DEFINES += _WIN32_WINNT=0x0501
+
+win32:RC_ICONS += pglab.ico
+
+SOURCES += main.cpp\
+ About.cpp \
+ catalog/delegates/IconColumnDelegate.cpp \
+ catalog/models/BaseTableModel.cpp \
+ catalog/models/ColumnTableModel.cpp \
+ catalog/models/ConstraintModel.cpp \
+ catalog/models/DatabasesTableModel.cpp \
+ catalog/models/DependantsTableModel.cpp \
+ catalog/models/IndexModel.cpp \
+ catalog/models/ProcTableModel.cpp \
+ catalog/models/RolesTableModel.cpp \
+ catalog/models/SequenceModel.cpp \
+ catalog/models/TriggerTableModel.cpp \
+ catalog/tables/TablesTableModel.cpp \
+ catalog/widgets/CatalogConstraintPage.cpp \
+ catalog/widgets/CatalogFunctionsPage.cpp \
+ catalog/widgets/CatalogIndexPage.cpp \
+ catalog/widgets/CatalogInspector.cpp \
+ catalog/widgets/CatalogNamespacePage.cpp \
+ catalog/widgets/CatalogPageBase.cpp \
+ catalog/widgets/CatalogSequencesPage.cpp \
+ catalog/widgets/CatalogTablesPage.cpp \
+ catalog/widgets/CatalogTypesPage.cpp \
+ catalog/widgets/ColumnPage.cpp \
+ catalog/widgets/DependantsPage.cpp \
+ catalog/widgets/TriggerPage.cpp \
+ codeeditor/CodeEditor.cpp \
+ codeeditor/EditorGutter.cpp \
+ codeeditor/GutterPainter.cpp \
+ crud/CrudModel.cpp \
+ crud/CrudTab.cpp \
+ querytool/QueryExplainModel.cpp \
+ querytool/QueryParamListController.cpp \
+ querytool/QueryResultModel.cpp \
+ querytool/QueryTool.cpp \
+ serverinspector/DatabasesPage.cpp \
+ serverinspector/RolesPage.cpp \
+ serverinspector/ServerInspector.cpp \
+ util/Colors.cpp \
+ util/PgLabItemDelegate.cpp \
+ util/PgLabTableView.cpp \
+ util/SqlSyntaxHighlighter.cpp \
+ ConnectionConfigurationWidget.cpp \
+ ConnectionController.cpp \
+ ManagedPage.cpp \
+ PgDumpOutputHighlighter.cpp \
+ CreateDatabaseDialog.cpp \
+ ConnectionManagerWindow.cpp \
+ ConnectionListModel.cpp \
+ SslModeModel.cpp \
+ stopwatch.cpp \
+ TuplesResultWidget.cpp \
+ BackupDialog.cpp \
+ MasterController.cpp \
+ ParamTypeDelegate.cpp \
+ OpenDatabase.cpp \
+ ProcessStdioWidget.cpp \
+ ResultTableModelUtil.cpp \
+ NamespaceItemModel.cpp \
+ PropertyProxyModel.cpp \
+ CodeGenerator.cpp \
+ UserConfiguration.cpp \
+ widgets/SqlCodePreview.cpp \
+ CustomFilterSortModel.cpp \
+ PropertiesPage.cpp \
+ PasswordPromptDialog.cpp \
+ EditTableWidget.cpp \
+ EditColumnTableModel.cpp \
+ DatabaseWindow.cpp \
+ widgets/SingleRecordModel.cpp \
+ widgets/SingleRecordWidget.cpp
+
+HEADERS += \
+ About.h \
+ Config.h \
+ catalog/delegates/IconColumnDelegate.h \
+ catalog/models/BaseTableModel.h \
+ catalog/models/ColumnTableModel.h \
+ catalog/models/ConstraintModel.h \
+ catalog/models/DatabasesTableModel.h \
+ catalog/models/DependantsTableModel.h \
+ catalog/models/IndexModel.h \
+ catalog/models/ProcTableModel.h \
+ catalog/models/RolesTableModel.h \
+ catalog/models/SequenceModel.h \
+ catalog/models/TriggerTableModel.h \
+ catalog/tables/TablesTableModel.h \
+ catalog/widgets/CatalogConstraintPage.h \
+ catalog/widgets/CatalogFunctionsPage.h \
+ catalog/widgets/CatalogIndexPage.h \
+ catalog/widgets/CatalogInspector.h \
+ catalog/widgets/CatalogNamespacePage.h \
+ catalog/widgets/CatalogPageBase.h \
+ catalog/widgets/CatalogSequencesPage.h \
+ catalog/widgets/CatalogTablesPage.h \
+ catalog/widgets/CatalogTypesPage.h \
+ catalog/widgets/ColumnPage.h \
+ catalog/widgets/DependantsPage.h \
+ catalog/widgets/TriggerPage.h \
+ codeeditor/CodeEditor.h \
+ codeeditor/EditorGutter.h \
+ codeeditor/GutterPainter.h \
+ crud/CrudModel.h \
+ crud/CrudTab.h \
+ querytool/QueryExplainModel.h \
+ querytool/QueryParamListController.h \
+ querytool/QueryResultModel.h \
+ querytool/QueryTool.h \
+ serverinspector/DatabasesPage.h \
+ serverinspector/RolesPage.h \
+ serverinspector/ServerInspector.h \
+ util/Colors.h \
+ util/PgLabItemDelegate.h \
+ util/PgLabTableView.h \
+ util/PgLabTableViewHelper.h \
+ util/SqlSyntaxHighlighter.h \
+ ConnectionConfigurationWidget.h \
+ ConnectionController.h \
+ IDatabaseWindow.h \
+ ManagedPage.h \
+ PgDumpOutputHighlighter.h \
+ CreateDatabaseDialog.h \
+ ConnectionManagerWindow.h \
+ ConnectionListModel.h \
+ SslModeModel.h \
+ stopwatch.h \
+ TuplesResultWidget.h \
+ BackupDialog.h \
+ MasterController.h \
+ ParamTypeDelegate.h \
+ OpenDatabase.h \
+ ProcessStdioWidget.h \
+ ResultTableModelUtil.h \
+ NamespaceItemModel.h \
+ AbstractCommand.h \
+ PropertyProxyModel.h \
+ CustomDataRole.h \
+ CodeGenerator.h \
+ UserConfiguration.h \
+ widgets/SqlCodePreview.h \
+ CustomFilterSortModel.h \
+ PropertiesPage.h \
+ PasswordPromptDialog.h \
+ EditTableWidget.h \
+ EditColumnTableModel.h \
+ DatabaseWindow.h \
+ NamespaceFilter.h \
+ widgets/SingleRecordModel.h \
+ widgets/SingleRecordWidget.h
+
+FORMS += \
+ ConnectionManagerWindow.ui \
+ CreateDatabaseDialog.ui \
+ DatabaseWindow.ui \
+ TuplesResultWidget.ui \
+ querytool/QueryTab.ui \
+ ProcessStdioWidget.ui \
+ crud/CrudTab.ui \
+ CodeGenerator.ui \
+ widgets/SingleRecordWidget.ui
+
+RESOURCES += \
+ resources.qrc
+
+#QMAKE_LFLAGS_WINDOWS = /SUBSYSTEM:WINDOWS,5.01
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/release/ -lcore
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -lcore
+
+INCLUDEPATH += $$PWD/../core
+DEPENDPATH += $$PWD/../core
+
+win32:CONFIG(debug, debug|release): LIBS += -lbotand
+else:win32:CONFIG(release, debug|release): LIBS += -lbotan
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/libcore.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/libcore.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/core.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/core.lib
+
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../pgsql/release/ -lpgsql
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../pgsql/debug/ -lpgsql
+else:unix:!macx: LIBS += -L$$OUT_PWD/../pgsql/ -lpgsql
+
+INCLUDEPATH += $$PWD/../pgsql
+DEPENDPATH += $$PWD/../pgsql
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/release/libpgsql.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/debug/libpgsql.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/release/pgsql.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/debug/pgsql.lib
+else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../pgsql/libpgsql.a
+
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../pglablib/release/ -lpglablib
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../pglablib/debug/ -lpglablib
+else:unix:!macx: LIBS += -L$$OUT_PWD/../pglablib/ -lpglablib
+
+INCLUDEPATH += $$PWD/../pglablib
+DEPENDPATH += $$PWD/../pglablib
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pglablib/release/libpglablib.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pglablib/debug/libpglablib.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pglablib/release/pglablib.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pglablib/debug/pglablib.lib
+else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../pglablib/libpglablib.a
diff --git a/pglab/querytool/QueryExplainModel.cpp b/pglab/querytool/QueryExplainModel.cpp
index bcce73b..51381ec 100644
--- a/pglab/querytool/QueryExplainModel.cpp
+++ b/pglab/querytool/QueryExplainModel.cpp
@@ -40,7 +40,7 @@ if (role == Qt::DisplayRole) {
result = item->estimateError();
break;
case c_ColumnRowCount:
- result = QVariant::fromValue(item->actualRows);
+ result = item->actualRows;
break;
case c_ColumnLoops:
result = item->actualLoops;
diff --git a/pglabAll.pro b/pglabAll.pro
new file mode 100644
index 0000000..8631a5e
--- /dev/null
+++ b/pglabAll.pro
@@ -0,0 +1,18 @@
+TEMPLATE = subdirs
+
+DEFINES += BOOST_ENABLE_ASSERT_HANDLER
+
+SUBDIRS += core \
+ pgsql \
+ pglablib \
+ pglab
+
+pglab.depends = core pgsql pglablib
+pgsql.depends = core
+pglablib.depends = core pgsql
+tests.depends = core pgsql pglablib
+
+
+CONFIG(debug, debug|release) {
+SUBDIRS += tests
+}
diff --git a/pglablib/ASyncDBConnection.cpp b/pglablib/ASyncDBConnection.cpp
index 2b5c2fb..1c27fb9 100644
--- a/pglablib/ASyncDBConnection.cpp
+++ b/pglablib/ASyncDBConnection.cpp
@@ -1,14 +1,13 @@
-#include "ASyncDBConnection.h"
+#include "ASyncDBConnection.h"
#include "ScopeGuard.h"
#include "util.h"
#include "Pgsql_PgException.h"
-#include
+#include "Win32Event.h"
+#include "WaitHandleList.h"
#include
#include
+#include
#include
-#include
-#include
-#include
namespace {
@@ -46,6 +45,10 @@ public:
struct t_Command {
std::mutex m_mutex;
t_CommandQueue m_queue;
+ Win32Event m_newEvent;
+ t_Command()
+ : m_newEvent(Win32Event::Reset::Auto, Win32Event::Initial::Clear)
+ {}
} m_commandQueue;
ConnectionConfig m_config;
@@ -61,29 +64,18 @@ public:
void stop();
- /// Wakes the worker thread when it is waiting in its event loop
- void wake();
-
private:
- enum class WaitResult {
- Socket, ///< the socket became ready
- Wakeup, ///< woken up by stop() or by a new command
- Timeout ///< the timeout expired
- };
-
ASyncDBConnection *asyncConnObject = nullptr;
- std::atomic terminateRequested{false}; ///< is set when the thread should stop
- std::mutex m_wakeMutex;
- QEventLoop *m_loop = nullptr; ///< loop the worker blocks in, guarded by m_wakeMutex
+ /// \todo Implement new method to stop the thread
+ Win32Event m_stopEvent;
Pgsql::Connection m_connection;
+ bool terminateRequested = false; ///< is set when the thread should stop
bool m_terminated = true;
Pgsql::Canceller m_canceller;
QElapsedTimer m_timer;
- bool hasQueuedCommand();
- WaitResult waitForSocket(QSocketNotifier::Type type, int timeout_ms, bool wakeOnNewCommand);
bool makeConnection();
void communicate();
@@ -105,6 +97,7 @@ private:
ASyncDBConnectionThread::ASyncDBConnectionThread(ASyncDBConnection *asco)
: asyncConnObject(asco)
+ , m_stopEvent(Win32Event::Reset::Manual, Win32Event::Initial::Clear)
{}
void ASyncDBConnectionThread::run()
@@ -161,59 +154,6 @@ bool ASyncDBConnectionThread::cancel()
return m_canceller.cancel(nullptr);
}
-bool ASyncDBConnectionThread::hasQueuedCommand()
-{
- std::lock_guard lg(m_commandQueue.m_mutex);
- return !m_commandQueue.m_queue.empty();
-}
-
-ASyncDBConnectionThread::WaitResult ASyncDBConnectionThread::waitForSocket(QSocketNotifier::Type type, int timeout_ms, bool wakeOnNewCommand)
-{
- QEventLoop loop;
- WaitResult result = WaitResult::Wakeup;
-
- QSocketNotifier notifier(m_connection.socket(), type);
- QObject::connect(¬ifier, &QSocketNotifier::activated, &loop, [&result, &loop] {
- result = WaitResult::Socket;
- loop.quit();
- });
-
- QTimer timer;
- timer.setSingleShot(true);
- if (timeout_ms >= 0) {
- QObject::connect(&timer, &QTimer::timeout, &loop, [&result, &loop] {
- result = WaitResult::Timeout;
- loop.quit();
- });
- timer.start(timeout_ms);
- }
-
- {
- std::lock_guard lg(m_wakeMutex);
- m_loop = &loop;
- }
-
- // Checked after publishing the loop, so a wake-up that happened before is not lost
- bool pending = terminateRequested || (wakeOnNewCommand && hasQueuedCommand());
- if (!pending) {
- loop.exec();
- }
-
- {
- std::lock_guard lg(m_wakeMutex);
- m_loop = nullptr;
- }
- return result;
-}
-
-void ASyncDBConnectionThread::wake()
-{
- std::lock_guard lg(m_wakeMutex);
- if (m_loop) {
- QMetaObject::invokeMethod(m_loop, [loop = m_loop] { loop->quit(); }, Qt::QueuedConnection);
- }
-}
-
bool ASyncDBConnectionThread::makeConnection()
{
using namespace std::literals::chrono_literals;
@@ -225,14 +165,30 @@ bool ASyncDBConnectionThread::makeConnection()
bool ok = m_connection.connectStart(conn_string); //keywords, values);
auto start = std::chrono::steady_clock::now();
if (ok && m_connection.status() != CONNECTION_BAD) {
- QSocketNotifier::Type type = QSocketNotifier::Write;
+ Win32Event socket_event(Win32Event::Reset::Auto, Win32Event::Initial::Clear);
+
+ long fd = FD_WRITE;
while (true) {
// poll till complete or failed (we can get an abort command)
- auto elapsed = std::chrono::steady_clock::now() - start;
- auto remaining = std::chrono::duration_cast(30s - elapsed).count();
- WaitResult res = waitForSocket(type, remaining > 0 ? static_cast(remaining) : 0, false);
+ int sock = m_connection.socket();
+ WSAEventSelect(sock, socket_event.handle(), fd);
+ WaitHandleList whl;
+ auto wait_result_socket_event = whl.add(socket_event);
+ auto wait_result_stop = whl.add(m_stopEvent);
- if (res == WaitResult::Socket) {
+ auto nu = std::chrono::steady_clock::now();
+ std::chrono::duration diff = -(nu-start);
+ diff += 30s;
+ DWORD timeout = diff.count();
+
+ DWORD res = MsgWaitForMultipleObjectsEx(
+ whl.count(), // _In_ DWORD nCount,
+ whl, // _In_ const HANDLE *pHandles,
+ timeout, // _In_ DWORD dwMilliseconds,
+ 0, // _In_ DWORD dwWakeMask,
+ 0 // _In_ DWORD dwFlags
+ );
+ if (res == wait_result_socket_event) {
auto poll_state = m_connection.connectPoll();
if (poll_state == PGRES_POLLING_OK) {
qDebug() << "ASyncDBConnection Connected";
@@ -246,21 +202,17 @@ bool ASyncDBConnectionThread::makeConnection()
}
else if (poll_state == PGRES_POLLING_READING) {
doStateCallback({ ASyncDBConnection::State::Connecting, "Negotiating" });
- type = QSocketNotifier::Read;
+ fd = FD_READ;
}
else if (poll_state == PGRES_POLLING_WRITING) {
doStateCallback({ ASyncDBConnection::State::Connecting, "Negotiating" });
- type = QSocketNotifier::Write;
+ fd = FD_WRITE;
}
}
- else if (terminateRequested) {
- m_connection.close();
- return false;
- }
- else if (res == WaitResult::Timeout) {
- doStateCallback({ ASyncDBConnection::State::NotConnected, "Connection timed out" });
+ else if (res == wait_result_stop) {
m_connection.close();
return false;
+
}
} // end while (true)
}
@@ -300,7 +252,7 @@ void ASyncDBConnectionThread::communicate()
void ASyncDBConnectionThread::stop()
{
terminateRequested = true;
- wake();
+ m_stopEvent.set();
}
void ASyncDBConnectionThread::doStateCallback(ASyncDBConnection::StateData state)
@@ -312,18 +264,34 @@ void ASyncDBConnectionThread::doStateCallback(ASyncDBConnection::StateData state
bool ASyncDBConnectionThread::waitForAndSendCommand()
{
- if (hasQueuedCommand()) {
- doNewCommand();
- return true;
- }
+ SOCKET sock = static_cast(m_connection.socket());
+ Win32Event socket_event(Win32Event::Reset::Manual, Win32Event::Initial::Clear);
+ long fd = FD_READ | FD_CLOSE;
+ WSAEventSelect(sock, socket_event.handle(), fd);
- // Idle connection: a readable socket carries notifies or notices, or signals a lost connection
- if (waitForSocket(QSocketNotifier::Read, -1, true) == WaitResult::Socket) {
- if (!m_connection.consumeInput()) {
- doStateCallback({ ASyncDBConnection::State::NotConnected, "Connection lost" });
- return false;
- }
+ WaitHandleList whl;
+ auto wait_result_new_command = whl.add(m_commandQueue.m_newEvent);
+ auto wait_result_socket = whl.add(socket_event);
+ whl.add(m_stopEvent);
+
+ DWORD res = MsgWaitForMultipleObjectsEx(
+ whl.count(), // _In_ DWORD nCount,
+ whl, // _In_ const HANDLE *pHandles,
+ INFINITE, // _In_ DWORD dwMilliseconds,
+ 0, // _In_ DWORD dwWakeMask,
+ 0 // _In_ DWORD dwFlags
+ );
+ if (res == wait_result_new_command) {
+ doNewCommand();
}
+ else if (res == wait_result_socket) {
+ WSANETWORKEVENTS net_events;
+ WSAEnumNetworkEvents(sock, socket_event.handle(), &net_events);
+ if (net_events.lNetworkEvents & FD_CLOSE) {
+ doStateCallback({ ASyncDBConnection::State::NotConnected, "Connection lost" });
+ return false;
+ }
+ }
// Note if it was stop we can just return and function
// above will stop looping because terminateRequested has been set too by stop
return true;
@@ -379,16 +347,42 @@ bool ASyncDBConnectionThread::consumeResultInput()
void ASyncDBConnectionThread::waitForResult()
{
+ SOCKET sock = static_cast(m_connection.socket());
+ Win32Event socket_event(Win32Event::Reset::Manual, Win32Event::Initial::Clear);
+
+ long fd = FD_READ | FD_CLOSE;
+
bool finished = false;
while ( ! finished) {
- WaitResult res = waitForSocket(QSocketNotifier::Read, -1, false);
+ WSAEventSelect(sock, socket_event.handle(), fd);
- if (res == WaitResult::Socket) {
- if (consumeResultInput()) {
- finished = true;
+ WaitHandleList whl;
+ auto wait_result_socket = whl.add(socket_event);
+ auto wait_result_stop = whl.add(m_stopEvent);
+
+ DWORD res = MsgWaitForMultipleObjectsEx(
+ whl.count(), // _In_ DWORD nCount,
+ whl, // _In_ const HANDLE *pHandles,
+ INFINITE, // _In_ DWORD dwMilliseconds,
+ 0, // _In_ DWORD dwWakeMask,
+ 0 // _In_ DWORD dwFlags
+ );
+ if (res == wait_result_socket) {
+ WSANETWORKEVENTS net_events;
+ WSAEnumNetworkEvents(sock, socket_event.handle(), &net_events);
+
+ if (net_events.lNetworkEvents & FD_READ) {
+ if (consumeResultInput()) {
+ finished = true;
+ }
}
+ else if (net_events.lNetworkEvents & FD_CLOSE) {
+ doStateCallback({ ASyncDBConnection::State::NotConnected, "Close while waiting for result" });
+ finished = true;
+ stop();
+ }
}
- else if (terminateRequested) {
+ if (res == wait_result_stop) {
// Send cancel, close connection and terminate thread
cancel();
doStateCallback(ASyncDBConnection::State::Terminating);
@@ -461,8 +455,8 @@ bool ASyncDBConnection::send(const std::string &command, on_result_callback on_r
{
std::lock_guard lg(m_threadData->m_commandQueue.m_mutex);
m_threadData->m_commandQueue.m_queue.emplace(command, on_result);
+ m_threadData->m_commandQueue.m_newEvent.set();
}
- m_threadData->wake();
return true;
}
@@ -474,8 +468,8 @@ bool ASyncDBConnection::send(const std::string &command, Pgsql::Params params, o
{
std::lock_guard lg(m_threadData->m_commandQueue.m_mutex);
m_threadData->m_commandQueue.m_queue.emplace(command, std::move(params), on_result);
+ m_threadData->m_commandQueue.m_newEvent.set();
}
- m_threadData->wake();
return true;
}
diff --git a/pglablib/ASyncDBConnection.h b/pglablib/ASyncDBConnection.h
index 0479f5f..02f5310 100644
--- a/pglablib/ASyncDBConnection.h
+++ b/pglablib/ASyncDBConnection.h
@@ -11,7 +11,6 @@
#include
#include
#include
-#include
class ASyncDBConnectionThread;
/** \brief Class that handles asynchronous execution of queries.
@@ -34,7 +33,7 @@ public:
class StateData {
public:
- enum State State;
+ State State;
QString Message;
StateData(enum State state, QString message = QString())
diff --git a/pglablib/CMakeLists.txt b/pglablib/CMakeLists.txt
deleted file mode 100644
index a3c759d..0000000
--- a/pglablib/CMakeLists.txt
+++ /dev/null
@@ -1,187 +0,0 @@
-add_library(pglablib STATIC
- Pglablib.cpp
- ASyncDBConnection.cpp
- ConnectionConfig.cpp
- TestConnection.cpp
- catalog/PgType.cpp
- catalog/PgTypeContainer.cpp
- catalog/PgNamespace.cpp
- catalog/PgClass.cpp
- catalog/PgDatabase.cpp
- catalog/PgDatabaseContainer.cpp
- catalog/PgAuthId.cpp
- catalog/PgAuthIdContainer.cpp
- catalog/PgClassContainer.cpp
- catalog/PgDatabaseCatalog.cpp
- catalog/PgNamespaceContainer.cpp
- catalog/PgAttribute.cpp
- catalog/PgContainer.cpp
- catalog/PgAttributeContainer.cpp
- catalog/PgIndex.cpp
- catalog/PgIndexContainer.cpp
- catalog/PgConstraint.cpp
- catalog/PgConstraintContainer.cpp
- ParamListJson.cpp
- ParamListModel.cpp
- sqlite/SQLiteConnection.cpp
- sqlite/sqlite3.c
- ui/catalog/tables/TableNode.cpp
- ui/catalog/tables/TableSize.cpp
- ui/catalog/tables/TableTreeBuilder.cpp
- util.cpp
- SqlFormattingUtils.cpp
- catalog/PgKeywordList.cpp
- QueryGenerator.cpp
- catalog/PgObject.cpp
- catalog/PgTablespace.cpp
- catalog/PgTablespaceContainer.cpp
- codebuilder/LanguageConfig.cpp
- codebuilder/CodeBuilder.cpp
- codebuilder/NameManglingRules.cpp
- codebuilder/DefaultConfigs.cpp
- codebuilder/TypeMappings.cpp
- codebuilder/IndentationConfig.cpp
- codebuilder/StructureTemplate.cpp
- FormatToStream.cpp
- codebuilder/StringLiteralRules.cpp
- codebuilder/StringEscapeRule.cpp
- catalog/PgTrigger.cpp
- catalog/PgTriggerContainer.cpp
- catalog/PgProc.cpp
- catalog/PgProcContainer.cpp
- catalog/PgDatabaseObject.cpp
- catalog/PgServerObject.cpp
- catalog/PgNamespaceObject.cpp
- catalog/PgCollation.cpp
- catalog/PgCollationContainer.cpp
- catalog/PgInherits.cpp
- catalog/PgInheritsContainer.cpp
- SelectionEditorFactory.cpp
- catalog/PgAm.cpp
- model/TypeModelFactory.cpp
- model/TypeSelectionItemModel.cpp
- catalog/PgAmContainer.cpp
- model/CollationModel.cpp
- model/CollationModelFactory.cpp
- catalog/PgLanguageContainer.cpp
- catalog/PgLanguage.cpp
- catalog/PgAcl.cpp
- catalog/PgSequence.cpp
- catalog/PgSequenceContainer.cpp
- utils/HumanReadableBytes.cpp
- utils/KeyStrengthener.cpp
- utils/PasswordManager.cpp
- utils/PostgresqlUrlParser.cpp
- Pglablib.h
- ASyncDBConnection.h
- ConnectionConfig.h
- TestConnection.h
- catalog/PgType.h
- catalog/PgTypeContainer.h
- catalog/PgNamespace.h
- catalog/PgClass.h
- catalog/PgDatabase.h
- catalog/PgDatabaseContainer.h
- catalog/PgContainer.h
- catalog/PgAuthId.h
- catalog/PgAuthIdContainer.h
- catalog/PgClassContainer.h
- catalog/PgDatabaseCatalog.h
- catalog/PgNamespaceContainer.h
- catalog/PgAttribute.h
- catalog/PgAttributeContainer.h
- catalog/PgIndex.h
- catalog/PgIndexContainer.h
- catalog/PgConstraint.h
- catalog/PgConstraintContainer.h
- ParamListJson.h
- ParamListModel.h
- sqlite/SQLiteConnection.h
- sqlite/sqlite3.h
- sqlite/sqlite3ext.h
- ui/catalog/tables/TableNode.h
- ui/catalog/tables/TableSize.h
- ui/catalog/tables/TableTreeBuilder.h
- util.h
- SqlFormattingUtils.h
- catalog/PgCatalogTypes.h
- catalog/PgKeywordList.h
- QueryGenerator.h
- catalog/PgObject.h
- catalog/PgTablespace.h
- catalog/PgTablespaceContainer.h
- codebuilder/LanguageConfig.h
- codebuilder/CodeBuilder.h
- codebuilder/NameManglingRules.h
- codebuilder/DefaultConfigs.h
- codebuilder/TypeMappings.h
- codebuilder/IndentationConfig.h
- codebuilder/StructureTemplate.h
- FormatToStream.h
- codebuilder/ResultLoopTemplate.h
- codebuilder/StringEscapeRule.h
- codebuilder/StringLiteralRules.h
- catalog/PgTrigger.h
- catalog/PgTriggerContainer.h
- catalog/PgProc.h
- catalog/PgProcContainer.h
- catalog/PgDatabaseObject.h
- catalog/PgServerObject.h
- catalog/PgNamespaceObject.h
- catalog/PgCollation.h
- catalog/PgCollationContainer.h
- AbstractModelFactory.h
- AbstractEditorFactory.h
- catalog/PgInherits.h
- catalog/PgInheritsContainer.h
- SelectionEditorFactory.h
- model/TypeSelectionItemModel.h
- model/TypeModelFactory.h
- catalog/PgAm.h
- catalog/PgAmContainer.h
- model/CollationModel.h
- model/CollationModelFactory.h
- catalog/PgLanguageContainer.h
- catalog/PgLanguage.h
- catalog/PgAcl.h
- catalog/PgSequence.h
- catalog/PgSequenceContainer.h
- utils/HumanReadableBytes.h
- utils/KeyStrengthener.h
- utils/PasswordManager.h
- utils/PostgresqlUrlParser.h
- )
-
-find_package(Boost REQUIRED COMPONENTS container timer chrono assert)
-
-find_path(BOTAN_INCLUDE_DIR botan/hash.h REQUIRED)
-find_library(BOTAN_LIBRARY NAMES botan-3 botan REQUIRED)
-if(NOT TARGET Botan::Botan)
- add_library(Botan::Botan STATIC IMPORTED)
- set_target_properties(Botan::Botan PROPERTIES
- IMPORTED_LOCATION "${BOTAN_LIBRARY}"
- INTERFACE_INCLUDE_DIRECTORIES "${BOTAN_INCLUDE_DIR}"
- )
-endif()
-
-target_link_libraries(pglablib PUBLIC
- core
- pgsql
- Boost::container
- Boost::timer
- Boost::chrono
- Boost::assert
- Botan::Botan
- Qt6::Core
- Qt6::Widgets
- )
-
-target_include_directories(pglablib PUBLIC
- $
- )
-
-set_target_properties(pglablib PROPERTIES
- CXX_STANDARD 20
- CXX_STANDARD_REQUIRED ON
- POSITION_INDEPENDENT_CODE ON
- )
diff --git a/pglablib/SqlFormattingUtils.cpp b/pglablib/SqlFormattingUtils.cpp
index ff7f1d3..a75620e 100644
--- a/pglablib/SqlFormattingUtils.cpp
+++ b/pglablib/SqlFormattingUtils.cpp
@@ -200,7 +200,7 @@ QString quoteIdent(QString ident)
{
assert(ident.length() > 0);
- static const QChar dquote = u'"';
+ static const wchar_t dquote = L'"';
if (identNeedsQuotes(ident)) {
QString out;
diff --git a/pglablib/WaitHandleList.cpp b/pglablib/WaitHandleList.cpp
new file mode 100644
index 0000000..d219610
--- /dev/null
+++ b/pglablib/WaitHandleList.cpp
@@ -0,0 +1,31 @@
+#include "WaitHandleList.h"
+#include "win32event.h"
+
+WaitHandleList::WaitHandleList() = default;
+WaitHandleList::~WaitHandleList() = default;
+
+WaitResultValue WaitHandleList::add(HANDLE h)
+{
+ m_waitHandles.push_back(h);
+ return WAIT_OBJECT_0 + static_cast(m_waitHandles.size() - 1);
+}
+
+WaitResultValue WaitHandleList::add(Win32Event &e)
+{
+ return add(e.handle());
+}
+
+DWORD WaitHandleList::count() const
+{
+ return static_cast(m_waitHandles.size());
+}
+
+void WaitHandleList::clear()
+{
+ m_waitHandles.clear();
+}
+
+WaitHandleList::operator const HANDLE*() const
+{
+ return m_waitHandles.data();
+}
diff --git a/pglablib/WaitHandleList.h b/pglablib/WaitHandleList.h
new file mode 100644
index 0000000..376e817
--- /dev/null
+++ b/pglablib/WaitHandleList.h
@@ -0,0 +1,26 @@
+#ifndef WAITHANDLELIST_H
+#define WAITHANDLELIST_H
+
+#include
+#include
+
+class Win32Event;
+
+using WaitResultValue = DWORD;
+
+class WaitHandleList {
+public:
+ WaitHandleList();
+ ~WaitHandleList();
+
+ WaitResultValue add(HANDLE h);
+ WaitResultValue add(Win32Event &e);
+ DWORD count() const;
+ void clear();
+ operator const HANDLE*() const;
+
+private:
+ std::vector m_waitHandles;
+};
+
+#endif // WAITHANDLELIST_H
diff --git a/pglablib/Win32Event.h b/pglablib/Win32Event.h
new file mode 100644
index 0000000..684d13f
--- /dev/null
+++ b/pglablib/Win32Event.h
@@ -0,0 +1,47 @@
+#ifndef WIN32EVENT_H
+#define WIN32EVENT_H
+
+#include
+
+#include
+/** Simpel wrapper around a Win32 Event object.
+
+Mostly to make cleanup automatic.*/
+class Win32Event {
+public:
+ enum class Reset { Auto=0, Manual=1 };
+ enum class Initial { Clear=0, Set=1 };
+
+ Win32Event(Reset r, Initial is)
+ : hEvent(CreateEvent(
+ nullptr, // _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
+ BOOL(r), // _In_ BOOL bManualReset,
+ BOOL(is), // _In_ BOOL bInitialState,
+ nullptr //_In_opt_ LPCTSTR lpName
+ ))
+ {}
+
+ Win32Event(Reset r, Initial is, int sock, long net_events)
+ : Win32Event(r, is)
+ {
+ WSAEventSelect(sock, hEvent, net_events);
+ }
+
+ ~Win32Event()
+ {
+ CloseHandle(hEvent);
+ }
+
+ Win32Event(const Win32Event &) = delete;
+ Win32Event &operator=(const Win32Event &) = delete;
+
+ void set() { SetEvent(hEvent); }
+
+ void reset() { ResetEvent(hEvent); }
+
+ HANDLE handle() { return hEvent; }
+private:
+ HANDLE hEvent;
+};
+
+#endif // WIN32EVENT_H
diff --git a/pglablib/catalog/PgLanguage.cpp b/pglablib/catalog/PgLanguage.cpp
index c224d23..cd9dd4f 100644
--- a/pglablib/catalog/PgLanguage.cpp
+++ b/pglablib/catalog/PgLanguage.cpp
@@ -1,15 +1,13 @@
#include "PgLanguage.h"
-#include
-
QString PgLanguage::createSql() const
{
- throw std::logic_error("PgLanguage::createSql() not implemented");
+ throw std::exception("PgLanguage::createSql() not implemented");
}
QString PgLanguage::dropSql() const
{
- throw std::logic_error("PgLanguage::dropSql() not implemented");
+ throw std::exception("PgLanguage::dropSql() not implemented");
}
QString PgLanguage::typeName() const
diff --git a/pglablib/catalog/PgProc.cpp b/pglablib/catalog/PgProc.cpp
index 02cf6d0..83fe734 100644
--- a/pglablib/catalog/PgProc.cpp
+++ b/pglablib/catalog/PgProc.cpp
@@ -48,15 +48,15 @@ namespace {
for(; index < len; index++) {
QChar ch = str[index];
- if (!double_quote && ch == u'\'')
+ if (!double_quote && ch == L'\'')
single_quote = !single_quote;
- else if (!single_quote && ch == u'"')
+ else if (!single_quote && ch == L'"')
double_quote = !double_quote;
- else if (!double_quote && !single_quote && ch == u'(')
+ else if (!double_quote && !single_quote && ch == L'(')
brackets++;
- else if (!double_quote && !single_quote && ch == u')')
+ else if (!double_quote && !single_quote && ch == L')')
brackets--;
- else if (!double_quote && !single_quote && brackets == 0 && ch == u',') {
+ else if (!double_quote && !single_quote && brackets == 0 && ch == L',') {
if (index != start_array)
res.push_back(str.mid(start_array, index - 1).trimmed());
else
diff --git a/pglablib/catalog/PgServerObject.cpp b/pglablib/catalog/PgServerObject.cpp
index 1108917..f85bd1f 100644
--- a/pglablib/catalog/PgServerObject.cpp
+++ b/pglablib/catalog/PgServerObject.cpp
@@ -38,7 +38,7 @@ QString PgServerObject::alterOwnerSql(const QString& ident) const
}
-void PgServerObject::setAcls(std::optional acls)
+void PgServerObject::setAcls(boost::optional acls)
{
m_acls = std::move(acls);
}
diff --git a/pglablib/catalog/PgServerObject.h b/pglablib/catalog/PgServerObject.h
index b1520a1..5c08fd3 100644
--- a/pglablib/catalog/PgServerObject.h
+++ b/pglablib/catalog/PgServerObject.h
@@ -4,7 +4,7 @@
#include
#include "PgObject.h"
#include "PgAcl.h"
-#include
+#include
class PgAuthId;
@@ -26,7 +26,7 @@ public:
* @brief setAcls
* @param acls Important: pass empty optional when acl IS NULL, pass empty list for empty array
*/
- void setAcls(std::optional acls);
+ void setAcls(boost::optional acls);
QString aclString() const;
/**
* @brief grantSql
@@ -53,7 +53,7 @@ protected:
private:
Oid m_ownerOid = InvalidOid;
const PgAuthId * m_owner = nullptr;
- std::optional m_acls;
+ boost::optional m_acls;
};
#endif // PGSERVEROBJECT_H
diff --git a/pglablib/codebuilder/StringEscapeRule.h b/pglablib/codebuilder/StringEscapeRule.h
index fb01dd8..a8c9822 100644
--- a/pglablib/codebuilder/StringEscapeRule.h
+++ b/pglablib/codebuilder/StringEscapeRule.h
@@ -2,6 +2,7 @@
#define STRINGESCAPERULE_H
#include
+#include
enum class ConvertToNumericEscape {
Utf8, ///< Generates upto four escapes for 4 utf8 chars
diff --git a/pglablib/pglablib.pro b/pglablib/pglablib.pro
new file mode 100644
index 0000000..c41f973
--- /dev/null
+++ b/pglablib/pglablib.pro
@@ -0,0 +1,222 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2017-12-13T17:36:43
+#
+#-------------------------------------------------
+
+QT += widgets core
+
+TARGET = pglablib
+TEMPLATE = lib
+CONFIG += staticlib
+
+! include( ../common.pri ) {
+error( "Couldn't find the common.pri file!" )
+}
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ Pglablib.cpp \
+ ASyncDBConnection.cpp \
+ ConnectionConfig.cpp \
+ TestConnection.cpp \
+ WaitHandleList.cpp \
+ catalog/PgType.cpp \
+ catalog/PgTypeContainer.cpp \
+ catalog/PgNamespace.cpp \
+ catalog/PgClass.cpp \
+ catalog/PgDatabase.cpp \
+ catalog/PgDatabaseContainer.cpp \
+ catalog/PgAuthId.cpp \
+ catalog/PgAuthIdContainer.cpp \
+ catalog/PgClassContainer.cpp \
+ catalog/PgDatabaseCatalog.cpp \
+ catalog/PgNamespaceContainer.cpp \
+ catalog/PgAttribute.cpp \
+ catalog/PgContainer.cpp \
+ catalog/PgAttributeContainer.cpp \
+ catalog/PgIndex.cpp \
+ catalog/PgIndexContainer.cpp \
+ catalog/PgConstraint.cpp \
+ catalog/PgConstraintContainer.cpp \
+ ParamListJson.cpp \
+ ParamListModel.cpp \
+ sqlite/SQLiteConnection.cpp \
+ sqlite/sqlite3.c \
+ ui/catalog/tables/TableNode.cpp \
+ ui/catalog/tables/TableSize.cpp \
+ ui/catalog/tables/TableTreeBuilder.cpp \
+ util.cpp \
+ SqlFormattingUtils.cpp \
+ catalog/PgKeywordList.cpp \
+ QueryGenerator.cpp \
+ catalog/PgObject.cpp \
+ catalog/PgTablespace.cpp \
+ catalog/PgTablespaceContainer.cpp \
+ codebuilder/LanguageConfig.cpp \
+ codebuilder/CodeBuilder.cpp \
+ codebuilder/NameManglingRules.cpp \
+ codebuilder/DefaultConfigs.cpp \
+ codebuilder/TypeMappings.cpp \
+ codebuilder/IndentationConfig.cpp \
+ codebuilder/StructureTemplate.cpp \
+ FormatToStream.cpp \
+ codebuilder/StringLiteralRules.cpp \
+ codebuilder/StringEscapeRule.cpp \
+ catalog/PgTrigger.cpp \
+ catalog/PgTriggerContainer.cpp \
+ catalog/PgProc.cpp \
+ catalog/PgProcContainer.cpp \
+ catalog/PgDatabaseObject.cpp \
+ catalog/PgServerObject.cpp \
+ catalog/PgNamespaceObject.cpp \
+ catalog/PgCollation.cpp \
+ catalog/PgCollationContainer.cpp \
+ catalog/PgInherits.cpp \
+ catalog/PgInheritsContainer.cpp \
+ SelectionEditorFactory.cpp \
+ catalog/PgAm.cpp \
+ model/TypeModelFactory.cpp \
+ model/TypeSelectionItemModel.cpp \
+ catalog/PgAmContainer.cpp \
+ model/CollationModel.cpp \
+ model/CollationModelFactory.cpp \
+ catalog/PgLanguageContainer.cpp \
+ catalog/PgLanguage.cpp \
+ catalog/PgAcl.cpp \
+ catalog/PgSequence.cpp \
+ catalog/PgSequenceContainer.cpp \
+ utils/HumanReadableBytes.cpp \
+ utils/KeyStrengthener.cpp \
+ utils/PasswordManager.cpp \
+ utils/PostgresqlUrlParser.cpp
+
+HEADERS += \
+ Pglablib.h \
+ ASyncDBConnection.h \
+ ConnectionConfig.h \
+ TestConnection.h \
+ WaitHandleList.h \
+ Win32Event.h \
+ catalog/PgType.h \
+ catalog/PgTypeContainer.h \
+ catalog/PgNamespace.h \
+ catalog/PgClass.h \
+ catalog/PgDatabase.h \
+ catalog/PgDatabaseContainer.h \
+ catalog/PgContainer.h \
+ catalog/PgAuthId.h \
+ catalog/PgAuthIdContainer.h \
+ catalog/PgClassContainer.h \
+ catalog/PgDatabaseCatalog.h \
+ catalog/PgNamespaceContainer.h \
+ catalog/PgAttribute.h \
+ catalog/PgAttributeContainer.h \
+ catalog/PgIndex.h \
+ catalog/PgIndexContainer.h \
+ catalog/PgConstraint.h \
+ catalog/PgConstraintContainer.h \
+ ParamListJson.h \
+ ParamListModel.h \
+ sqlite/SQLiteConnection.h \
+ sqlite/sqlite3.h \
+ sqlite/sqlite3ext.h \
+ ui/catalog/tables/TableNode.h \
+ ui/catalog/tables/TableSize.h \
+ ui/catalog/tables/TableTreeBuilder.h \
+ util.h \
+ SqlFormattingUtils.h \
+ catalog/PgCatalogTypes.h \
+ catalog/PgKeywordList.h \
+ QueryGenerator.h \
+ catalog/PgObject.h \
+ catalog/PgTablespace.h \
+ catalog/PgTablespaceContainer.h \
+ codebuilder/LanguageConfig.h \
+ codebuilder/CodeBuilder.h \
+ codebuilder/NameManglingRules.h \
+ codebuilder/DefaultConfigs.h \
+ codebuilder/TypeMappings.h \
+ codebuilder/IndentationConfig.h \
+ codebuilder/StructureTemplate.h \
+ FormatToStream.h \
+ codebuilder/ResultLoopTemplate.h \
+ codebuilder/StringEscapeRule.h \
+ codebuilder/StringLiteralRules.h \
+ catalog/PgTrigger.h \
+ catalog/PgTriggerContainer.h \
+ catalog/PgProc.h \
+ catalog/PgProcContainer.h \
+ catalog/PgDatabaseObject.h \
+ catalog/PgServerObject.h \
+ catalog/PgNamespaceObject.h \
+ catalog/PgCollation.h \
+ catalog/PgCollationContainer.h \
+ AbstractModelFactory.h \
+ AbstractEditorFactory.h \
+ catalog/PgInherits.h \
+ catalog/PgInheritsContainer.h \
+ SelectionEditorFactory.h \
+ model/TypeSelectionItemModel.h \
+ model/TypeModelFactory.h \
+ catalog/PgAm.h \
+ catalog/PgAmContainer.h \
+ model/CollationModel.h \
+ model/CollationModelFactory.h \
+ catalog/PgLanguageContainer.h \
+ catalog/PgLanguage.h \
+ catalog/PgAcl.h \
+ catalog/PgSequence.h \
+ catalog/PgSequenceContainer.h \
+ utils/HumanReadableBytes.h \
+ utils/KeyStrengthener.h \
+ utils/PasswordManager.h \
+ utils/PostgresqlUrlParser.h
+
+unix {
+ target.path = /usr/lib
+ INSTALLS += target
+}
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/release/ -lcore
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -lcore
+else:unix:!macx: LIBS += -L$$OUT_PWD/../core/ -lcore
+
+INCLUDEPATH += $$PWD/../core
+DEPENDPATH += $$PWD/../core
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/libcore.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/libcore.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/core.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/core.lib
+else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../core/libcore.a
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../pgsql/release/ -lpgsql
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../pgsql/debug/ -lpgsql
+else:unix:!macx: LIBS += -L$$OUT_PWD/../pgsql/ -lpgsql
+
+INCLUDEPATH += $$PWD/../pgsql
+DEPENDPATH += $$PWD/../pgsql
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/release/libpgsql.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/debug/libpgsql.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/release/pgsql.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../pgsql/debug/pgsql.lib
+else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../pgsql/libpgsql.a
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/release/ -lcore
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -lcore
+else:unix: LIBS += -L$$OUT_PWD/../core/ -lcore
+
+INCLUDEPATH += $$PWD/../core
+DEPENDPATH += $$PWD/../core
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/libcore.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/libcore.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/core.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/core.lib
+else:unix: PRE_TARGETDEPS += $$OUT_PWD/../core/libcore.a
diff --git a/pglablib/utils/HumanReadableBytes.h b/pglablib/utils/HumanReadableBytes.h
index b17ec0f..b76de05 100644
--- a/pglablib/utils/HumanReadableBytes.h
+++ b/pglablib/utils/HumanReadableBytes.h
@@ -1,6 +1,5 @@
#pragma once
-#include
#include
std::string HumanReadableBytes(uint64_t bytes);
diff --git a/pglablib/utils/PasswordManager.cpp b/pglablib/utils/PasswordManager.cpp
index dfa0476..b0a71de 100644
--- a/pglablib/utils/PasswordManager.cpp
+++ b/pglablib/utils/PasswordManager.cpp
@@ -9,7 +9,7 @@
#include
#include
#include
-#include
+#include
using namespace Botan;
@@ -33,7 +33,7 @@ public:
* distinct key which is derived by hashing the wrapped key name with HMAC.
*/
const std::vector wrapped_name =
- nist_key_wrap_padded(reinterpret_cast(name.data()),
+ nist_key_wrap_padded(cast_char_ptr_to_uint8(name.data()),
name.size(),
*m_cipher);
@@ -47,7 +47,7 @@ public:
secure_vector get(const std::string& name, const std::string_view &wrapped_key) const
{
const std::vector wrapped_name =
- nist_key_wrap_padded(reinterpret_cast(name.data()),
+ nist_key_wrap_padded(cast_char_ptr_to_uint8(name.data()),
name.size(),
*m_cipher);
diff --git a/pglablib/utils/PasswordManager.h b/pglablib/utils/PasswordManager.h
index 8fb99d1..4bba574 100644
--- a/pglablib/utils/PasswordManager.h
+++ b/pglablib/utils/PasswordManager.h
@@ -19,11 +19,7 @@ namespace Botan {
class PasswordManagerException: public std::exception {
public:
- PasswordManagerException() = default;
- explicit PasswordManagerException(const char *message) : m_message(message) {}
- const char *what() const noexcept override { return m_message.c_str(); }
-private:
- std::string m_message;
+ using std::exception::exception; //(char const* const _Message);
};
class PasswordManagerLockedException: public PasswordManagerException {
diff --git a/pgsql/ArrayParser.cpp b/pgsql/ArrayParser.cpp
index cdb5999..1f29a61 100644
--- a/pgsql/ArrayParser.cpp
+++ b/pgsql/ArrayParser.cpp
@@ -1,5 +1,4 @@
#include "ArrayParser.h"
-#include
#include
using namespace Pgsql;
diff --git a/pgsql/CMakeLists.txt b/pgsql/CMakeLists.txt
deleted file mode 100644
index f6b0f39..0000000
--- a/pgsql/CMakeLists.txt
+++ /dev/null
@@ -1,48 +0,0 @@
-find_package(PostgreSQL REQUIRED)
-
-add_library(pgsql STATIC
- Pgsql_Connection.cpp
- Pgsql_Params.cpp
- Pgsql_PgException.cpp
- Pgsql_Result.cpp
- Pgsql_Row.cpp
- Pgsql_Value.cpp
- ArrayParser.cpp
- Pgsql_oids.cpp
- Pgsql_Transaction.cpp
- Pgsql_ErrorDetails.cpp
- Pgsql_Canceller.cpp
- Pgsql_Connection.h
- Pgsql_IResult.h
- Pgsql_Params.h
- Pgsql_PgException.h
- Pgsql_Result.h
- Pgsql_ResultConstIterator.h
- Pgsql_Row.h
- Pgsql_Value.h
- Pgsql_declare.h
- Pgsql_Col.h
- ArrayParser.h
- Pgsql_oids.h
- SqlGenerator.h
- Pgsql_Transaction.h
- Pgsql_ErrorDetails.h
- Pgsql_Canceller.h
- )
-
-target_link_libraries(pgsql PUBLIC
- core
- PostgreSQL::PostgreSQL
- Qt6::Core
- Qt6::Widgets
- )
-
-target_include_directories(pgsql PUBLIC
- $
- )
-
-set_target_properties(pgsql PROPERTIES
- CXX_STANDARD 20
- CXX_STANDARD_REQUIRED ON
- POSITION_INDEPENDENT_CODE ON
- )
diff --git a/pgsql/pgsql.pro b/pgsql/pgsql.pro
new file mode 100644
index 0000000..02c21a5
--- /dev/null
+++ b/pgsql/pgsql.pro
@@ -0,0 +1,60 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2016-11-11T09:17:13
+#
+#-------------------------------------------------
+
+CONFIG += staticlib
+QT += core
+
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
+
+TARGET = pgsql
+TEMPLATE = lib
+
+! include( ../common.pri ) {
+error( "Couldn't find the common.pri file!" )
+}
+
+LIBS += -lws2_32 -llibpq
+
+SOURCES += Pgsql_Connection.cpp \
+ Pgsql_Params.cpp \
+ Pgsql_PgException.cpp \
+ Pgsql_Result.cpp \
+ Pgsql_Row.cpp \
+ Pgsql_Value.cpp \
+ ArrayParser.cpp \
+ Pgsql_oids.cpp \
+ Pgsql_Transaction.cpp \
+ Pgsql_ErrorDetails.cpp \
+ Pgsql_Canceller.cpp
+
+HEADERS += Pgsql_Connection.h \
+ Pgsql_IResult.h \
+ Pgsql_Params.h \
+ Pgsql_PgException.h \
+ Pgsql_Result.h \
+ Pgsql_ResultConstIterator.h \
+ Pgsql_Row.h \
+ Pgsql_Value.h \
+ Pgsql_declare.h \
+ Pgsql_Col.h \
+ ArrayParser.h \
+ Pgsql_oids.h \
+ SqlGenerator.h \
+ Pgsql_Transaction.h \
+ Pgsql_ErrorDetails.h \
+ Pgsql_Canceller.h
+
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../core/release/ -lcore
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../core/debug/ -lcore
+
+INCLUDEPATH += $$PWD/../core
+DEPENDPATH += $$PWD/../core
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/libcore.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/libcore.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/release/core.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../core/debug/core.lib
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
deleted file mode 100644
index a02ee3c..0000000
--- a/tests/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-find_package(GTest CONFIG REQUIRED)
-
-add_subdirectory(mygtestutils)
-add_subdirectory(PgsqlTests)
-add_subdirectory(pglabtests)
diff --git a/tests/PgsqlTests/CMakeLists.txt b/tests/PgsqlTests/CMakeLists.txt
deleted file mode 100644
index 34071a1..0000000
--- a/tests/PgsqlTests/CMakeLists.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-add_executable(PgsqlTests
- main.cpp
- tst_Value.cpp
- tst_ArrayParser.cpp
- tst_Pgsql_oids.cpp
- )
-
-target_link_libraries(PgsqlTests PRIVATE
- pgsql
- mygtestutils
- GTest::gtest
- Qt6::Core
- )
-
-target_include_directories(PgsqlTests PRIVATE
- ${CMAKE_CURRENT_SOURCE_DIR}
- )
-
-set_target_properties(PgsqlTests PROPERTIES
- CXX_STANDARD 20
- CXX_STANDARD_REQUIRED ON
- )
-
-add_test(NAME PgsqlTests COMMAND PgsqlTests)
diff --git a/tests/PgsqlTests/PgsqlTests.pro b/tests/PgsqlTests/PgsqlTests.pro
new file mode 100644
index 0000000..cb1d574
--- /dev/null
+++ b/tests/PgsqlTests/PgsqlTests.pro
@@ -0,0 +1,46 @@
+! include( ../../common.pri ) {
+error( "Couldn't find the common.pri file!" )
+}
+include(gtest_dependency.pri)
+
+TEMPLATE = app
+CONFIG += console
+CONFIG -= app_bundle
+CONFIG += thread
+CONFIG += qt
+
+QT += core
+
+HEADERS +=
+
+SOURCES += main.cpp \
+ tst_Value.cpp \
+ tst_ArrayParser.cpp \
+ tst_Pgsql_oids.cpp
+
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../pgsql/release/ -lpgsql
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../pgsql/debug/ -lpgsql
+else:unix: LIBS += -L$$OUT_PWD/../../pgsql/ -lpgsql
+
+INCLUDEPATH += $$PWD/../../pgsql
+DEPENDPATH += $$PWD/../../pgsql
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/release/libpgsql.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/debug/libpgsql.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/release/pgsql.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/debug/pgsql.lib
+else:unix: PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/libpgsql.a
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../mygtestutils/release/ -lmygtestutils
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../mygtestutils/debug/ -lmygtestutils
+else:unix:!macx: LIBS += -L$$OUT_PWD/../mygtestutils/ -lmygtestutils
+
+INCLUDEPATH += $$PWD/../mygtestutils
+DEPENDPATH += $$PWD/../mygtestutils
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/release/libmygtestutils.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/debug/libmygtestutils.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/release/mygtestutils.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/debug/mygtestutils.lib
+else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/libmygtestutils.a
diff --git a/tests/PgsqlTests/gtest_dependency.pri b/tests/PgsqlTests/gtest_dependency.pri
new file mode 100644
index 0000000..d01d7f0
--- /dev/null
+++ b/tests/PgsqlTests/gtest_dependency.pri
@@ -0,0 +1,29 @@
+isEmpty(GOOGLETEST_DIR):GOOGLETEST_DIR=$$(GOOGLETEST_DIR)
+
+isEmpty(GOOGLETEST_DIR) {
+ warning("Using googletest src dir specified at Qt Creator wizard")
+ message("set GOOGLETEST_DIR as environment variable or qmake variable to get rid of this message")
+ GOOGLETEST_DIR = C:/Prog/googletest
+}
+
+!isEmpty(GOOGLETEST_DIR): {
+ GTEST_SRCDIR = $$GOOGLETEST_DIR/googletest
+ GMOCK_SRCDIR = $$GOOGLETEST_DIR/googlemock
+}
+
+requires(exists($$GTEST_SRCDIR):exists($$GMOCK_SRCDIR))
+
+!exists($$GOOGLETEST_DIR):message("No googletest src dir found - set GOOGLETEST_DIR to enable.")
+
+DEFINES += \
+ GTEST_LANG_CXX11
+
+INCLUDEPATH *= \
+ $$GTEST_SRCDIR \
+ $$GTEST_SRCDIR/include \
+ $$GMOCK_SRCDIR \
+ $$GMOCK_SRCDIR/include
+
+SOURCES += \
+ $$GTEST_SRCDIR/src/gtest-all.cc \
+ $$GMOCK_SRCDIR/src/gmock-all.cc
diff --git a/tests/mygtestutils/CMakeLists.txt b/tests/mygtestutils/CMakeLists.txt
deleted file mode 100644
index 930a0ad..0000000
--- a/tests/mygtestutils/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-add_library(mygtestutils STATIC
- PrintTo_Qt.cpp
- PrintTo_Qt.h
- )
-
-target_link_libraries(mygtestutils PUBLIC
- GTest::gtest
- Qt6::Core
- )
-
-target_include_directories(mygtestutils PUBLIC
- ${CMAKE_CURRENT_SOURCE_DIR}
- )
-
-set_target_properties(mygtestutils PROPERTIES
- CXX_STANDARD 20
- CXX_STANDARD_REQUIRED ON
- POSITION_INDEPENDENT_CODE ON
- )
diff --git a/tests/mygtestutils/mygtestutils.pro b/tests/mygtestutils/mygtestutils.pro
new file mode 100644
index 0000000..a56a359
--- /dev/null
+++ b/tests/mygtestutils/mygtestutils.pro
@@ -0,0 +1,32 @@
+#-------------------------------------------------
+#
+# Project created by QtCreator 2017-12-01T10:07:31
+#
+#-------------------------------------------------
+
+QT -= gui
+
+TARGET = mygtestutils
+TEMPLATE = lib
+CONFIG += staticlib
+
+# The following define makes your compiler emit warnings if you use
+# any feature of Qt which has been marked as deprecated (the exact warnings
+# depend on your compiler). Please consult the documentation of the
+# deprecated API in order to know how to port your code away from it.
+DEFINES += QT_DEPRECATED_WARNINGS
+
+# You can also make your code fail to compile if you use deprecated APIs.
+# In order to do so, uncomment the following line.
+# You can also select to disable deprecated APIs only up to a certain version of Qt.
+#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
+
+SOURCES += \
+ PrintTo_Qt.cpp
+
+HEADERS += \
+ PrintTo_Qt.h
+unix {
+ target.path = /usr/lib
+ INSTALLS += target
+}
diff --git a/tests/pglabtests/CMakeLists.txt b/tests/pglabtests/CMakeLists.txt
deleted file mode 100644
index f13dc29..0000000
--- a/tests/pglabtests/CMakeLists.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-add_executable(pglabtests
- main.cpp
- TableTreeBuilderTests.cpp
- tst_ConvertLangToSqlString.cpp
- tst_ConvertToMultiLineCString.cpp
- tst_ExplainJsonParser.cpp
- tst_HumanReadableBytes.cpp
- tst_TryParsePostgresqlUrl.cpp
- tst_escapeConnectionStringValue.cpp
- tst_expected.cpp
- tst_SqlLexer.cpp
- tst_scopeguard.cpp
- tst_CsvWriter.cpp
- tst_PasswordManager.cpp
- tst_ParamJson.cpp
- tst_CodeBuilder.cpp
- tst_NameManglingRules.cpp
- tst_TypeMappings.cpp
- tst_Range.cpp
- )
-
-target_link_libraries(pglabtests PRIVATE
- pglablib
- pgsql
- core
- mygtestutils
- GTest::gtest
- Qt6::Core
- Qt6::Widgets
- )
-
-target_include_directories(pglabtests PRIVATE
- ${CMAKE_CURRENT_SOURCE_DIR}
- )
-
-set_target_properties(pglabtests PROPERTIES
- CXX_STANDARD 20
- CXX_STANDARD_REQUIRED ON
- )
-
-add_test(NAME pglabtests COMMAND pglabtests)
diff --git a/tests/pglabtests/pglabtests.pro b/tests/pglabtests/pglabtests.pro
new file mode 100644
index 0000000..a666430
--- /dev/null
+++ b/tests/pglabtests/pglabtests.pro
@@ -0,0 +1,86 @@
+! include( ../../common.pri ) {
+error( "Couldn't find the common.pri file!" )
+}
+include(gtest_dependency.pri)
+
+TEMPLATE = app
+CONFIG += console
+CONFIG -= app_bundle
+CONFIG += thread
+CONFIG += qt
+
+QT += core widgets
+
+HEADERS +=
+
+SOURCES += main.cpp \
+ TableTreeBuilderTests.cpp \
+ tst_ConvertLangToSqlString.cpp \
+ tst_ConvertToMultiLineCString.cpp \
+ tst_ExplainJsonParser.cpp \
+ tst_HumanReadableBytes.cpp \
+ tst_TryParsePostgresqlUrl.cpp \
+ tst_escapeConnectionStringValue.cpp \
+ tst_expected.cpp \
+ tst_SqlLexer.cpp \
+ tst_scopeguard.cpp \
+ tst_CsvWriter.cpp \
+ tst_PasswordManager.cpp \
+ tst_ParamJson.cpp \
+ tst_CodeBuilder.cpp \
+ tst_NameManglingRules.cpp \
+ tst_TypeMappings.cpp \
+ tst_Range.cpp
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../core/release/ -lcore
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../core/debug/ -lcore
+
+INCLUDEPATH += $$PWD/../../core
+DEPENDPATH += $$PWD/../../core
+
+win32:CONFIG(debug, debug|release): LIBS += -lbotand
+else:win32:CONFIG(release, debug|release): LIBS += -lbotan
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../core/release/libcore.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../core/debug/libcore.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../core/release/core.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../core/debug/core.lib
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../pgsql/release/ -lpgsql
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../pgsql/debug/ -lpgsql
+else:unix:!macx: LIBS += -L$$OUT_PWD/../../pgsql/ -lpgsql
+
+INCLUDEPATH += $$PWD/../../pgsql
+DEPENDPATH += $$PWD/../../pgsql
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/release/libpgsql.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/debug/libpgsql.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/release/pgsql.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/debug/pgsql.lib
+else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../../pgsql/libpgsql.a
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../../pglablib/release/ -lpglablib
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../../pglablib/debug/ -lpglablib
+else:unix:!macx: LIBS += -L$$OUT_PWD/../../pglablib/ -lpglablib
+
+INCLUDEPATH += $$PWD/../../pglablib
+DEPENDPATH += $$PWD/../../pglablib
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pglablib/release/libpglablib.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pglablib/debug/libpglablib.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pglablib/release/pglablib.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../../pglablib/debug/pglablib.lib
+else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../../pglablib/libpglablib.a
+
+win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../mygtestutils/release/ -lmygtestutils
+else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../mygtestutils/debug/ -lmygtestutils
+else:unix:!macx: LIBS += -L$$OUT_PWD/../mygtestutils/ -lmygtestutils
+
+INCLUDEPATH += $$PWD/../mygtestutils
+DEPENDPATH += $$PWD/../mygtestutils
+
+win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/release/libmygtestutils.a
+else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/debug/libmygtestutils.a
+else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/release/mygtestutils.lib
+else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/debug/mygtestutils.lib
+else:unix:!macx: PRE_TARGETDEPS += $$OUT_PWD/../mygtestutils/libmygtestutils.a
diff --git a/tests/tests.pro b/tests/tests.pro
new file mode 100644
index 0000000..ee23c08
--- /dev/null
+++ b/tests/tests.pro
@@ -0,0 +1,5 @@
+TEMPLATE = subdirs
+
+SUBDIRS += PgsqlTests \
+ pglabtests \
+ mygtestutils
diff --git a/vcpkg.json b/vcpkg.json
deleted file mode 100644
index 4283df6..0000000
--- a/vcpkg.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "pglab",
- "version-string": "0.1.0",
- "dependencies": [
- "boost-container",
- "boost-timer",
- "boost-chrono",
- "boost-assert",
- "botan",
- "libpq",
- "gtest"
- ]
-}