From 3db74ce483cb3ba39db275620d87cce0cb701160 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Mon, 10 Jan 2022 14:30:42 -0800 Subject: [PATCH 001/100] [AD-509] Update mac developer environment setup --- README.md | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index a52f6cf3d..642c44660 100644 --- a/README.md +++ b/README.md @@ -19,23 +19,31 @@ 3. [WiX Installer (3.11)](https://wixtoolset.org/releases/) 1. Ensure to add path to WiX executables (e.g. `C:\Program Files (x86)\WiX Toolset v3.11\bin`) 4. Java **JDK** (version 8+ - 17 recommended) - 1. Ensure to set JAVA_HOME -5. Run one of build scripts to create an initial compilation. + 1. Ensure to set JAVA_HOME. +5. Boost Test Framework + 1. Install via [VCPKG](https://vcpkg.io/en/getting-started.html) using `.\vcpkg install openssl:x64-windows boost-test:x64-windows boost-asio:x64-windows boost-chrono:x64-windows boost-interprocess:x64-windows boost-regex:x64-windows boost-system:x64-windows boost-thread:x64-windows` +6. Run one of the build scripts to create an initial compilation. 1. E.g.: `.\build_win_debug64.ps1` 2. Navigate to the `build\odbc\cmake` folder to use the generated solution file, `Ignite.C++.sln` to work on source code development and testing. -6. More details in `src\DEVNOTES.txt`. +7. More details in `src\DEVNOTES.txt`. ### MacOS -1. Install deppendencies - 1. brew install cmake - 2. brew install openssl - 3. brew install unixodbc -2. Run one of build scripts to create an initial compilation. - 1. E.g.: `./buid_mac_release64.sh` +1. Install dependencies + 1. `brew install cmake` + 2. `brew install openssl` + 3. `brew install unixodbc` + - You may need to unlink `libiodbc` if you already have this installed. Use `brew unlink libiodbc`. + 4. `brew install boost` + 5. Install Java **JDK** (version 8+ - 17 recommended) + - This can be done through Homebrew using `brew install --cask temurin`. + - Ensure to set `JAVA_HOME`. +2. Run one of the build scripts to create an initial compilation. + 1. E.g.: `./build_mac_release64.sh` 2. Navigate to the `build/odbc/lib` folder to use the generated files. 3. Use Microsoft VS Code to work on source code devlopment and testing. +4. More details in `src\DEVNOTES.txt`. ### Linux From 52b9b0272b62f20c50d399bf7d5188d89c0262e9 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Mon, 10 Jan 2022 14:31:48 -0800 Subject: [PATCH 002/100] Adjust formatting --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 642c44660..46b591555 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ 3. [WiX Installer (3.11)](https://wixtoolset.org/releases/) 1. Ensure to add path to WiX executables (e.g. `C:\Program Files (x86)\WiX Toolset v3.11\bin`) 4. Java **JDK** (version 8+ - 17 recommended) - 1. Ensure to set JAVA_HOME. + 1. Ensure to set `JAVA_HOME`. 5. Boost Test Framework 1. Install via [VCPKG](https://vcpkg.io/en/getting-started.html) using `.\vcpkg install openssl:x64-windows boost-test:x64-windows boost-asio:x64-windows boost-chrono:x64-windows boost-interprocess:x64-windows boost-regex:x64-windows boost-system:x64-windows boost-thread:x64-windows` 6. Run one of the build scripts to create an initial compilation. @@ -42,7 +42,7 @@ 2. Run one of the build scripts to create an initial compilation. 1. E.g.: `./build_mac_release64.sh` 2. Navigate to the `build/odbc/lib` folder to use the generated files. -3. Use Microsoft VS Code to work on source code devlopment and testing. +3. Use Microsoft VS Code to work on source code development and testing. 4. More details in `src\DEVNOTES.txt`. ### Linux From d3278a4343fcfb048545b465d85ea8869c7eca3c Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Wed, 12 Jan 2022 15:11:21 -0800 Subject: [PATCH 003/100] Add note about llvm --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 46b591555..2b80f53d9 100644 --- a/README.md +++ b/README.md @@ -38,12 +38,13 @@ 4. `brew install boost` 5. Install Java **JDK** (version 8+ - 17 recommended) - This can be done through Homebrew using `brew install --cask temurin`. - - Ensure to set `JAVA_HOME`. + - Ensure to set `JAVA_HOME`. + 6. If creating a debug build (`./build_mac_debug64.sh`), install LLVM. + - To ensure LLVM and CMake are compatible, use the LLVM included with XCode by modifying the PATH with `export PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/:$PATH`. 2. Run one of the build scripts to create an initial compilation. 1. E.g.: `./build_mac_release64.sh` 2. Navigate to the `build/odbc/lib` folder to use the generated files. -3. Use Microsoft VS Code to work on source code development and testing. -4. More details in `src\DEVNOTES.txt`. +3. More details in `src\DEVNOTES.txt`. ### Linux From 9802e1b6c21168ad5d53736ea041824e7dd41b09 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Fri, 14 Jan 2022 10:49:02 -0800 Subject: [PATCH 004/100] Add note about iodbc --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index 2b80f53d9..221589bb9 100644 --- a/README.md +++ b/README.md @@ -49,3 +49,15 @@ ### Linux TBD + +### Troubleshooting + +#### Issue: MacOS build fails with error about iODBC header +##### Example error message +``` +/Library/Frameworks/iODBC.framework/Headers/sqlext.h:82:10: fatal error: 'iODBC/sql.h' file not found +#include + ^~~~~~~~~~~~~ +``` +##### Fix +If you have installed the iODBC Driver Manager, the headers installed with it might be used instead of those from `unixodbc`. You may need to uninstall this driver manager and remove the `/Library/Frameworks/iODBC.framework/` directory. \ No newline at end of file From dfc1d5e5bcdc5fe5252974566421bc58692dc135 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Fri, 14 Jan 2022 15:33:38 -0800 Subject: [PATCH 005/100] Update README.md change the install options for OpenSSL, since vcpkg is a preferred option --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 221589bb9..743f8ab34 100644 --- a/README.md +++ b/README.md @@ -13,8 +13,8 @@ 6. Wix Toolset v4 Schemas for Visual Studio 7. WiX Toolset Visual Studio 2019 Extension 2. OpenSSL (full) - 1. Installed via [Chocolatey](https://community.chocolatey.org/packages/openssl). - 2. Or installed via [VCPKG](https://vcpkg.io/en/getting-started.html) (`.\vcpkg install openssl`). + 1. Installed via [VCPKG](https://vcpkg.io/en/getting-started.html) (`.\vcpkg install openssl`). + 2. Or installed via [Chocolatey](https://community.chocolatey.org/packages/openssl). 3. Ensure to set the OPENSSL_ROOT_DIR. 3. [WiX Installer (3.11)](https://wixtoolset.org/releases/) 1. Ensure to add path to WiX executables (e.g. `C:\Program Files (x86)\WiX Toolset v3.11\bin`) @@ -60,4 +60,4 @@ TBD ^~~~~~~~~~~~~ ``` ##### Fix -If you have installed the iODBC Driver Manager, the headers installed with it might be used instead of those from `unixodbc`. You may need to uninstall this driver manager and remove the `/Library/Frameworks/iODBC.framework/` directory. \ No newline at end of file +If you have installed the iODBC Driver Manager, the headers installed with it might be used instead of those from `unixodbc`. You may need to uninstall this driver manager and remove the `/Library/Frameworks/iODBC.framework/` directory. From 14f8011342476b53bb9fe9144fcc25c50ffb1622 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" <96995091+alinaliBQ@users.noreply.github.com> Date: Mon, 17 Jan 2022 10:06:46 -0800 Subject: [PATCH 006/100] Update README.md remove the WiX Toolset v4 requirement --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 743f8ab34..c0757ccd7 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,7 @@ 3. C++ ATL for latest v142 build tools (x86 & x64) 4. C++ MFC for latest v142 build tools (x86 & x64) 5. WiX Toolset v3 Schemas for Visual Studio - 6. Wix Toolset v4 Schemas for Visual Studio - 7. WiX Toolset Visual Studio 2019 Extension + 6. WiX Toolset Visual Studio 2019 Extension 2. OpenSSL (full) 1. Installed via [VCPKG](https://vcpkg.io/en/getting-started.html) (`.\vcpkg install openssl`). 2. Or installed via [Chocolatey](https://community.chocolatey.org/packages/openssl). From d6ccf0e66af0fe78c367493b2fe56f038bd5d801 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 17 Jan 2022 15:52:29 -0800 Subject: [PATCH 007/100] Update README.md add steps for the fix for ignite-odbc-tests.profraw error in README. --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c0757ccd7..cb1308e83 100644 --- a/README.md +++ b/README.md @@ -38,8 +38,9 @@ 5. Install Java **JDK** (version 8+ - 17 recommended) - This can be done through Homebrew using `brew install --cask temurin`. - Ensure to set `JAVA_HOME`. - 6. If creating a debug build (`./build_mac_debug64.sh`), install LLVM. - - To ensure LLVM and CMake are compatible, use the LLVM included with XCode by modifying the PATH with `export PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/:$PATH`. + 6. If creating a debug build (`./build_mac_debug64.sh`), LLVM is required. + - If you only have XCode Command Line Tools, use the LLVM included with XCode by modifying the PATH with `export PATH=/Library/Developer/CommandLineTools/usr/bin/:$PATH`. Ensure this XCode path comes first in $PATH. If error occurs, check that clang and llvm are under folder Library/Developer/CommandLineTools/usr/bin. + - If you have XCode application, to ensure LLVM and CMake are compatible, use the LLVM included with XCode by modifying the PATH with `export PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/:$PATH`. 2. Run one of the build scripts to create an initial compilation. 1. E.g.: `./build_mac_release64.sh` 2. Navigate to the `build/odbc/lib` folder to use the generated files. From eda56ebe585d6e89e862b741d1e4ae4d95d51055 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Tue, 18 Jan 2022 12:39:18 -0800 Subject: [PATCH 008/100] [AD-517] Remove old properties + add new properties --- .../ignite/odbc/config/configuration.h | 570 ++++++++++++------ .../odbc/config/connection_string_parser.h | 76 ++- .../system/ui/dsn_configuration_window.cpp | 98 +-- src/odbc/src/config/configuration.cpp | 408 ++++++++----- .../src/config/connection_string_parser.cpp | 269 +++++---- src/odbc/src/connection.cpp | 27 +- src/odbc/src/dsn_config.cpp | 137 +++-- src/odbc/src/message.cpp | 6 +- src/odbc/src/query/batch_query.cpp | 2 +- src/odbc/src/query/data_query.cpp | 6 +- 10 files changed, 986 insertions(+), 613 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index 69f41b317..c5a021c2d 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -53,58 +53,91 @@ namespace ignite static const std::string driver; /** Default value for schema attribute. */ - static const std::string schema; + static const std::string database; /** Default value for address attribute. */ static const std::string address; /** Default value for server attribute. */ - static const std::string server; + static const std::string hostname; + + /** Default value for port attribute. */ + static const uint16_t port; + + /** Default value for user attribute. */ + static const std::string user; + + /** Default value for password attribute. */ + static const std::string password; + + /** Default value for appName attribute. */ + static const std::string appName; + + /** Default value for loginTimeoutSec attribute. */ + static const int32_t loginTimeoutSec; + + /** Default value for readPreference attribute. */ + static const std::string readPreference; + + /** Default value for replicaSet attribute. */ + static const std::string replicaSet; + + /** Default value for retryReads attribute. */ + static const bool retryReads; /** Default value for sslMode attribute. */ static const ssl::SslMode::Type sslMode; - /** Default value for sslKeyFile attribute. */ - static const std::string sslKeyFile; + /** Default value for tls attribute. */ + static const bool tls; - /** Default value for sslCertFile attribute. */ - static const std::string sslCertFile; + /** Default value for tlsAllowInvalidHostnames attribute. */ + static const bool tlsAllowInvalidHostnames; - /** Default value for sslCaFile attribute. */ - static const std::string sslCaFile; + /** Default value for tlsCaFile attribute. */ + static const std::string tlsCaFile; - /** Default value for protocol version. */ - static const ProtocolVersion& protocolVersion; + /** Default value for sshUser attribute. */ + static const std::string sshUser; - /** Default value for port attribute. */ - static const uint16_t port; + /** Default value for sshHost attribute. */ + static const std::string sshHost; - /** Default value for fetch results page size attribute. */ - static const int32_t pageSize; + /** Default value for sshPrivateKeyFile attribute. */ + static const std::string sshPrivateKeyFile; - /** Default value for distributed joins attribute. */ - static const bool distributedJoins; + /** Default value for sshPrivateKeyPassphrase attribute. */ + static const std::string sshPrivateKeyPassphrase; - /** Default value for enforce join order attribute. */ - static const bool enforceJoinOrder; + /** Default value for sshStrictHostKeyChecking attribute. */ + static const bool sshStrictHostKeyChecking; - /** Default value for replicated only attribute. */ - static const bool replicatedOnly; + /** Default value for sshKnownHostsFile attribute. */ + static const std::string sshKnownHostsFile; - /** Default value for collocated attribute. */ - static const bool collocated; + /** Default value for scanMethod attribute. */ + static const std::string scanMethod; - /** Default value for lazy attribute. */ - static const bool lazy; + /** Default value for scanLimit attribute. */ + static const int32_t scanLimit; - /** Default value for skipReducerOnUpdate attribute. */ - static const bool skipReducerOnUpdate; + /** Default value for schemaName attribute. */ + static const std::string schemaName; - /** Default value for user attribute. */ - static const std::string user; + /** Default value for refreshSchema attribute. */ + static const bool refreshSchema; - /** Default value for password attribute. */ - static const std::string password; + /** Default value for sslKeyFile attribute. */ + static const std::string sslKeyFile; + + /** Default value for sslCertFile attribute. */ + static const std::string sslCertFile; + + /** Default value for protocol version. */ + // static const ProtocolVersion& protocolVersion; + + /** Default value for fetch results page size attribute. */ + static const int32_t defaultFetchSize; /** Default value for nestedTxMode attribute. */ static const NestedTxMode::Type nestedTxMode; @@ -127,27 +160,6 @@ namespace ignite */ std::string ToConnectString() const; - /** - * Get server port. - * - * @return Server port. - */ - uint16_t GetTcpPort() const; - - /** - * Set server port. - * - * @param port Server port. - */ - void SetTcpPort(uint16_t port); - - /** - * Check if the value set. - * - * @return @true if the value set. - */ - bool IsTcpPortSet() const; - /** * Get DSN. * @@ -188,378 +200,524 @@ namespace ignite * * @return Server host. */ - const std::string& GetHost() const; + const std::string& GetHostname() const; /** * Set server host. * * @param server Server host. */ - void SetHost(const std::string& server); + void SetHostname(const std::string& host); /** * Check if the value set. * * @return @true if the value set. */ - bool IsHostSet() const; + bool IsHostnameSet() const; + + /** + * Get server port. + * + * @return Server port. + */ + uint16_t GetTcpPort() const; + + /** + * Set server port. + * + * @param port Server port. + */ + void SetTcpPort(uint16_t port); + + /** + * Check if the value set. + * + * @return @true if the value set. + */ + bool IsTcpPortSet() const; /** * Get schema. * * @return Schema. */ - const std::string& GetSchema() const; + const std::string& GetDatabase() const; /** * Set schema. * * @param schema Schema name. */ - void SetSchema(const std::string& schema); + void SetDatabase(const std::string& schema); /** * Check if the value set. * * @return @true if the value set. */ - bool IsSchemaSet() const; + bool IsDatabaseSet() const; /** - * Get addresses. + * Get user. * - * @return Addresses. + * @return User. */ - const std::vector& GetAddresses() const; + const std::string& GetUser() const; /** - * Set addresses to connect to. + * Set user. * - * @param endPoints Addresses. + * @param user User. */ - void SetAddresses(const std::vector& endPoints); + void SetUser(const std::string& user); /** * Check if the value set. * * @return @true if the value set. */ - bool IsAddressesSet() const; + bool IsUserSet() const; /** - * Get SSL mode. + * Get password. * - * @return SSL mode. + * @return Password. */ - ssl::SslMode::Type GetSslMode() const; + const std::string& GetPassword() const; /** - * Set SSL mode. + * Set password. * - * @param sslMode SSL mode. + * @param pass Password. */ - void SetSslMode(ssl::SslMode::Type sslMode); + void SetPassword(const std::string& pass); /** * Check if the value set. * * @return @true if the value set. */ - bool IsSslModeSet() const; + bool IsPasswordSet() const; + + /** + * Get password. + * + * @return Password. + */ + const std::string& GetApplicationName() const; + + /** + * Set password. + * + * @param pass Password. + */ + void SetApplicationName(const std::string& name); + + /** + * Check if the value set. + * + * @return @true if the value set. + */ + bool IsApplicationNameSet() const; + + /** + * Get fetch results page size. + * + * @return Fetch results page size. + */ + int32_t GetLoginTimeoutSeconds() const; + + /** + * Set fetch results page size. + * + * @param size Fetch results page size. + */ + void SetLoginTimeoutSeconds(int32_t seconds); + + /** + * Check if the value set. + * + * @return @true if the value set. + */ + bool IsLoginTimeoutSecondsSet() const; + + /** + * Get password. + * + * @return Password. + */ + const std::string& GetReadPreference() const; /** - * Get SSL key file path. + * Set password. + * + * @param pass Password. + */ + void SetReadPreference(const std::string& preference); + + /** + * Check if the value set. + * + * @return @true if the value set. + */ + bool IsReadPreferenceSet() const; + /** + * Get password. * - * @return SSL key file path. + * @return Password. */ - const std::string& GetSslKeyFile() const; + const std::string& GetReplicaSet() const; /** - * Set SSL key file path. + * Set password. * - * @param sslKeyFile SSL key file path. + * @param pass Password. */ - void SetSslKeyFile(const std::string& sslKeyFile); + void SetReplicaSet(const std::string& name); /** * Check if the value set. * * @return @true if the value set. */ - bool IsSslKeyFileSet() const; + bool IsReplicaSetSet() const; /** - * Get SSL certificate file path. + * Get password. * - * @return SSL certificate file path. + * @return Password. */ - const std::string& GetSslCertFile() const; + bool IsRetryReads() const; /** - * Set SSL certificate file path. + * Set password. * - * @param sslCertFile SSL certificate file path. + * @param pass Password. */ - void SetSslCertFile(const std::string& sslCertFile); + void SetRetryReads(bool val); /** * Check if the value set. * * @return @true if the value set. */ - bool IsSslCertFileSet() const; + bool IsRetryReadsSet() const; /** - * Get SSL certificate authority file path. + * Get password. * - * @return SSL certificate authority file path. + * @return Password. */ - const std::string& GetSslCaFile() const; + bool IsTls() const; /** - * Set SSL certificate authority file path. + * Set password. * - * @param sslCaFile SSL certificate authority file path. + * @param pass Password. */ - void SetSslCaFile(const std::string& sslCaFile); + void SetTls(bool val); /** * Check if the value set. * * @return @true if the value set. */ - bool IsSslCaFileSet() const; + bool IsTlsSet() const; + + /** + * Get password. + * + * @return Password. + */ + bool IsTlsAllowInvalidHostnames() const; + + /** + * Set password. + * + * @param pass Password. + */ + void SetTlsAllowInvalidHostnames(bool val); /** - * Check distributed joins flag. + * Check if the value set. * - * @return True if distributed joins are enabled. + * @return @true if the value set. */ - bool IsDistributedJoins() const; + bool IsTlsAllowInvalidHostnamesSet() const; + + /** + * Get password. + * + * @return Password. + */ + const std::string& GetTlsCaFile() const; /** - * Set distributed joins. + * Set password. * - * @param val Value to set. + * @param pass Password. */ - void SetDistributedJoins(bool val); + void SetTlsCaFile(const std::string& path); /** * Check if the value set. * * @return @true if the value set. */ - bool IsDistributedJoinsSet() const; + bool IsTlsCaFileSet() const; /** - * Check enforce join order flag. + * Get password. * - * @return True if enforcing of join order is enabled. + * @return Password. */ - bool IsEnforceJoinOrder() const; + const std::string& GetSshUser() const; /** - * Set enforce joins. + * Set password. * - * @param val Value to set. + * @param pass Password. */ - void SetEnforceJoinOrder(bool val); + void SetSshUser(const std::string& user); /** * Check if the value set. * * @return @true if the value set. */ - bool IsEnforceJoinOrderSet() const; + bool IsSshUserSet() const; /** - * Check replicated only flag. + * Get password. * - * @return True if replicated only is enabled. + * @return Password. */ - bool IsReplicatedOnly() const; + const std::string& GetSshHost() const; /** - * Set replicated only flag. + * Set password. * - * @param val Value to set. + * @param pass Password. */ - void SetReplicatedOnly(bool val); + void SetSshHost(const std::string& host); /** * Check if the value set. * * @return @true if the value set. */ - bool IsReplicatedOnlySet() const; + bool IsSshHostSet() const; /** - * Check collocated flag. + * Get password. * - * @return True if collocated is enabled. + * @return Password. */ - bool IsCollocated() const; + const std::string& GetSshPrivateKeyFile () const; /** - * Set collocated. + * Set password. * - * @param val Value to set. + * @param pass Password. */ - void SetCollocated(bool val); + void SetSshPrivateKeyFile(const std::string& path); /** * Check if the value set. * * @return @true if the value set. */ - bool IsCollocatedSet() const; + bool IsSshPrivateKeyFileSet() const; /** - * Check lazy flag. + * Get password. * - * @return True if lazy is enabled. + * @return Password. */ - bool IsLazy() const; + const std::string& GetSshPrivateKeyPassphrase() const; /** - * Set lazy. + * Set password. * - * @param val Value to set. + * @param pass Password. */ - void SetLazy(bool val); + void SetSshPrivateKeyPassphrase(const std::string& passphrase); /** * Check if the value set. * * @return @true if the value set. */ - bool IsLazySet() const; + bool IsSshPrivateKeyPassphraseSet() const; /** - * Check update on server flag. + * Get password. * - * @return True if update on server. + * @return Password. */ - bool IsSkipReducerOnUpdate() const; + bool IsSshStrictHostKeyChecking() const; /** - * Set update on server. + * Set password. * - * @param val Value to set. + * @param pass Password. */ - void SetSkipReducerOnUpdate(bool val); + void SetSshStrictHostKeyChecking(bool val); /** * Check if the value set. * * @return @true if the value set. */ - bool IsSkipReducerOnUpdateSet() const; + bool IsSshStrictHostKeyCheckingSet() const; /** - * Get protocol version. + * Get password. * - * @return Protocol version. + * @return Password. */ - ProtocolVersion GetProtocolVersion() const; + const std::string& GetSshKnownHostsFile() const; /** - * Set protocol version. + * Set password. * - * @param version Version to set. + * @param pass Password. */ - void SetProtocolVersion(const ProtocolVersion& version); + void SetSshKnownHostsFile(const std::string& path); /** * Check if the value set. * * @return @true if the value set. */ - bool IsProtocolVersionSet() const; + bool IsSshKnownHostsFileSet() const; + + /** + * Get password. + * + * @return Password. + */ + const std::string& GetScanMethod() const; + + /** + * Set password. + * + * @param pass Password. + */ + void SetScanMethod(const std::string& method); + + /** + * Check if the value set. + * + * @return @true if the value set. + */ + bool IsScanMethodSet() const; /** * Get fetch results page size. * * @return Fetch results page size. */ - int32_t GetPageSize() const; + int32_t GetScanLimit() const; /** * Set fetch results page size. * * @param size Fetch results page size. */ - void SetPageSize(int32_t size); + void SetScanLimit(int32_t limit); /** * Check if the value set. * * @return @true if the value set. */ - bool IsPageSizeSet() const; + bool IsScanLimitSet() const; /** - * Get user. - * - * @return User. - */ - const std::string& GetUser() const; + * Get password. + * + * @return Password. + */ + const std::string& GetSchemaName() const; /** - * Set user. + * Set password. * - * @param user User. + * @param pass Password. */ - void SetUser(const std::string& user); + void SetSchemaName(const std::string& method); /** * Check if the value set. * * @return @true if the value set. */ - bool IsUserSet() const; + bool IsSchemaNameSet() const; /** * Get password. * * @return Password. */ - const std::string& GetPassword() const; + bool IsSchemaRefresh() const; /** * Set password. * * @param pass Password. */ - void SetPassword(const std::string& pass); + void SetSchemaRefresh(bool val); /** * Check if the value set. * * @return @true if the value set. */ - bool IsPasswordSet() const; + bool IsSchemaRefreshSet() const; /** - * Get nested transaction mode. + * Get addresses. * - * @return Nested transaction mode. + * @return Addresses. */ - NestedTxMode::Type GetNestedTxMode() const; + const std::vector& GetAddresses() const; /** - * Set nested transaction mode. + * Set addresses to connect to. * - * @param mode Nested transaction mode. + * @param endPoints Addresses. */ - void SetNestedTxMode(NestedTxMode::Type mode); + void SetAddresses(const std::vector& endPoints); /** * Check if the value set. * * @return @true if the value set. */ - bool IsNestedTxModeSet() const; + bool IsAddressesSet() const; + + /** + * Get fetch results page size. + * + * @return Fetch results page size. + */ + int32_t GetDefaultFetchSize() const; + + /** + * Set fetch results page size. + * + * @param size Fetch results page size. + */ + void SetDefaultFetchSize(int32_t size); + + /** + * Check if the value set. + * + * @return @true if the value set. + */ + bool IsDefaultFetchSizeSet() const; /** * Get argument map. @@ -586,61 +744,79 @@ namespace ignite SettableValue driver; /** Schema. */ - SettableValue schema; + SettableValue database; /** Server. Deprecated. */ - SettableValue server; + SettableValue hostname; /** TCP port. Deprecated. */ SettableValue port; - /** Request and response page size. */ - SettableValue pageSize; - - /** Distributed joins flag. */ - SettableValue distributedJoins; + /** User. */ + SettableValue user; - /** Enforce join order flag. */ - SettableValue enforceJoinOrder; + /** Password. */ + SettableValue password; - /** Replicated only flag. */ - SettableValue replicatedOnly; + /** Application name. */ + SettableValue appName; - /** Collocated flag. */ - SettableValue collocated; + /** Login timeout in seconds. */ + SettableValue loginTimeoutSec; - /** Lazy flag. */ - SettableValue lazy; + /** Read pereference. */ + SettableValue readPreference; - /** Skip reducer on update flag. */ - SettableValue skipReducerOnUpdate; + /** Replica set name. */ + SettableValue replicaSet; - /** Protocol version. */ - SettableValue protocolVersion; + /** Retry reads flag. */ + SettableValue retryReads; /** Connection end-points. */ - SettableValue< std::vector > endPoints; + SettableValue< std::vector > endPoints; // Remove in favor of deprecated one - /** SSL Mode. */ - SettableValue sslMode; + /** Enable SSL/TLS. */ + SettableValue tls; - /** SSL private key file path. */ - SettableValue sslKeyFile; + /** Flag for if invalid hostnames for the TLS certificate are allowed. */ + SettableValue tlsAllowInvalidHostnames; - /** SSL certificate file path. */ - SettableValue sslCertFile; + /** SSL/TLS certificate authority file path. */ + SettableValue tlsCaFile; - /** SSL certificate authority file path. */ - SettableValue sslCaFile; + /** The SSH host username for the internal SSH tunnel. */ + SettableValue sshUser; - /** User. */ - SettableValue user; + /** The SSH host host name for the internal SSH tunnel. */ + SettableValue sshHost; - /** Password. */ - SettableValue password; + /** The SSH host private key file path for the internal SSH tunnel. */ + SettableValue sshPrivateKeyFile; - /** Nested transaction mode. */ - SettableValue nestedTxMode; + /** The SSH host private key file passphrase for the internal SSH tunnel. */ + SettableValue sshPrivateKeyPassphrase; + + /** Strict host key checking flag for the internal SSH tunnel. */ + SettableValue sshStrictHostKeyChecking; + + /** The known hosts file path for the internal SSH tunnel. */ + SettableValue sshKnownHostsFile; + + /** Scan method. */ + SettableValue scanMethod; + + /** Scan limit. */ + SettableValue scanLimit; + + /** Schema name. */ + SettableValue schemaName; + + /** Refresh schema flag. */ + SettableValue refreshSchema; + + /** Request and response page size. */ + SettableValue defaultFetchSize; }; template<> diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index de02cb45d..27e4f48d2 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -45,7 +45,7 @@ namespace ignite static const std::string driver; /** Connection attribute keyword for schema attribute. */ - static const std::string schema; + static const std::string database; /** Connection attribute keyword for address attribute. */ static const std::string address; @@ -56,29 +56,71 @@ namespace ignite /** Connection attribute keyword for port attribute. */ static const std::string port; - /** Connection attribute keyword for distributed joins attribute. */ - static const std::string distributedJoins; + /** Connection attribute keyword for username attribute. */ + static const std::string user; - /** Connection attribute keyword for enforce join order attribute. */ - static const std::string enforceJoinOrder; + /** Connection attribute keyword for password attribute. */ + static const std::string password; - /** Connection attribute keyword for protocol version attribute. */ - static const std::string protocolVersion; + /** Connection attribute keyword for username attribute. */ + static const std::string appName; - /** Connection attribute keyword for fetch results page size attribute. */ - static const std::string pageSize; + /** Connection attribute keyword for password attribute. */ + static const std::string loginTimeoutSec; + + /** Connection attribute keyword for username attribute. */ + static const std::string readPreference; + + /** Connection attribute keyword for password attribute. */ + static const std::string replicaSet; + + /** Connection attribute keyword for username attribute. */ + static const std::string retryReads; + + /** Connection attribute keyword for password attribute. */ + static const std::string tls; + + /** Connection attribute keyword for password attribute. */ + static const std::string tlsAllowInvalidHostnames; + + /** Connection attribute keyword for password attribute. */ + static const std::string tlsCaFile; - /** Connection attribute keyword for replicated only attribute. */ - static const std::string replicatedOnly; + /** Connection attribute keyword for password attribute. */ + static const std::string sshUser; + + /** Connection attribute keyword for password attribute. */ + static const std::string sshHost; - /** Connection attribute keyword for collocated attribute. */ - static const std::string collocated; + /** Connection attribute keyword for password attribute. */ + static const std::string sshPrivateKeyFile; + + /** Connection attribute keyword for password attribute. */ + static const std::string sshPrivateKeyPassphrase; - /** Connection attribute keyword for lazy attribute. */ - static const std::string lazy; + /** Connection attribute keyword for password attribute. */ + static const std::string sshStrictHostKeyChecking; + + /** Connection attribute keyword for password attribute. */ + static const std::string sshKnownHostsFile; + + /** Connection attribute keyword for password attribute. */ + static const std::string scanMethod; - /** Connection attribute keyword for skipReducerOnUpdate attribute. */ - static const std::string skipReducerOnUpdate; + /** Connection attribute keyword for password attribute. */ + static const std::string scanLimit; + + /** Connection attribute keyword for password attribute. */ + static const std::string schemaName; + + /** Connection attribute keyword for password attribute. */ + static const std::string refreshSchema; + + /** Connection attribute keyword for protocol version attribute. */ + static const std::string protocolVersion; + + /** Connection attribute keyword for fetch results page size attribute. */ + static const std::string defaultFetchSize; /** Connection attribute keyword for sslMode attribute. */ static const std::string sslMode; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 38496d993..c8832697c 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -34,7 +34,7 @@ namespace ignite namespace ui { DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config): - CustomWindow(parent, "IgniteConfigureDsn", "Configure Apache Ignite DSN"), + CustomWindow(parent, "IgniteConfigureDsn", "Configure Amazon DocumentDB DSN Latest"), width(360), height(600), connectionSettingsGroupBox(), @@ -144,7 +144,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - val = config.GetSchema().c_str(); + val = config.GetDatabase().c_str(); schemaLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "Schema name:", ChildId::SCHEMA_LABEL); schemaEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SCHEMA_EDIT); @@ -160,7 +160,7 @@ namespace ignite const ProtocolVersion::VersionSet& supported = ProtocolVersion::GetSupported(); - ProtocolVersion version = config.GetProtocolVersion(); + ProtocolVersion version = ProtocolVersion::GetCurrent(); if (!version.IsSupported()) version = ProtocolVersion::GetCurrent(); @@ -228,7 +228,7 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; - SslMode::Type sslMode = config.GetSslMode(); + SslMode::Type sslMode = ssl::SslMode::REQUIRE; std::string sslModeStr = SslMode::ToString(sslMode); const char* val = sslModeStr.c_str(); @@ -245,7 +245,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - val = config.GetSslKeyFile().c_str(); + val = config.GetTlsCaFile().c_str(); sslKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSL Private Key:", ChildId::SSL_KEY_FILE_LABEL); sslKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, @@ -255,7 +255,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - val = config.GetSslCertFile().c_str(); + val = config.GetTlsCaFile().c_str(); sslCertFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSL Certificate:", ChildId::SSL_CERT_FILE_LABEL); sslCertFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, @@ -265,7 +265,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - val = config.GetSslCaFile().c_str(); + val = config.GetTlsCaFile().c_str(); sslCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSL Certificate Authority:", ChildId::SSL_CA_FILE_LABEL); sslCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, @@ -296,14 +296,14 @@ namespace ignite int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; - ProtocolVersion version = config.GetProtocolVersion(); + ProtocolVersion version = ProtocolVersion::GetCurrent(); if (!version.IsSupported()) version = ProtocolVersion::GetCurrent(); int rowPos = posY + 2 * INTERVAL; - std::string tmp = common::LexicalCast(config.GetPageSize()); + std::string tmp = common::LexicalCast(1000); const char* val = tmp.c_str(); pageSizeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "Page size:", ChildId::PAGE_SIZE_LABEL); @@ -326,8 +326,8 @@ namespace ignite { nestedTxModeComboBox->AddString(NestedTxMode::ToString(*it)); - if (*it == config.GetNestedTxMode()) - nestedTxModeComboBox->SetSelection(id); + /* if (*it == config.GetNestedTxMode()) + nestedTxModeComboBox->SetSelection(id); */ ++id; } @@ -337,30 +337,30 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; distributedJoinsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Distributed Joins", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, config.IsDistributedJoins()); + "Distributed Joins", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, false); enforceJoinOrderCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize, ROW_HEIGHT, "Enforce Join Order", - ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX, config.IsEnforceJoinOrder()); + ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX, false); rowPos += ROW_HEIGHT; replicatedOnlyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Replicated Only", ChildId::REPLICATED_ONLY_CHECK_BOX, config.IsReplicatedOnly()); - + "Replicated Only", ChildId::REPLICATED_ONLY_CHECK_BOX, false); + collocatedCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize, - ROW_HEIGHT, "Collocated", ChildId::COLLOCATED_CHECK_BOX, config.IsCollocated()); + ROW_HEIGHT, "Collocated", ChildId::COLLOCATED_CHECK_BOX, false); rowPos += ROW_HEIGHT; lazyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Lazy", ChildId::LAZY_CHECK_BOX, config.IsLazy()); + "Lazy", ChildId::LAZY_CHECK_BOX, false); lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5); skipReducerOnUpdateCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize, ROW_HEIGHT, "Skip reducer on update", ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX, - config.IsSkipReducerOnUpdate()); + false); skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0); @@ -550,8 +550,8 @@ namespace ignite cfg.SetDsn(dsnStr); cfg.SetAddresses(addresses); - cfg.SetSchema(schemaStr); - cfg.SetProtocolVersion(version); + cfg.SetDatabase(schemaStr); + //cfg.SetProtocolVersion(version); } void DsnConfigurationWindow::RetrieveAuthParameters(config::Configuration& cfg) const @@ -586,10 +586,10 @@ namespace ignite ssl::SslMode::Type sslMode = ssl::SslMode::FromString(sslModeStr, ssl::SslMode::DISABLE); - cfg.SetSslMode(sslMode); - cfg.SetSslKeyFile(sslKeyStr); - cfg.SetSslCertFile(sslCertStr); - cfg.SetSslCaFile(sslCaStr); + //cfg.SetSslMode(sslMode); + //cfg.SetSslKeyFile(sslKeyStr); + //cfg.SetSslCertFile(sslCertStr); + cfg.SetTlsCaFile(sslCaStr); } void DsnConfigurationWindow::RetrieveAdditionalParameters(config::Configuration& cfg) const @@ -601,39 +601,39 @@ namespace ignite int32_t pageSize = common::LexicalCast(pageSizeStr); if (pageSize <= 0) - pageSize = config.GetPageSize(); - + pageSize = config.GetDefaultFetchSize(); + std::string nestedTxModeStr; nestedTxModeComboBox->GetText(nestedTxModeStr); - NestedTxMode::Type mode = NestedTxMode::FromString(nestedTxModeStr, config.GetNestedTxMode()); + //NestedTxMode::Type mode = NestedTxMode::FromString(nestedTxModeStr, config.GetNestedTxMode()); - bool distributedJoins = distributedJoinsCheckBox->IsChecked(); - bool enforceJoinOrder = enforceJoinOrderCheckBox->IsChecked(); - bool replicatedOnly = replicatedOnlyCheckBox->IsChecked(); - bool collocated = collocatedCheckBox->IsChecked(); - bool lazy = lazyCheckBox->IsChecked(); - bool skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked(); + //bool distributedJoins = distributedJoinsCheckBox->IsChecked(); + //bool enforceJoinOrder = enforceJoinOrderCheckBox->IsChecked(); + //bool replicatedOnly = replicatedOnlyCheckBox->IsChecked(); + //bool collocated = collocatedCheckBox->IsChecked(); + //bool lazy = lazyCheckBox->IsChecked(); + //bool skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked(); LOG_MSG("Retrieving arguments:"); LOG_MSG("Page size: " << pageSize); - LOG_MSG("Nested TX Mode: " << NestedTxMode::ToString(mode)); - LOG_MSG("Distributed Joins: " << (distributedJoins ? "true" : "false")); - LOG_MSG("Enforce Join Order: " << (enforceJoinOrder ? "true" : "false")); - LOG_MSG("Replicated only: " << (replicatedOnly ? "true" : "false")); - LOG_MSG("Collocated: " << (collocated ? "true" : "false")); - LOG_MSG("Lazy: " << (lazy ? "true" : "false")); - LOG_MSG("Skip reducer on update: " << (skipReducerOnUpdate ? "true" : "false")); - - cfg.SetPageSize(pageSize); - cfg.SetNestedTxMode(mode); - cfg.SetDistributedJoins(distributedJoins); - cfg.SetEnforceJoinOrder(enforceJoinOrder); - cfg.SetReplicatedOnly(replicatedOnly); - cfg.SetCollocated(collocated); - cfg.SetLazy(lazy); - cfg.SetSkipReducerOnUpdate(skipReducerOnUpdate); + //LOG_MSG("Nested TX Mode: " << NestedTxMode::ToString(mode)); + //LOG_MSG("Distributed Joins: " << (distributedJoins ? "true" : "false")); + //LOG_MSG("Enforce Join Order: " << (enforceJoinOrder ? "true" : "false")); + //LOG_MSG("Replicated only: " << (replicatedOnly ? "true" : "false")); + //LOG_MSG("Collocated: " << (collocated ? "true" : "false")); + //LOG_MSG("Lazy: " << (lazy ? "true" : "false")); + //LOG_MSG("Skip reducer on update: " << (skipReducerOnUpdate ? "true" : "false")); + + cfg.SetDefaultFetchSize(pageSize); + //cfg.SetNestedTxMode(mode); + //cfg.SetDistributedJoins(distributedJoins); + //cfg.SetEnforceJoinOrder(enforceJoinOrder); + //cfg.SetReplicatedOnly(replicatedOnly); + //cfg.SetCollocated(collocated); + //cfg.SetLazy(lazy); + //cfg.SetSkipReducerOnUpdate(skipReducerOnUpdate); } } } diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index a99894dfc..198ecb9d0 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -30,56 +30,73 @@ namespace ignite { namespace config { + const std::string Configuration::DefaultValue::dsn = "Apache Ignite DSN"; const std::string Configuration::DefaultValue::driver = "Apache Ignite"; - const std::string Configuration::DefaultValue::schema = "PUBLIC"; - const std::string Configuration::DefaultValue::address = ""; - const std::string Configuration::DefaultValue::server = ""; - - const uint16_t Configuration::DefaultValue::port = 10800; - const int32_t Configuration::DefaultValue::pageSize = 1024; - - const bool Configuration::DefaultValue::distributedJoins = false; - const bool Configuration::DefaultValue::enforceJoinOrder = false; - const bool Configuration::DefaultValue::replicatedOnly = false; - const bool Configuration::DefaultValue::collocated = false; - const bool Configuration::DefaultValue::lazy = false; - const bool Configuration::DefaultValue::skipReducerOnUpdate = false; - - const ProtocolVersion& Configuration::DefaultValue::protocolVersion = ProtocolVersion::GetCurrent(); - - const ssl::SslMode::Type Configuration::DefaultValue::sslMode = ssl::SslMode::DISABLE; - const std::string Configuration::DefaultValue::sslKeyFile = ""; - const std::string Configuration::DefaultValue::sslCertFile = ""; - const std::string Configuration::DefaultValue::sslCaFile = ""; - + const std::string Configuration::DefaultValue::database = ""; + const std::string Configuration::DefaultValue::address = ""; // remove + const std::string Configuration::DefaultValue::hostname = ""; + const uint16_t Configuration::DefaultValue::port = 27017; const std::string Configuration::DefaultValue::user = ""; const std::string Configuration::DefaultValue::password = ""; - - const NestedTxMode::Type Configuration::DefaultValue::nestedTxMode = NestedTxMode::AI_ERROR; + + // SSL/TLS options + const bool Configuration::DefaultValue::tls = true; + const bool Configuration::DefaultValue::tlsAllowInvalidHostnames = false; + const std::string Configuration::DefaultValue::tlsCaFile = ""; + + // Schema Generation and Discovery options + const std::string Configuration::DefaultValue::scanMethod = "random"; + const int32_t Configuration::DefaultValue::scanLimit = 1000; + const std::string Configuration::DefaultValue::schemaName = "_default"; + const bool Configuration::DefaultValue::refreshSchema = false; + + // Internal SSH Tunnel options + const std::string Configuration::DefaultValue::sshUser = ""; + const std::string Configuration::DefaultValue::sshHost = ""; + const std::string Configuration::DefaultValue::sshPrivateKeyFile = ""; + const std::string Configuration::DefaultValue::sshPrivateKeyPassphrase = ""; + const bool Configuration::DefaultValue::sshStrictHostKeyChecking = true; + const std::string Configuration::DefaultValue::sshKnownHostsFile = ""; + + // Additional options + const std::string Configuration::DefaultValue::appName = "Amazon DocumentDB ODBC Driver"; + const int32_t Configuration::DefaultValue::loginTimeoutSec = 0; + const std::string Configuration::DefaultValue::readPreference = ""; + const std::string Configuration::DefaultValue::replicaSet = ""; + const bool Configuration::DefaultValue::retryReads = true; + const int32_t Configuration::DefaultValue::defaultFetchSize = 2000; + + const NestedTxMode::Type Configuration::DefaultValue::nestedTxMode = NestedTxMode::AI_ERROR; // remove Configuration::Configuration() : dsn(DefaultValue::dsn), driver(DefaultValue::driver), - schema(DefaultValue::schema), - server(DefaultValue::server), + database(DefaultValue::database), + hostname(DefaultValue::hostname), port(DefaultValue::port), - pageSize(DefaultValue::pageSize), - distributedJoins(DefaultValue::distributedJoins), - enforceJoinOrder(DefaultValue::enforceJoinOrder), - replicatedOnly(DefaultValue::replicatedOnly), - collocated(DefaultValue::collocated), - lazy(DefaultValue::lazy), - skipReducerOnUpdate(DefaultValue::skipReducerOnUpdate), - protocolVersion(DefaultValue::protocolVersion), - endPoints(std::vector()), - sslMode(DefaultValue::sslMode), - sslKeyFile(DefaultValue::sslKeyFile), - sslCertFile(DefaultValue::sslCertFile), - sslCaFile(DefaultValue::sslCaFile), user(DefaultValue::user), password(DefaultValue::password), - nestedTxMode(DefaultValue::nestedTxMode) + endPoints(std::vector()), + appName(DefaultValue::appName), + loginTimeoutSec(DefaultValue::loginTimeoutSec), + readPreference(DefaultValue::readPreference), + replicaSet(DefaultValue::replicaSet), + retryReads(DefaultValue::retryReads), + tls(DefaultValue::tls), + tlsAllowInvalidHostnames(DefaultValue::tlsAllowInvalidHostnames), + tlsCaFile(DefaultValue::tlsCaFile), + sshUser(DefaultValue::sshUser), + sshHost(DefaultValue::sshHost), + sshPrivateKeyFile(DefaultValue::sshPrivateKeyFile), + sshPrivateKeyPassphrase(DefaultValue::sshPrivateKeyPassphrase), + sshStrictHostKeyChecking(DefaultValue::sshStrictHostKeyChecking), + sshKnownHostsFile(DefaultValue::sshKnownHostsFile), + scanMethod(DefaultValue::scanMethod), + scanLimit(DefaultValue::scanLimit), + schemaName(DefaultValue::schemaName), + refreshSchema(DefaultValue::refreshSchema), + defaultFetchSize(DefaultValue::defaultFetchSize) { // No-op. } @@ -157,34 +174,34 @@ namespace ignite this->driver.SetValue(driver); } - const std::string& Configuration::GetHost() const + const std::string& Configuration::GetHostname() const { - return server.GetValue(); + return hostname.GetValue(); } - void Configuration::SetHost(const std::string& server) + void Configuration::SetHostname(const std::string& host) { - this->server.SetValue(server); + this->hostname.SetValue(host); } - bool Configuration::IsHostSet() const + bool Configuration::IsHostnameSet() const { - return server.IsSet(); + return hostname.IsSet(); } - const std::string& Configuration::GetSchema() const + const std::string& Configuration::GetDatabase() const { - return schema.GetValue(); + return database.GetValue(); } - void Configuration::SetSchema(const std::string& schema) + void Configuration::SetDatabase(const std::string& schema) { - this->schema.SetValue(schema); + this->database.SetValue(schema); } - bool Configuration::IsSchemaSet() const + bool Configuration::IsDatabaseSet() const { - return schema.IsSet(); + return database.IsSet(); } const std::vector& Configuration::GetAddresses() const @@ -202,179 +219,274 @@ namespace ignite return endPoints.IsSet(); } - ssl::SslMode::Type Configuration::GetSslMode() const + const std::string& Configuration::GetApplicationName() const + { + return appName.GetValue(); + } + + void Configuration::SetApplicationName(const std::string& name) + { + this->appName.SetValue(name); + } + + bool Configuration::IsApplicationNameSet() const + { + return appName.IsSet(); + } + + int32_t Configuration::GetLoginTimeoutSeconds() const { - return sslMode.GetValue(); + return loginTimeoutSec.GetValue(); } - void Configuration::SetSslMode(ssl::SslMode::Type sslMode) + void Configuration::SetLoginTimeoutSeconds(int32_t seconds) { - this->sslMode.SetValue(sslMode); + this->loginTimeoutSec.SetValue(seconds); } - bool Configuration::IsSslModeSet() const + bool Configuration::IsLoginTimeoutSecondsSet() const { - return sslMode.IsSet(); + return loginTimeoutSec.IsSet(); } - const std::string& Configuration::GetSslKeyFile() const + const std::string& Configuration::GetReadPreference() const { - return sslKeyFile.GetValue(); + return readPreference.GetValue(); } - void Configuration::SetSslKeyFile(const std::string& sslKeyFile) + void Configuration::SetReadPreference(const std::string& preference) { - this->sslKeyFile.SetValue(sslKeyFile); + this->readPreference.SetValue(preference); } - bool Configuration::IsSslKeyFileSet() const + bool Configuration::IsReadPreferenceSet() const { - return sslKeyFile.IsSet(); + return readPreference.IsSet(); } - const std::string& Configuration::GetSslCertFile() const + const std::string& Configuration::GetReplicaSet() const { - return sslCertFile.GetValue(); + return replicaSet.GetValue(); } - void Configuration::SetSslCertFile(const std::string& sslCertFile) + void Configuration::SetReplicaSet(const std::string& name) { - this->sslCertFile.SetValue(sslCertFile); + this->replicaSet.SetValue(name); } - bool Configuration::IsSslCertFileSet() const + bool Configuration::IsReplicaSetSet() const { - return sslCertFile.IsSet(); + return replicaSet.IsSet(); } - const std::string& Configuration::GetSslCaFile() const + bool Configuration::IsRetryReads() const { - return sslCaFile.GetValue(); + return retryReads.GetValue(); } - void Configuration::SetSslCaFile(const std::string& sslCaFile) + void Configuration::SetRetryReads(bool val) { - this->sslCaFile.SetValue(sslCaFile); + this->retryReads.SetValue(val); } - bool Configuration::IsSslCaFileSet() const + bool Configuration::IsRetryReadsSet() const { - return sslCaFile.IsSet(); + return retryReads.IsSet(); } - bool Configuration::IsDistributedJoins() const + bool Configuration::IsTls() const { - return distributedJoins.GetValue(); + return tls.GetValue(); } - void Configuration::SetDistributedJoins(bool val) + void Configuration::SetTls(bool val) { - this->distributedJoins.SetValue(val); + this->tls.SetValue(val); } - bool Configuration::IsDistributedJoinsSet() const + bool Configuration::IsTlsSet() const { - return distributedJoins.IsSet(); + return tls.IsSet(); } - bool Configuration::IsEnforceJoinOrder() const + bool Configuration::IsTlsAllowInvalidHostnames() const { - return enforceJoinOrder.GetValue(); + return tlsAllowInvalidHostnames.GetValue(); } - void Configuration::SetEnforceJoinOrder(bool val) + void Configuration::SetTlsAllowInvalidHostnames(bool val) { - this->enforceJoinOrder.SetValue(val); + this->tlsAllowInvalidHostnames.SetValue(val); } - bool Configuration::IsEnforceJoinOrderSet() const + bool Configuration::IsTlsAllowInvalidHostnamesSet() const { - return enforceJoinOrder.IsSet(); + return tlsAllowInvalidHostnames.IsSet(); } - bool Configuration::IsReplicatedOnly() const + const std::string& Configuration::GetTlsCaFile() const { - return replicatedOnly.GetValue(); + return tlsCaFile.GetValue(); } - void Configuration::SetReplicatedOnly(bool val) + void Configuration::SetTlsCaFile(const std::string& path) { - this->replicatedOnly.SetValue(val); + this->tlsCaFile.SetValue(path); } - bool Configuration::IsReplicatedOnlySet() const + bool Configuration::IsTlsCaFileSet() const { - return replicatedOnly.IsSet(); + return tlsCaFile.IsSet(); } - bool Configuration::IsCollocated() const + const std::string& Configuration::GetSshUser() const { - return collocated.GetValue(); + return sshUser.GetValue(); } - void Configuration::SetCollocated(bool val) + void Configuration::SetSshUser(const std::string& username) { - this->collocated.SetValue(val); + this->sshUser.SetValue(username); } - bool Configuration::IsCollocatedSet() const + bool Configuration::IsSshUserSet() const { - return collocated.IsSet(); + return sshUser.IsSet(); } - bool Configuration::IsLazy() const + const std::string& Configuration::GetSshHost() const { - return lazy.GetValue(); + return sshHost.GetValue(); } - void Configuration::SetLazy(bool val) + void Configuration::SetSshHost(const std::string& hostname) { - this->lazy.SetValue(val); + this->sshHost.SetValue(hostname); } - bool Configuration::IsLazySet() const + bool Configuration::IsSshHostSet() const { - return lazy.IsSet(); + return sshHost.IsSet(); } - bool Configuration::IsSkipReducerOnUpdate() const + const std::string& Configuration::GetSshPrivateKeyFile() const { - return skipReducerOnUpdate.GetValue(); + return sshPrivateKeyFile.GetValue(); } - void Configuration::SetSkipReducerOnUpdate(bool val) + void Configuration::SetSshPrivateKeyFile(const std::string& path) { - this->skipReducerOnUpdate.SetValue(val); + this->sshPrivateKeyFile.SetValue(path); } - bool Configuration::IsSkipReducerOnUpdateSet() const + bool Configuration::IsSshPrivateKeyFileSet() const { - return skipReducerOnUpdate.IsSet(); + return sshPrivateKeyFile.IsSet(); } - ProtocolVersion Configuration::GetProtocolVersion() const + const std::string& Configuration::GetSshPrivateKeyPassphrase() const { - return protocolVersion.GetValue(); + return sshPrivateKeyPassphrase.GetValue(); } - void Configuration::SetProtocolVersion(const ProtocolVersion& version) + void Configuration::SetSshPrivateKeyPassphrase(const std::string& passphrase) { - this->protocolVersion.SetValue(version); + this->sshPrivateKeyPassphrase.SetValue(passphrase); } - bool Configuration::IsProtocolVersionSet() const + bool Configuration::IsSshPrivateKeyPassphraseSet() const { - return protocolVersion.IsSet(); + return sshPrivateKeyPassphrase.IsSet(); } - void Configuration::SetPageSize(int32_t size) + bool Configuration::IsSshStrictHostKeyChecking() const { - this->pageSize.SetValue(size); + return sshStrictHostKeyChecking.GetValue(); } - bool Configuration::IsPageSizeSet() const + void Configuration::SetSshStrictHostKeyChecking(bool val) { - return pageSize.IsSet(); + this->sshStrictHostKeyChecking.SetValue(val); + } + + bool Configuration::IsSshStrictHostKeyCheckingSet() const + { + return sshStrictHostKeyChecking.IsSet(); + } + + const std::string& Configuration::GetSshKnownHostsFile() const + { + return sshKnownHostsFile.GetValue(); + } + + void Configuration::SetSshKnownHostsFile(const std::string& path) + { + this->sshKnownHostsFile.SetValue(path); + } + + bool Configuration::IsSshKnownHostsFileSet() const + { + return sshKnownHostsFile.IsSet(); + } + + const std::string& Configuration::GetScanMethod() const + { + return scanMethod.GetValue(); + } + + void Configuration::SetScanMethod(const std::string& method) + { + this->scanMethod.SetValue(method); + } + + bool Configuration::IsScanMethodSet() const + { + return scanMethod.IsSet(); + } + + int32_t Configuration::GetScanLimit() const + { + return scanLimit.GetValue(); + } + + void Configuration::SetScanLimit(int32_t limit) + { + this->scanLimit.SetValue(limit); + } + + bool Configuration::IsScanLimitSet() const + { + return scanLimit.IsSet(); + } + + const std::string& Configuration::GetSchemaName() const + { + return schemaName.GetValue(); + } + + void Configuration::SetSchemaName(const std::string& name) + { + this->schemaName.SetValue(name); + } + + bool Configuration::IsSchemaNameSet() const + { + return schemaName.IsSet(); + } + + bool Configuration::IsSchemaRefresh() const + { + return refreshSchema.GetValue(); + } + + void Configuration::SetSchemaRefresh(bool val) + { + this->refreshSchema.SetValue(val); + } + + bool Configuration::IsSchemaRefreshSet() const + { + return refreshSchema.IsSet(); } const std::string& Configuration::GetUser() const @@ -407,49 +519,51 @@ namespace ignite return password.IsSet(); } - NestedTxMode::Type Configuration::GetNestedTxMode() const - { - return nestedTxMode.GetValue(); - } - - void Configuration::SetNestedTxMode(NestedTxMode::Type mode) + int32_t Configuration::GetDefaultFetchSize() const { - this->nestedTxMode.SetValue(mode); + return defaultFetchSize.GetValue(); } - bool Configuration::IsNestedTxModeSet() const + void Configuration::SetDefaultFetchSize(int32_t size) { - return nestedTxMode.IsSet(); + this->defaultFetchSize.SetValue(size); } - int32_t Configuration::GetPageSize() const + bool Configuration::IsDefaultFetchSizeSet() const { - return pageSize.GetValue(); + return defaultFetchSize.IsSet(); } void Configuration::ToMap(ArgumentMap& res) const { + // Need to add properties here!! AddToMap(res, ConnectionStringParser::Key::dsn, dsn); AddToMap(res, ConnectionStringParser::Key::driver, driver); - AddToMap(res, ConnectionStringParser::Key::schema, schema); + AddToMap(res, ConnectionStringParser::Key::database, database); AddToMap(res, ConnectionStringParser::Key::address, endPoints); - AddToMap(res, ConnectionStringParser::Key::server, server); + AddToMap(res, ConnectionStringParser::Key::server, hostname); AddToMap(res, ConnectionStringParser::Key::port, port); - AddToMap(res, ConnectionStringParser::Key::distributedJoins, distributedJoins); - AddToMap(res, ConnectionStringParser::Key::enforceJoinOrder, enforceJoinOrder); - AddToMap(res, ConnectionStringParser::Key::protocolVersion, protocolVersion); - AddToMap(res, ConnectionStringParser::Key::pageSize, pageSize); - AddToMap(res, ConnectionStringParser::Key::replicatedOnly, replicatedOnly); - AddToMap(res, ConnectionStringParser::Key::collocated, collocated); - AddToMap(res, ConnectionStringParser::Key::lazy, lazy); - AddToMap(res, ConnectionStringParser::Key::skipReducerOnUpdate, skipReducerOnUpdate); - AddToMap(res, ConnectionStringParser::Key::sslMode, sslMode); - AddToMap(res, ConnectionStringParser::Key::sslKeyFile, sslKeyFile); - AddToMap(res, ConnectionStringParser::Key::sslCertFile, sslCertFile); - AddToMap(res, ConnectionStringParser::Key::sslCaFile, sslCaFile); AddToMap(res, ConnectionStringParser::Key::user, user); AddToMap(res, ConnectionStringParser::Key::password, password); - AddToMap(res, ConnectionStringParser::Key::nestedTxMode, nestedTxMode); + AddToMap(res, ConnectionStringParser::Key::appName, appName); + AddToMap(res, ConnectionStringParser::Key::loginTimeoutSec, loginTimeoutSec); + AddToMap(res, ConnectionStringParser::Key::readPreference, readPreference); + AddToMap(res, ConnectionStringParser::Key::replicaSet, replicaSet); + AddToMap(res, ConnectionStringParser::Key::retryReads, retryReads); + AddToMap(res, ConnectionStringParser::Key::tls, tls); + AddToMap(res, ConnectionStringParser::Key::tlsAllowInvalidHostnames, tlsAllowInvalidHostnames); + AddToMap(res, ConnectionStringParser::Key::tlsCaFile, tlsCaFile); + AddToMap(res, ConnectionStringParser::Key::sshUser, sshUser); + AddToMap(res, ConnectionStringParser::Key::sshHost, sshHost); + AddToMap(res, ConnectionStringParser::Key::sshPrivateKeyFile, sshPrivateKeyFile); + AddToMap(res, ConnectionStringParser::Key::sshPrivateKeyPassphrase, sshPrivateKeyPassphrase); + AddToMap(res, ConnectionStringParser::Key::sshStrictHostKeyChecking, sshStrictHostKeyChecking); + AddToMap(res, ConnectionStringParser::Key::sshKnownHostsFile, sshKnownHostsFile); + AddToMap(res, ConnectionStringParser::Key::scanMethod, scanMethod); + AddToMap(res, ConnectionStringParser::Key::scanLimit, scanLimit); + AddToMap(res, ConnectionStringParser::Key::schemaName, schemaName); + AddToMap(res, ConnectionStringParser::Key::refreshSchema, refreshSchema); + AddToMap(res, ConnectionStringParser::Key::defaultFetchSize, defaultFetchSize); } template<> diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index a93e3b575..308bb225b 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -31,29 +31,35 @@ namespace ignite { namespace config { - const std::string ConnectionStringParser::Key::dsn = "dsn"; - const std::string ConnectionStringParser::Key::driver = "driver"; - const std::string ConnectionStringParser::Key::schema = "schema"; - const std::string ConnectionStringParser::Key::address = "address"; - const std::string ConnectionStringParser::Key::server = "server"; - const std::string ConnectionStringParser::Key::port = "port"; - const std::string ConnectionStringParser::Key::distributedJoins = "distributed_joins"; - const std::string ConnectionStringParser::Key::enforceJoinOrder = "enforce_join_order"; - const std::string ConnectionStringParser::Key::protocolVersion = "protocol_version"; - const std::string ConnectionStringParser::Key::pageSize = "page_size"; - const std::string ConnectionStringParser::Key::replicatedOnly = "replicated_only"; - const std::string ConnectionStringParser::Key::collocated = "collocated"; - const std::string ConnectionStringParser::Key::lazy = "lazy"; - const std::string ConnectionStringParser::Key::skipReducerOnUpdate = "skip_reducer_on_update"; - const std::string ConnectionStringParser::Key::sslMode = "ssl_mode"; - const std::string ConnectionStringParser::Key::sslKeyFile = "ssl_key_file"; - const std::string ConnectionStringParser::Key::sslCertFile = "ssl_cert_file"; - const std::string ConnectionStringParser::Key::sslCaFile = "ssl_ca_file"; - const std::string ConnectionStringParser::Key::user = "user"; - const std::string ConnectionStringParser::Key::password = "password"; - const std::string ConnectionStringParser::Key::uid = "uid"; - const std::string ConnectionStringParser::Key::pwd = "pwd"; - const std::string ConnectionStringParser::Key::nestedTxMode = "nested_tx_mode"; + const std::string ConnectionStringParser::Key::dsn = "dsn"; + const std::string ConnectionStringParser::Key::driver = "driver"; + const std::string ConnectionStringParser::Key::database = "database"; + const std::string ConnectionStringParser::Key::address = "address"; + const std::string ConnectionStringParser::Key::server = "server"; + const std::string ConnectionStringParser::Key::port = "port"; + const std::string ConnectionStringParser::Key::user = "user"; + const std::string ConnectionStringParser::Key::password = "password"; + const std::string ConnectionStringParser::Key::appName = "app_name"; + const std::string ConnectionStringParser::Key::loginTimeoutSec = "login_timeout_sec"; + const std::string ConnectionStringParser::Key::readPreference = "read_preference"; + const std::string ConnectionStringParser::Key::replicaSet = "replica_set"; + const std::string ConnectionStringParser::Key::retryReads = "retry_reads"; + const std::string ConnectionStringParser::Key::tls = "tls"; + const std::string ConnectionStringParser::Key::tlsAllowInvalidHostnames = "tls_allow_invalid_hostnames"; + const std::string ConnectionStringParser::Key::tlsCaFile = "tls_ca_file"; + const std::string ConnectionStringParser::Key::sshUser = "ssh_user"; + const std::string ConnectionStringParser::Key::sshHost = "ssh_host"; + const std::string ConnectionStringParser::Key::sshPrivateKeyFile = "ssh_private_key_file"; + const std::string ConnectionStringParser::Key::sshPrivateKeyPassphrase = "ssh_private_key_passphrase"; + const std::string ConnectionStringParser::Key::sshStrictHostKeyChecking = "ssh_strict_host_key_checking"; + const std::string ConnectionStringParser::Key::sshKnownHostsFile = "ssh_known_hosts_file"; + const std::string ConnectionStringParser::Key::scanMethod = "scan_method"; + const std::string ConnectionStringParser::Key::scanLimit = "scan_limit"; + const std::string ConnectionStringParser::Key::schemaName = "schema_name"; + const std::string ConnectionStringParser::Key::refreshSchema = "refresh_schema"; + const std::string ConnectionStringParser::Key::defaultFetchSize = "default_fetch_size"; + const std::string ConnectionStringParser::Key::uid = "uid"; + const std::string ConnectionStringParser::Key::pwd = "pwd"; ConnectionStringParser::ConnectionStringParser(Configuration& cfg): cfg(cfg) @@ -136,14 +142,14 @@ namespace ignite diagnostic::DiagnosticRecordStorage* diag) { std::string lKey = common::ToLower(key); - + if (lKey == Key::dsn) { cfg.SetDsn(value); } - else if (lKey == Key::schema) + else if (lKey == Key::database) { - cfg.SetSchema(value); + cfg.SetDatabase(value); } else if (lKey == Key::address) { @@ -155,7 +161,7 @@ namespace ignite } else if (lKey == Key::server) { - cfg.SetHost(value); + cfg.SetHostname(value); } else if (lKey == Key::port) { @@ -213,24 +219,53 @@ namespace ignite cfg.SetTcpPort(static_cast(numValue)); } - else if (lKey == Key::distributedJoins) + else if (lKey == Key::appName) { - BoolParseResult::Type res = StringToBool(value); + cfg.SetApplicationName(value); + } + else if (lKey == Key::loginTimeoutSec) + { + if (!common::AllDigits(value)) + { + if (diag) + { + diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, + MakeErrorMessage("Login timeout seconds attribute value contains unexpected characters." + " Using default value.", key, value)); + } - if (res == BoolParseResult::AI_UNRECOGNIZED) + return; + } + + int64_t numValue = 0; + std::stringstream conv; + + conv << value; + conv >> numValue; + + if (numValue <= 0 || numValue > 0xFFFFFFFFL) { if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Unrecognized bool value. Using default value.", key, value)); + MakeErrorMessage("Login timeout seconds attribute value is out of range." + " Using default value.", key, value)); } return; } - cfg.SetDistributedJoins(res == BoolParseResult::AI_TRUE); + cfg.SetScanLimit(static_cast(numValue)); + } + else if (lKey == Key::readPreference) + { + cfg.SetReadPreference(value); } - else if (lKey == Key::enforceJoinOrder) + else if (lKey == Key::replicaSet) + { + cfg.SetReplicaSet(value); + } + else if (lKey == Key::tls) { BoolParseResult::Type res = StringToBool(value); @@ -245,53 +280,78 @@ namespace ignite return; } - cfg.SetEnforceJoinOrder(res == BoolParseResult::AI_TRUE); + cfg.SetTls(res == BoolParseResult::AI_TRUE); } - else if (lKey == Key::protocolVersion) + else if (lKey == Key::tlsAllowInvalidHostnames) { - try - { - ProtocolVersion version = ProtocolVersion::FromString(value); + BoolParseResult::Type res = StringToBool(value); - if (!version.IsSupported()) + if (res == BoolParseResult::AI_UNRECOGNIZED) + { + if (diag) { - if (diag) - { - diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - "Specified version is not supported. Default value used."); - } - - return; + diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, + MakeErrorMessage("Unrecognized bool value. Using default value.", key, value)); } - cfg.SetProtocolVersion(version); - } - catch (IgniteError& err) - { - if (diag) - diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, err.GetText()); + return; } + + cfg.SetTlsAllowInvalidHostnames(res == BoolParseResult::AI_TRUE); } - else if (lKey == Key::pageSize) + else if (lKey == Key::tlsCaFile) { - if (!common::AllDigits(value)) + cfg.SetTlsCaFile(value); + } + else if (lKey == Key::sshUser) + { + cfg.SetSshUser(value); + } + else if (lKey == Key::sshHost) + { + cfg.SetSshHost(value); + } + else if (lKey == Key::sshPrivateKeyFile) + { + cfg.SetSshPrivateKeyFile(value); + } + else if (lKey == Key::sshPrivateKeyPassphrase) + { + cfg.SetSshPrivateKeyPassphrase(value); + } + else if (lKey == Key::sshStrictHostKeyChecking) + { + BoolParseResult::Type res = StringToBool(value); + + if (res == BoolParseResult::AI_UNRECOGNIZED) { if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Page size attribute value contains unexpected characters." - " Using default value.", key, value)); + MakeErrorMessage("Unrecognized bool value. Using default value.", key, value)); } return; } - if (value.size() >= sizeof("4294967295")) + cfg.SetSshStrictHostKeyChecking(res == BoolParseResult::AI_TRUE); + } + else if (lKey == Key::sshKnownHostsFile) + { + cfg.SetSshKnownHostsFile(value); + } + else if (lKey == Key::scanMethod) + { + cfg.SetScanMethod(value); + } + else if (lKey == Key::scanLimit) + { + if (!common::AllDigits(value)) { if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Page size attribute value is too large." + MakeErrorMessage("Scan limit attribute value contains unexpected characters." " Using default value.", key, value)); } @@ -309,33 +369,20 @@ namespace ignite if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Page size attribute value is out of range." + MakeErrorMessage("Scan limit attribute value is out of range." " Using default value.", key, value)); } return; } - cfg.SetPageSize(static_cast(numValue)); + cfg.SetScanLimit(static_cast(numValue)); } - else if (lKey == Key::replicatedOnly) + else if (lKey == Key::schemaName) { - BoolParseResult::Type res = StringToBool(value); - - if (res == BoolParseResult::AI_UNRECOGNIZED) - { - if (diag) - { - diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Unrecognized bool value. Using default value.", key, value)); - } - - return; - } - - cfg.SetReplicatedOnly(res == BoolParseResult::AI_TRUE); + cfg.SetSchemaName(value); } - else if (lKey == Key::collocated) + else if (lKey == Key::refreshSchema) { BoolParseResult::Type res = StringToBool(value); @@ -350,70 +397,57 @@ namespace ignite return; } - cfg.SetCollocated(res == BoolParseResult::AI_TRUE); + cfg.SetTls(res == BoolParseResult::AI_TRUE); } - else if (lKey == Key::lazy) + else if (lKey == Key::defaultFetchSize) { - BoolParseResult::Type res = StringToBool(value); - - if (res == BoolParseResult::AI_UNRECOGNIZED) + if (!common::AllDigits(value)) { if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Unrecognized bool value. Defaulting to 'false'.", key, value)); + MakeErrorMessage("Default fetch size attribute value contains unexpected characters." + " Using default value.", key, value)); } return; } - cfg.SetLazy(res == BoolParseResult::AI_TRUE); - } - else if (lKey == Key::skipReducerOnUpdate) - { - BoolParseResult::Type res = StringToBool(value); - - if (res == BoolParseResult::AI_UNRECOGNIZED) + if (value.size() >= sizeof("4294967295")) { if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Unrecognized bool value. Defaulting to 'false'.", key, value)); + MakeErrorMessage("Page size attribute value is too large." + " Using default value.", key, value)); } return; } - cfg.SetSkipReducerOnUpdate(res == BoolParseResult::AI_TRUE); - } - else if (lKey == Key::sslMode) - { - ssl::SslMode::Type mode = ssl::SslMode::FromString(value); + int64_t numValue = 0; + std::stringstream conv; - if (mode == ssl::SslMode::UNKNOWN) + conv << value; + conv >> numValue; + + if (numValue <= 0 || numValue > 0xFFFFFFFFL) { if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - "Specified SSL mode is not supported. Default value used ('disable')."); + MakeErrorMessage("Page size attribute value is out of range." + " Using default value.", key, value)); } return; } - cfg.SetSslMode(mode); - } - else if (lKey == Key::sslKeyFile) - { - cfg.SetSslKeyFile(value); - } - else if (lKey == Key::sslCertFile) - { - cfg.SetSslCertFile(value); - } - else if (lKey == Key::sslCaFile) + cfg.SetDefaultFetchSize(static_cast(numValue)); + } + else if (lKey == Key::tlsCaFile) { - cfg.SetSslCaFile(value); + cfg.SetTlsCaFile(value); } else if (lKey == Key::driver) { @@ -439,23 +473,6 @@ namespace ignite cfg.SetPassword(value); } - else if (lKey == Key::nestedTxMode) - { - NestedTxMode::Type mode = NestedTxMode::FromString(value); - - if (mode == NestedTxMode::AI_UNKNOWN) - { - if (diag) - { - diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - "Specified nested transaction mode is not supported. Default value used ('error')."); - } - - return; - } - - cfg.SetNestedTxMode(mode); - } else if (diag) { std::stringstream stream; diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index c472716d1..c2875fd7e 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -145,7 +145,8 @@ namespace ignite SqlResult::Type Connection::InitSocket() { - ssl::SslMode::Type sslMode = config.GetSslMode(); + // Removed SSL Mode in DSN. Replaced this with REQUIRE for now. + ssl::SslMode::Type sslMode = ssl::SslMode::REQUIRE; if (sslMode == ssl::SslMode::DISABLE) { @@ -167,8 +168,9 @@ namespace ignite return SqlResult::AI_ERROR; } + // Removed SSL key and cert files from DSN. Replaced with empty string for now. socket.reset(network::ssl::MakeSecureSocketClient( - config.GetSslCertFile(), config.GetSslKeyFile(), config.GetSslCaFile())); + "", "", config.GetTlsCaFile())); return SqlResult::AI_SUCCESS; } @@ -186,7 +188,7 @@ namespace ignite return SqlResult::AI_ERROR; } - if (!config.IsHostSet() && config.IsAddressesSet() && config.GetAddresses().empty()) + if (!config.IsHostnameSet() && config.IsAddressesSet() && config.GetAddresses().empty()) { AddStatusRecord("No valid address to connect."); @@ -392,7 +394,7 @@ namespace ignite const std::string& Connection::GetSchema() const { - return config.GetSchema(); + return config.GetDatabase(); } const config::Configuration& Connection::GetConfiguration() const @@ -418,7 +420,7 @@ namespace ignite SqlResult::Type Connection::InternalTransactionCommit() { - std::string schema = config.GetSchema(); + std::string schema = config.GetDatabase(); app::ParameterSet empty; @@ -459,7 +461,7 @@ namespace ignite SqlResult::Type Connection::InternalTransactionRollback() { - std::string schema = config.GetSchema(); + std::string schema = config.GetDatabase(); app::ParameterSet empty; @@ -636,7 +638,7 @@ namespace ignite SqlResult::Type Connection::MakeRequestHandshake() { - ProtocolVersion protocolVersion = config.GetProtocolVersion(); + /* ProtocolVersion protocolVersion = config.GetProtocolVersion(); if (!protocolVersion.IsSupported()) { @@ -653,6 +655,7 @@ namespace ignite return SqlResult::AI_ERROR; } + */ HandshakeRequest req(config); HandshakeResponse rsp; @@ -695,10 +698,12 @@ namespace ignite if (!rsp.GetError().empty()) constructor << "Additional info: " << rsp.GetError() << " "; - constructor << "Current version of the protocol, used by the server node is " + /* constructor + << "Current version of the protocol, used by the server " + "node is " << rsp.GetCurrentVer().ToString() << ", " << "driver protocol version introduced in version " - << protocolVersion.ToString() << "."; + << protocolVersion.ToString() << "."; */ AddStatusRecord(SqlState::S08004_CONNECTION_REJECTED, constructor.str()); @@ -767,8 +772,6 @@ namespace ignite if (!connected) Close(); - else - parser.SetProtocolVersion(config.GetProtocolVersion()); return connected; } @@ -781,7 +784,7 @@ namespace ignite { LOG_MSG("'Address' is not set. Using legacy connection method."); - endPoints.push_back(EndPoint(cfg.GetHost(), cfg.GetTcpPort())); + endPoints.push_back(EndPoint(cfg.GetHostname(), cfg.GetTcpPort())); return; } diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 8f1a6df16..6526a38bd 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -117,104 +117,125 @@ namespace ignite SettableValue server = ReadDsnString(dsn, ConnectionStringParser::Key::server); - if (server.IsSet() && !config.IsHostSet()) - config.SetHost(server.GetValue()); + if (server.IsSet() && !config.IsHostnameSet()) + config.SetHostname(server.GetValue()); SettableValue port = ReadDsnInt(dsn, ConnectionStringParser::Key::port); if (port.IsSet() && !config.IsTcpPortSet()) config.SetTcpPort(static_cast(port.GetValue())); - SettableValue schema = ReadDsnString(dsn, ConnectionStringParser::Key::schema); + SettableValue database = ReadDsnString(dsn, ConnectionStringParser::Key::database); - if (schema.IsSet() && !config.IsSchemaSet()) - config.SetSchema(schema.GetValue()); + if (database.IsSet() && !config.IsDatabaseSet()) + config.SetDatabase(database.GetValue()); - SettableValue distributedJoins = ReadDsnBool(dsn, ConnectionStringParser::Key::distributedJoins); + SettableValue user = ReadDsnString(dsn, ConnectionStringParser::Key::user); - if (distributedJoins.IsSet() && !config.IsDistributedJoinsSet()) - config.SetDistributedJoins(distributedJoins.GetValue()); + if (user.IsSet() && !config.IsUserSet()) + config.SetUser(user.GetValue()); - SettableValue enforceJoinOrder = ReadDsnBool(dsn, ConnectionStringParser::Key::enforceJoinOrder); + SettableValue password = ReadDsnString(dsn, ConnectionStringParser::Key::password); - if (enforceJoinOrder.IsSet() && !config.IsEnforceJoinOrderSet()) - config.SetEnforceJoinOrder(enforceJoinOrder.GetValue()); + if (password.IsSet() && !config.IsPasswordSet()) + config.SetPassword(password.GetValue()); - SettableValue replicatedOnly = ReadDsnBool(dsn, ConnectionStringParser::Key::replicatedOnly); + SettableValue appName = ReadDsnString(dsn, ConnectionStringParser::Key::appName); - if (replicatedOnly.IsSet() && !config.IsReplicatedOnlySet()) - config.SetReplicatedOnly(replicatedOnly.GetValue()); + if (appName.IsSet() && !config.IsApplicationNameSet()) + config.SetApplicationName(appName.GetValue()); - SettableValue collocated = ReadDsnBool(dsn, ConnectionStringParser::Key::collocated); + SettableValue loginTimeoutSec = ReadDsnInt(dsn, ConnectionStringParser::Key::loginTimeoutSec); - if (collocated.IsSet() && !config.IsCollocatedSet()) - config.SetCollocated(collocated.GetValue()); + if (loginTimeoutSec.IsSet() && !config.IsLoginTimeoutSecondsSet()) + config.SetLoginTimeoutSeconds(loginTimeoutSec.GetValue()); - SettableValue lazy = ReadDsnBool(dsn, ConnectionStringParser::Key::lazy); + SettableValue readPreference = ReadDsnString(dsn, ConnectionStringParser::Key::readPreference); - if (lazy.IsSet() && !config.IsLazySet()) - config.SetLazy(lazy.GetValue()); + if (readPreference.IsSet() && !config.IsReadPreferenceSet()) + config.SetReadPreference(readPreference.GetValue()); - SettableValue skipReducerOnUpdate = ReadDsnBool(dsn, ConnectionStringParser::Key::skipReducerOnUpdate); + SettableValue replicaSet = ReadDsnString(dsn, ConnectionStringParser::Key::replicaSet); - if (skipReducerOnUpdate.IsSet() && !config.IsSkipReducerOnUpdateSet()) - config.SetSkipReducerOnUpdate(skipReducerOnUpdate.GetValue()); + if (replicaSet.IsSet() && !config.IsReplicaSetSet()) + config.SetReplicaSet(replicaSet.GetValue()); - SettableValue versionStr = ReadDsnString(dsn, ConnectionStringParser::Key::protocolVersion); + SettableValue retryReads = ReadDsnBool(dsn, ConnectionStringParser::Key::retryReads); - if (versionStr.IsSet() && !config.IsProtocolVersionSet()) - { - ProtocolVersion version = ProtocolVersion::FromString(versionStr.GetValue()); + if (retryReads.IsSet() && !config.IsRetryReadsSet()) + config.SetRetryReads(retryReads.GetValue()); - if (!version.IsSupported()) - version = Configuration::DefaultValue::protocolVersion; + SettableValue tls = ReadDsnBool(dsn, ConnectionStringParser::Key::tls); - config.SetProtocolVersion(version); - } + if (tls.IsSet() && !config.IsTlsSet()) + config.SetTls(tls.GetValue()); - SettableValue pageSize = ReadDsnInt(dsn, ConnectionStringParser::Key::pageSize); + SettableValue tlsAllowInvalidHostnames = ReadDsnBool(dsn, ConnectionStringParser::Key::tlsAllowInvalidHostnames); - if (pageSize.IsSet() && !config.IsPageSizeSet() && pageSize.GetValue() > 0) - config.SetPageSize(pageSize.GetValue()); + if (tlsAllowInvalidHostnames.IsSet() && !config.IsTlsAllowInvalidHostnamesSet()) + config.SetTlsAllowInvalidHostnames(tlsAllowInvalidHostnames.GetValue()); - SettableValue sslModeStr = ReadDsnString(dsn, ConnectionStringParser::Key::sslMode); + SettableValue tlsCaFile = ReadDsnString(dsn, ConnectionStringParser::Key::tlsCaFile); - if (sslModeStr.IsSet() && !config.IsSslModeSet()) - { - ssl::SslMode::Type sslMode = ssl::SslMode::FromString(sslModeStr.GetValue(), ssl::SslMode::DISABLE); + if (tlsCaFile.IsSet() && !config.IsTlsCaFileSet()) + config.SetTlsCaFile(tlsCaFile.GetValue()); - config.SetSslMode(sslMode); - } + SettableValue sshUser = ReadDsnString(dsn, ConnectionStringParser::Key::sshUser); - SettableValue sslKeyFile = ReadDsnString(dsn, ConnectionStringParser::Key::sslKeyFile); + if (sshUser.IsSet() && !config.IsSshUserSet()) + config.SetSshUser(sshUser.GetValue()); - if (sslKeyFile.IsSet() && !config.IsSslKeyFileSet()) - config.SetSslKeyFile(sslKeyFile.GetValue()); + SettableValue sshHost = ReadDsnString(dsn, ConnectionStringParser::Key::sshHost); - SettableValue sslCertFile = ReadDsnString(dsn, ConnectionStringParser::Key::sslCertFile); + if (sshHost.IsSet() && !config.IsSshHostSet()) + config.SetSshHost(sshHost.GetValue()); - if (sslCertFile.IsSet() && !config.IsSslCertFileSet()) - config.SetSslCertFile(sslCertFile.GetValue()); + SettableValue sshPrivateKeyFile = ReadDsnString(dsn, ConnectionStringParser::Key::sshPrivateKeyFile); - SettableValue sslCaFile = ReadDsnString(dsn, ConnectionStringParser::Key::sslCaFile); + if (sshPrivateKeyFile.IsSet() && !config.IsSshPrivateKeyFileSet()) + config.SetSshPrivateKeyFile(sshPrivateKeyFile.GetValue()); - if (sslCaFile.IsSet() && !config.IsSslCaFileSet()) - config.SetSslCaFile(sslCaFile.GetValue()); + SettableValue sshPrivateKeyPassphrase = ReadDsnString(dsn, ConnectionStringParser::Key::sshPrivateKeyPassphrase); - SettableValue user = ReadDsnString(dsn, ConnectionStringParser::Key::user); + if (sshPrivateKeyPassphrase.IsSet() && !config.IsSshPrivateKeyPassphraseSet()) + config.SetSshPrivateKeyPassphrase(sshPrivateKeyPassphrase.GetValue()); + + SettableValue sshStrictHostKeyChecking = ReadDsnBool(dsn, ConnectionStringParser::Key::sshStrictHostKeyChecking); - if (user.IsSet() && !config.IsUserSet()) - config.SetUser(user.GetValue()); + if (sshStrictHostKeyChecking.IsSet() && !config.IsSshStrictHostKeyCheckingSet()) + config.SetSshStrictHostKeyChecking(sshStrictHostKeyChecking.GetValue()); - SettableValue password = ReadDsnString(dsn, ConnectionStringParser::Key::password); + SettableValue sshKnownHostsFile = ReadDsnString(dsn, ConnectionStringParser::Key::sshKnownHostsFile); - if (password.IsSet() && !config.IsPasswordSet()) - config.SetPassword(password.GetValue()); + if (sshKnownHostsFile.IsSet() && !config.IsSshStrictHostKeyCheckingSet()) + config.SetSshStrictHostKeyChecking(sshStrictHostKeyChecking.GetValue()); + + SettableValue scanMethod = ReadDsnString(dsn, ConnectionStringParser::Key::scanMethod); + + if (scanMethod.IsSet() && !config.IsScanMethodSet()) + config.SetScanMethod(scanMethod.GetValue()); + + SettableValue scanLimit = ReadDsnInt(dsn, ConnectionStringParser::Key::scanLimit); + + if (scanLimit.IsSet() && !config.IsScanLimitSet() + && scanLimit.GetValue() > 0) + config.SetDefaultFetchSize(scanLimit.GetValue()); + + SettableValue schemaName = ReadDsnString(dsn, ConnectionStringParser::Key::schemaName); + + if (schemaName.IsSet() && !config.IsSchemaNameSet()) + config.SetSchemaName(schemaName.GetValue()); + + SettableValue refreshSchema = ReadDsnBool(dsn, ConnectionStringParser::Key::refreshSchema); + + if (refreshSchema.IsSet() && !config.IsSchemaRefreshSet()) + config.SetSchemaRefresh(refreshSchema.GetValue()); - SettableValue nestedTxModeStr = ReadDsnString(dsn, ConnectionStringParser::Key::nestedTxMode); + SettableValue defaultFetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::defaultFetchSize); - if (nestedTxModeStr.IsSet() && !config.IsNestedTxModeSet()) - config.SetNestedTxMode(NestedTxMode::FromString(nestedTxModeStr.GetValue(), config.GetNestedTxMode())); + if (defaultFetchSize.IsSet() && !config.IsDefaultFetchSizeSet() + && defaultFetchSize.GetValue() > 0) + config.SetDefaultFetchSize(defaultFetchSize.GetValue()); } } } diff --git a/src/odbc/src/message.cpp b/src/odbc/src/message.cpp index 946529de3..80b809205 100644 --- a/src/odbc/src/message.cpp +++ b/src/odbc/src/message.cpp @@ -62,14 +62,14 @@ namespace ignite { writer.WriteInt8(RequestType::HANDSHAKE); - ProtocolVersion version = config.GetProtocolVersion(); + ProtocolVersion version = ProtocolVersion::GetCurrent(); writer.WriteInt16(version.GetMajor()); writer.WriteInt16(version.GetMinor()); writer.WriteInt16(version.GetMaintenance()); writer.WriteInt8(ClientType::ODBC); - writer.WriteBool(config.IsDistributedJoins()); + /*writer.WriteBool(config.IsDistributedJoins()); writer.WriteBool(config.IsEnforceJoinOrder()); writer.WriteBool(config.IsReplicatedOnly()); writer.WriteBool(config.IsCollocated()); @@ -87,7 +87,7 @@ namespace ignite } if (version >= ProtocolVersion::VERSION_2_7_0) - writer.WriteInt8(config.GetNestedTxMode()); + writer.WriteInt8(config.GetNestedTxMode());*/ } QueryExecuteRequest::QueryExecuteRequest(const std::string& schema, const std::string& sql, diff --git a/src/odbc/src/query/batch_query.cpp b/src/odbc/src/query/batch_query.cpp index 8b26e0d59..7390b4f59 100644 --- a/src/odbc/src/query/batch_query.cpp +++ b/src/odbc/src/query/batch_query.cpp @@ -52,7 +52,7 @@ namespace ignite if (executed) Close(); - int32_t maxPageSize = connection.GetConfiguration().GetPageSize(); + int32_t maxPageSize = connection.GetConfiguration().GetDefaultFetchSize(); int32_t rowNum = params.GetParamSetSize(); SqlResult::Type res; diff --git a/src/odbc/src/query/data_query.cpp b/src/odbc/src/query/data_query.cpp index 54723a109..d5c4d6a6d 100644 --- a/src/odbc/src/query/data_query.cpp +++ b/src/odbc/src/query/data_query.cpp @@ -193,7 +193,7 @@ namespace ignite if (affected >= 0) return affected; - return connection.GetConfiguration().GetPageSize(); + return connection.GetConfiguration().GetDefaultFetchSize(); } SqlResult::Type DataQuery::NextResultSet() @@ -320,7 +320,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetPageSize()); + QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); QueryFetchResponse rsp(*resultPage); try @@ -361,7 +361,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetPageSize()); + QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); QueryMoreResultsResponse rsp(*resultPage); try From 5914412c6a7d3183bd78d4f1816ad3fa79057f7b Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 18 Jan 2022 14:51:19 -0800 Subject: [PATCH 009/100] remove SSL settings and add TLS checkbox on the Configuration Window --- .../odbc/system/ui/dsn_configuration_window.h | 4 + .../system/ui/dsn_configuration_window.cpp | 104 ++++++++++-------- 2 files changed, 65 insertions(+), 43 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 77974ade3..d528317d3 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -63,6 +63,7 @@ namespace ignite PROTOCOL_VERSION_COMBO_BOX, NESTED_TX_MODE_LABEL, NESTED_TX_MODE_COMBO_BOX, + TLS_CHECK_BOX, SSL_MODE_LABEL, SSL_MODE_COMBO_BOX, SSL_KEY_FILE_LABEL, @@ -278,6 +279,9 @@ namespace ignite /** Cancel button. */ std::auto_ptr cancelButton; + /** TLS Encryption CheckBox. */ + std::auto_ptr< Window > tlsCheckBox; + /** SSL Mode label. */ std::auto_ptr sslModeLabel; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index c8832697c..6f2eab8c4 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -32,15 +32,16 @@ namespace ignite namespace system { namespace ui - { + { // -AL- the constructor. No-op means no operation I think? DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config): CustomWindow(parent, "IgniteConfigureDsn", "Configure Amazon DocumentDB DSN Latest"), width(360), height(600), connectionSettingsGroupBox(), - sslSettingsGroupBox(), + sslSettingsGroupBox(), // has a create... function defined + tlsCheckBox(), authSettingsGroupBox(), - additionalSettingsGroupBox(), + // additionalSettingsGroupBox(), nameLabel(), nameEdit(), addressLabel(), @@ -52,7 +53,8 @@ namespace ignite distributedJoinsCheckBox(), enforceJoinOrderCheckBox(), replicatedOnlyCheckBox(), - collocatedCheckBox(), + // collocatedCheckBox(), // -AL- after commenting this out, the checkbox is intact? + // checkbox is created in function DsnConfigurationWindow::CreateAdditionalSettingsGroup protocolVersionLabel(), protocolVersionComboBox(), userLabel(), @@ -98,7 +100,7 @@ namespace ignite throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, buf.str().c_str()); } } - + // the function that actually creates the UI -AL- void DsnConfigurationWindow::OnCreate() { int groupPosY = MARGIN; @@ -108,6 +110,8 @@ namespace ignite groupPosY += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosY, groupSizeY); groupPosY += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosY, groupSizeY); groupPosY += INTERVAL + CreateAdditionalSettingsGroup(MARGIN, groupPosY, groupSizeY); + // test: if above code is commented out, additional settings shouldn't appear in config window. Result: Yes test success. + // what happens here is the height of each subgroup is calculated and appended to the y position of the buttons int cancelPosX = width - MARGIN - BUTTON_WIDTH; int okPosX = cancelPosX - INTERVAL - BUTTON_WIDTH; @@ -216,7 +220,7 @@ namespace ignite } int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) - { + { // TODO: rename function name from Ssl to TLS after UI works using ssl::SslMode; enum { LABEL_WIDTH = 120 }; @@ -228,59 +232,66 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; - SslMode::Type sslMode = ssl::SslMode::REQUIRE; - std::string sslModeStr = SslMode::ToString(sslMode); + int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; - const char* val = sslModeStr.c_str(); + tlsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + "TLS", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, true); - sslModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSL Mode:", ChildId::SSL_MODE_LABEL); - sslModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, - "", ChildId::SSL_MODE_COMBO_BOX); + rowPos += INTERVAL + ROW_HEIGHT; - sslModeComboBox->AddString("disable"); - sslModeComboBox->AddString("require"); + //SslMode::Type sslMode = ssl::SslMode::REQUIRE; + //std::string sslModeStr = SslMode::ToString(sslMode); - sslModeComboBox->SetSelection(sslMode); + //const char* val = sslModeStr.c_str(); - rowPos += INTERVAL + ROW_HEIGHT; + //sslModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + // "SSL Mode:", ChildId::SSL_MODE_LABEL); + //sslModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, + // "", ChildId::SSL_MODE_COMBO_BOX); - val = config.GetTlsCaFile().c_str(); - sslKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSL Private Key:", ChildId::SSL_KEY_FILE_LABEL); - sslKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - val, ChildId::SSL_KEY_FILE_EDIT); + //sslModeComboBox->AddString("disable"); + //sslModeComboBox->AddString("require"); - SHAutoComplete(sslKeyFileEdit->GetHandle(), SHACF_DEFAULT); + //sslModeComboBox->SetSelection(sslMode); // set default value to require -AL- - rowPos += INTERVAL + ROW_HEIGHT; + //rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight I believe - val = config.GetTlsCaFile().c_str(); - sslCertFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSL Certificate:", ChildId::SSL_CERT_FILE_LABEL); - sslCertFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - val, ChildId::SSL_CERT_FILE_EDIT); + //val = config.GetTlsCaFile().c_str(); + //sslKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + // "SSL Private Key:", ChildId::SSL_KEY_FILE_LABEL); + //sslKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, + // val, ChildId::SSL_KEY_FILE_EDIT); - SHAutoComplete(sslCertFileEdit->GetHandle(), SHACF_DEFAULT); + //SHAutoComplete(sslKeyFileEdit->GetHandle(), SHACF_DEFAULT); - rowPos += INTERVAL + ROW_HEIGHT; + //rowPos += INTERVAL + ROW_HEIGHT; - val = config.GetTlsCaFile().c_str(); - sslCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSL Certificate Authority:", ChildId::SSL_CA_FILE_LABEL); - sslCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - val, ChildId::SSL_CA_FILE_EDIT); + //val = config.GetTlsCaFile().c_str(); + //sslCertFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + // "SSL Certificate:", ChildId::SSL_CERT_FILE_LABEL); + //sslCertFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, + // val, ChildId::SSL_CERT_FILE_EDIT); - SHAutoComplete(sslCaFileEdit->GetHandle(), SHACF_DEFAULT); + //SHAutoComplete(sslCertFileEdit->GetHandle(), SHACF_DEFAULT); - rowPos += INTERVAL + ROW_HEIGHT; + // rowPos += INTERVAL + ROW_HEIGHT; + + //val = config.GetTlsCaFile().c_str(); + //sslCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + // "SSL Certificate Authority:", ChildId::SSL_CA_FILE_LABEL); + //sslCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, + // val, ChildId::SSL_CA_FILE_EDIT); + + //SHAutoComplete(sslCaFileEdit->GetHandle(), SHACF_DEFAULT); + + // rowPos += INTERVAL + ROW_HEIGHT; sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX); - sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - sslCaFileEdit->SetEnabled(sslMode != SslMode::DISABLE); + //sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE); + //sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE); + //sslCaFileEdit->SetEnabled(sslMode != SslMode::DISABLE); return rowPos - posY; } @@ -371,7 +382,7 @@ namespace ignite return rowPos - posY; } - + // -AL- I'm not changing this one yet. bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) @@ -461,7 +472,13 @@ namespace ignite break; } - case ChildId::SSL_MODE_COMBO_BOX: + case ChildId::TLS_CHECK_BOX: { + tlsCheckBox->SetChecked(!tlsCheckBox->IsChecked()); + + break; + } + + case ChildId::SSL_MODE_COMBO_BOX: //-AL- may need to remove this later { using ssl::SslMode; @@ -607,6 +624,7 @@ namespace ignite nestedTxModeComboBox->GetText(nestedTxModeStr); + // unnecessary code is commented out -AL- //NestedTxMode::Type mode = NestedTxMode::FromString(nestedTxModeStr, config.GetNestedTxMode()); //bool distributedJoins = distributedJoinsCheckBox->IsChecked(); From df38b8c7815cb9ae33b460137101ffe7544f38f8 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 18 Jan 2022 14:52:14 -0800 Subject: [PATCH 010/100] add comments for my own work added some comments for my own convenience. Will remove later --- src/odbc/src/config/configuration.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 198ecb9d0..e852bb652 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +// configures for what is defined in .h .h has a lot of setable values, replaces with DocumentDB properties. #include #include #include @@ -33,25 +33,25 @@ namespace ignite const std::string Configuration::DefaultValue::dsn = "Apache Ignite DSN"; const std::string Configuration::DefaultValue::driver = "Apache Ignite"; - const std::string Configuration::DefaultValue::database = ""; + const std::string Configuration::DefaultValue::database = ""; // renamed from Schema const std::string Configuration::DefaultValue::address = ""; // remove const std::string Configuration::DefaultValue::hostname = ""; const uint16_t Configuration::DefaultValue::port = 27017; const std::string Configuration::DefaultValue::user = ""; const std::string Configuration::DefaultValue::password = ""; - // SSL/TLS options - const bool Configuration::DefaultValue::tls = true; - const bool Configuration::DefaultValue::tlsAllowInvalidHostnames = false; - const std::string Configuration::DefaultValue::tlsCaFile = ""; + // SSL/TLS options. Use checkboxes for boolean variables // need to add to UI + const bool Configuration::DefaultValue::tls = true; // changed instead of SSL mode; tls is TLS Encryption + const bool Configuration::DefaultValue::tlsAllowInvalidHostnames = false; // needs to be set to true for SSH; TLS Allow Invalid Hostnames + const std::string Configuration::DefaultValue::tlsCaFile = ""; //renamed from SSL CA file - // Schema Generation and Discovery options + // Schema Generation and Discovery options // need to add to UI const std::string Configuration::DefaultValue::scanMethod = "random"; const int32_t Configuration::DefaultValue::scanLimit = 1000; const std::string Configuration::DefaultValue::schemaName = "_default"; const bool Configuration::DefaultValue::refreshSchema = false; - // Internal SSH Tunnel options + // Internal SSH Tunnel options // need to add to UI const std::string Configuration::DefaultValue::sshUser = ""; const std::string Configuration::DefaultValue::sshHost = ""; const std::string Configuration::DefaultValue::sshPrivateKeyFile = ""; @@ -59,7 +59,7 @@ namespace ignite const bool Configuration::DefaultValue::sshStrictHostKeyChecking = true; const std::string Configuration::DefaultValue::sshKnownHostsFile = ""; - // Additional options + // Additional options // // need to add to UI const std::string Configuration::DefaultValue::appName = "Amazon DocumentDB ODBC Driver"; const int32_t Configuration::DefaultValue::loginTimeoutSec = 0; const std::string Configuration::DefaultValue::readPreference = ""; From f939e30b2692a6bcecdd3c6b6f6535e9d87ef1fd Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 18 Jan 2022 16:57:06 -0800 Subject: [PATCH 011/100] fix tls checkbox on Configuration Window fixed by updating ChildId in tlsCheckBox = CreateCheckBox --- .../odbc/system/ui/dsn_configuration_window.h | 53 +++++++-------- .../system/ui/dsn_configuration_window.cpp | 64 ++++++++++++------- 2 files changed, 68 insertions(+), 49 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index d528317d3..badfc42de 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -64,14 +64,14 @@ namespace ignite NESTED_TX_MODE_LABEL, NESTED_TX_MODE_COMBO_BOX, TLS_CHECK_BOX, - SSL_MODE_LABEL, - SSL_MODE_COMBO_BOX, - SSL_KEY_FILE_LABEL, - SSL_KEY_FILE_EDIT, - SSL_CERT_FILE_LABEL, - SSL_CERT_FILE_EDIT, - SSL_CA_FILE_LABEL, - SSL_CA_FILE_EDIT, + //SSL_MODE_LABEL, + //SSL_MODE_COMBO_BOX, + //SSL_KEY_FILE_LABEL, + //SSL_KEY_FILE_EDIT, + //SSL_CERT_FILE_LABEL, + //SSL_CERT_FILE_EDIT, + //SSL_CA_FILE_LABEL, + //SSL_CA_FILE_EDIT, USER_LABEL, USER_EDIT, PASSWORD_LABEL, @@ -280,31 +280,34 @@ namespace ignite std::auto_ptr cancelButton; /** TLS Encryption CheckBox. */ - std::auto_ptr< Window > tlsCheckBox; + std::auto_ptr tlsCheckBox; - /** SSL Mode label. */ - std::auto_ptr sslModeLabel; - /** SSL Mode ComboBox. */ - std::auto_ptr sslModeComboBox; - /** SSL Private Key File label. */ - std::auto_ptr sslKeyFileLabel; - /** SSL Private Key File edit. */ - std::auto_ptr sslKeyFileEdit; + ///** SSL Mode label. */ + //std::auto_ptr sslModeLabel; - /** SSL Certificate File label. */ - std::auto_ptr sslCertFileLabel; + ///** SSL Mode ComboBox. */ + //std::auto_ptr sslModeComboBox; - /** SSL Certificate File edit. */ - std::auto_ptr sslCertFileEdit; + ///** SSL Private Key File label. */ + //std::auto_ptr sslKeyFileLabel; - /** SSL Certificate Authority File label. */ - std::auto_ptr sslCaFileLabel; + ///** SSL Private Key File edit. */ + //std::auto_ptr sslKeyFileEdit; - /** SSL Certificate Authority File edit. */ - std::auto_ptr sslCaFileEdit; + ///** SSL Certificate File label. */ + //std::auto_ptr sslCertFileLabel; + + ///** SSL Certificate File edit. */ + //std::auto_ptr sslCertFileEdit; + + ///** SSL Certificate Authority File label. */ + //std::auto_ptr sslCaFileLabel; + + ///** SSL Certificate Authority File edit. */ + //std::auto_ptr sslCaFileEdit; /** User label. */ std::auto_ptr userLabel; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 6f2eab8c4..ff9a35948 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -221,7 +221,7 @@ namespace ignite int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) { // TODO: rename function name from Ssl to TLS after UI works - using ssl::SslMode; + //using ssl::SslMode; enum { LABEL_WIDTH = 120 }; @@ -235,7 +235,7 @@ namespace ignite int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; tlsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "TLS", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, true); + "TLS", ChildId::TLS_CHECK_BOX, true); rowPos += INTERVAL + ROW_HEIGHT; @@ -472,7 +472,8 @@ namespace ignite break; } - case ChildId::TLS_CHECK_BOX: { + case ChildId::TLS_CHECK_BOX: + { tlsCheckBox->SetChecked(!tlsCheckBox->IsChecked()); break; @@ -485,14 +486,21 @@ namespace ignite std::string sslModeStr; sslModeComboBox->GetText(sslModeStr); - SslMode::Type sslMode = SslMode::FromString(sslModeStr, SslMode::DISABLE); + //case ChildId::SSL_MODE_COMBO_BOX: //-AL- may need to remove this later + //{ + // using ssl::SslMode; - sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - sslCaFileEdit->SetEnabled(sslMode != SslMode::DISABLE); + // std::string sslModeStr; + // sslModeComboBox->GetText(sslModeStr); - break; - } + // SslMode::Type sslMode = SslMode::FromString(sslModeStr, SslMode::DISABLE); + + // sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE); + // sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE); + // sslCaFileEdit->SetEnabled(sslMode != SslMode::DISABLE); + + // break; + //} default: return false; @@ -585,28 +593,36 @@ namespace ignite void DsnConfigurationWindow::RetrieveSslParameters(config::Configuration& cfg) const { - std::string sslModeStr; - std::string sslKeyStr; - std::string sslCertStr; - std::string sslCaStr; - sslModeComboBox->GetText(sslModeStr); - sslKeyFileEdit->GetText(sslKeyStr); - sslCertFileEdit->GetText(sslCertStr); - sslCaFileEdit->GetText(sslCaStr); + bool tls = tlsCheckBox->IsChecked(); - LOG_MSG("Retrieving arguments:"); - LOG_MSG("SSL Mode: " << sslModeStr); - LOG_MSG("SSL Key: " << sslKeyStr); - LOG_MSG("SSL Certificate: " << sslCertStr); - LOG_MSG("SSL CA: " << sslCaStr); - ssl::SslMode::Type sslMode = ssl::SslMode::FromString(sslModeStr, ssl::SslMode::DISABLE); + LOG_MSG("TLS/SSL Encryption: " << (tls ? "true" : "false")); + + cfg.SetTls(tls); + + //std::string sslModeStr; + //std::string sslKeyStr; + //std::string sslCertStr; + //std::string sslCaStr; + + ////sslModeComboBox->GetText(sslModeStr); + ////sslKeyFileEdit->GetText(sslKeyStr); + ////sslCertFileEdit->GetText(sslCertStr); + ////sslCaFileEdit->GetText(sslCaStr); + + //LOG_MSG("Retrieving arguments:"); + //LOG_MSG("SSL Mode: " << sslModeStr); + //LOG_MSG("SSL Key: " << sslKeyStr); + //LOG_MSG("SSL Certificate: " << sslCertStr); + //LOG_MSG("SSL CA: " << sslCaStr); + + //ssl::SslMode::Type sslMode = ssl::SslMode::FromString(sslModeStr, ssl::SslMode::DISABLE); //cfg.SetSslMode(sslMode); //cfg.SetSslKeyFile(sslKeyStr); //cfg.SetSslCertFile(sslCertStr); - cfg.SetTlsCaFile(sslCaStr); + //cfg.SetTlsCaFile(sslCaStr); } void DsnConfigurationWindow::RetrieveAdditionalParameters(config::Configuration& cfg) const From 28950adb00307ad560dfb166d67467f7c202abf2 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 18 Jan 2022 16:58:12 -0800 Subject: [PATCH 012/100] add TlsAllowInvalidHostnames checkbox and TLS CA edit to the Configuration Window --- .../odbc/system/ui/dsn_configuration_window.h | 9 +++++ .../system/ui/dsn_configuration_window.cpp | 34 ++++++++++++++++--- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index badfc42de..eefce6894 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -64,6 +64,9 @@ namespace ignite NESTED_TX_MODE_LABEL, NESTED_TX_MODE_COMBO_BOX, TLS_CHECK_BOX, + TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, + TLS_CA_FILE_LABEL, + TLS_CA_FILE_EDIT, //SSL_MODE_LABEL, //SSL_MODE_COMBO_BOX, //SSL_KEY_FILE_LABEL, @@ -282,8 +285,14 @@ namespace ignite /** TLS Encryption CheckBox. */ std::auto_ptr tlsCheckBox; + /** TLS Allow Invalid Hostnames CheckBox. */ + std::auto_ptr< Window > tlsAllowInvalidHostnamesCheckBox; + /** TLS Certificate Authority File label. */ + std::auto_ptr tlsCaFileLabel; + /** TLS Certificate Authority File edit. */ + std::auto_ptr tlsCaFileEdit; ///** SSL Mode label. */ //std::auto_ptr sslModeLabel; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index ff9a35948..3addd1399 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -237,6 +237,19 @@ namespace ignite tlsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "TLS", ChildId::TLS_CHECK_BOX, true); + tlsAllowInvalidHostnamesCheckBox = CreateCheckBox( + labelPosX + checkBoxSize + INTERVAL, rowPos, + checkBoxSize, ROW_HEIGHT, "TLS Allow Invalid Hostnames", + ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, false); + + rowPos += INTERVAL + ROW_HEIGHT; + + const char* val = config.GetTlsCaFile().c_str(); + tlsCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "TLS Certificate Authority:", ChildId::TLS_CA_FILE_LABEL); + tlsCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, + ChildId::TLS_CA_FILE_EDIT); + rowPos += INTERVAL + ROW_HEIGHT; //SslMode::Type sslMode = ssl::SslMode::REQUIRE; @@ -287,7 +300,9 @@ namespace ignite // rowPos += INTERVAL + ROW_HEIGHT; sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX); + "TLS/SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX); + + tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); //sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE); //sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE); @@ -475,16 +490,18 @@ namespace ignite case ChildId::TLS_CHECK_BOX: { tlsCheckBox->SetChecked(!tlsCheckBox->IsChecked()); + tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); break; } - case ChildId::SSL_MODE_COMBO_BOX: //-AL- may need to remove this later + + case ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX: { - using ssl::SslMode; + tlsAllowInvalidHostnamesCheckBox->SetChecked(!tlsAllowInvalidHostnamesCheckBox->IsChecked()); - std::string sslModeStr; - sslModeComboBox->GetText(sslModeStr); + break; + } //case ChildId::SSL_MODE_COMBO_BOX: //-AL- may need to remove this later //{ @@ -595,11 +612,18 @@ namespace ignite { bool tls = tlsCheckBox->IsChecked(); + bool tlsAllowInvalidHostnames = tlsAllowInvalidHostnamesCheckBox->IsChecked(); + std::string tlsCaStr; + tlsCaFileEdit->GetText(tlsCaStr); LOG_MSG("TLS/SSL Encryption: " << (tls ? "true" : "false")); + LOG_MSG("tls Allow Invalid Hostnames: " << (tlsAllowInvalidHostnames ? "true" : "false")); + LOG_MSG("TLS CA: " << tlsCaStr); cfg.SetTls(tls); + cfg.SetTlsAllowInvalidHostnames(tlsAllowInvalidHostnames); + cfg.SetTlsCaFile(tlsCaStr); //std::string sslModeStr; //std::string sslKeyStr; From d5ae191a7241a1a3eb21b43902d932010dda2d3c Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 09:22:54 -0800 Subject: [PATCH 013/100] Update configuration.cpp add comment to illustrate plan on what to do for the configuration window --- src/odbc/src/config/configuration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index e852bb652..d09cfa758 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -45,7 +45,7 @@ namespace ignite const bool Configuration::DefaultValue::tlsAllowInvalidHostnames = false; // needs to be set to true for SSH; TLS Allow Invalid Hostnames const std::string Configuration::DefaultValue::tlsCaFile = ""; //renamed from SSL CA file - // Schema Generation and Discovery options // need to add to UI + // Schema Generation and Discovery options // need to add to UI // I think I need a new group setting thing const std::string Configuration::DefaultValue::scanMethod = "random"; const int32_t Configuration::DefaultValue::scanLimit = 1000; const std::string Configuration::DefaultValue::schemaName = "_default"; From c06275eb37f57568009c6b175f285f855b962979 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 10:39:02 -0800 Subject: [PATCH 014/100] Update dsn_configuration_window.cpp bugfix to make tlsCheckBox and tlsAllowInvalidHostnamesCheckBox read into the saved values --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 3addd1399..45128ea42 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -235,12 +235,13 @@ namespace ignite int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; tlsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "TLS", ChildId::TLS_CHECK_BOX, true); + "TLS", ChildId::TLS_CHECK_BOX, config.IsTls()); tlsAllowInvalidHostnamesCheckBox = CreateCheckBox( labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize, ROW_HEIGHT, "TLS Allow Invalid Hostnames", - ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, false); + ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, + config.IsTlsAllowInvalidHostnames()); rowPos += INTERVAL + ROW_HEIGHT; From f311e3bc7df1fd66d7be66c8e60170a41d078c18 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 14:35:12 -0800 Subject: [PATCH 015/100] change defaultFetchSize to fetchSize in configuration.h --- .../include/ignite/odbc/config/configuration.h | 10 +++++----- src/odbc/src/config/configuration.cpp | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index c5a021c2d..695f257e7 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -137,7 +137,7 @@ namespace ignite // static const ProtocolVersion& protocolVersion; /** Default value for fetch results page size attribute. */ - static const int32_t defaultFetchSize; + static const int32_t fetchSize; /** Default value for nestedTxMode attribute. */ static const NestedTxMode::Type nestedTxMode; @@ -703,21 +703,21 @@ namespace ignite * * @return Fetch results page size. */ - int32_t GetDefaultFetchSize() const; + int32_t GetFetchSize() const; /** * Set fetch results page size. * * @param size Fetch results page size. */ - void SetDefaultFetchSize(int32_t size); + void SetFetchSize(int32_t size); /** * Check if the value set. * * @return @true if the value set. */ - bool IsDefaultFetchSizeSet() const; + bool IsFetchSizeSet() const; /** * Get argument map. @@ -816,7 +816,7 @@ namespace ignite SettableValue refreshSchema; /** Request and response page size. */ - SettableValue defaultFetchSize; + SettableValue fetchSize; }; template<> diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index d09cfa758..7ae42b733 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -65,7 +65,7 @@ namespace ignite const std::string Configuration::DefaultValue::readPreference = ""; const std::string Configuration::DefaultValue::replicaSet = ""; const bool Configuration::DefaultValue::retryReads = true; - const int32_t Configuration::DefaultValue::defaultFetchSize = 2000; + const int32_t Configuration::DefaultValue::fetchSize = 2000; const NestedTxMode::Type Configuration::DefaultValue::nestedTxMode = NestedTxMode::AI_ERROR; // remove @@ -96,7 +96,7 @@ namespace ignite scanLimit(DefaultValue::scanLimit), schemaName(DefaultValue::schemaName), refreshSchema(DefaultValue::refreshSchema), - defaultFetchSize(DefaultValue::defaultFetchSize) + fetchSize(DefaultValue::fetchSize) { // No-op. } @@ -519,19 +519,19 @@ namespace ignite return password.IsSet(); } - int32_t Configuration::GetDefaultFetchSize() const + int32_t Configuration::GetFetchSize() const { - return defaultFetchSize.GetValue(); + return fetchSize.GetValue(); } - void Configuration::SetDefaultFetchSize(int32_t size) + void Configuration::SetFetchSize(int32_t size) { - this->defaultFetchSize.SetValue(size); + this->fetchSize.SetValue(size); } - bool Configuration::IsDefaultFetchSizeSet() const + bool Configuration::IsFetchSizeSet() const { - return defaultFetchSize.IsSet(); + return fetchSize.IsSet(); } void Configuration::ToMap(ArgumentMap& res) const @@ -563,7 +563,7 @@ namespace ignite AddToMap(res, ConnectionStringParser::Key::scanLimit, scanLimit); AddToMap(res, ConnectionStringParser::Key::schemaName, schemaName); AddToMap(res, ConnectionStringParser::Key::refreshSchema, refreshSchema); - AddToMap(res, ConnectionStringParser::Key::defaultFetchSize, defaultFetchSize); + AddToMap(res, ConnectionStringParser::Key::fetchSize, fetchSize); } template<> From 8e79965abbcd7963659f191af288254878008cb3 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 14:35:36 -0800 Subject: [PATCH 016/100] change Default DSN name to DocumentDB DSN --- src/odbc/src/config/configuration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 7ae42b733..a0d11bc0b 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -31,7 +31,7 @@ namespace ignite namespace config { - const std::string Configuration::DefaultValue::dsn = "Apache Ignite DSN"; + const std::string Configuration::DefaultValue::dsn = "DocumentDB DSN"; const std::string Configuration::DefaultValue::driver = "Apache Ignite"; const std::string Configuration::DefaultValue::database = ""; // renamed from Schema const std::string Configuration::DefaultValue::address = ""; // remove From a5cd10ee247a48ae93d4c56b8fad09effcca385e Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 14:37:47 -0800 Subject: [PATCH 017/100] add App Name, Fetch Size, Read Preference, and login timeout to configuration window --- .../odbc/system/ui/dsn_configuration_window.h | 90 ++++-- .../system/ui/dsn_configuration_window.cpp | 283 +++++++++++------- 2 files changed, 242 insertions(+), 131 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index eefce6894..a5274cfdc 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -51,22 +51,30 @@ namespace ignite ADDRESS_LABEL, SCHEMA_EDIT, SCHEMA_LABEL, - PAGE_SIZE_EDIT, - PAGE_SIZE_LABEL, - DISTRIBUTED_JOINS_CHECK_BOX, - ENFORCE_JOIN_ORDER_CHECK_BOX, - REPLICATED_ONLY_CHECK_BOX, - COLLOCATED_CHECK_BOX, - LAZY_CHECK_BOX, - SKIP_REDUCER_ON_UPDATE_CHECK_BOX, + APP_NAME_EDIT, + APP_NAME_LABEL, + FETCH_SIZE_EDIT, + FETCH_SIZE_LABEL, + READ_PREFERENCE_EDIT, + READ_PREFERENCE_LABEL, + LOGIN_TIMEOUT_SEC_EDIT, + LOGIN_TIMEOUT_SEC_LABEL, + //PAGE_SIZE_EDIT, + //PAGE_SIZE_LABEL, + //DISTRIBUTED_JOINS_CHECK_BOX, + //ENFORCE_JOIN_ORDER_CHECK_BOX, + //REPLICATED_ONLY_CHECK_BOX, + //COLLOCATED_CHECK_BOX, + //LAZY_CHECK_BOX, + //SKIP_REDUCER_ON_UPDATE_CHECK_BOX, PROTOCOL_VERSION_LABEL, PROTOCOL_VERSION_COMBO_BOX, NESTED_TX_MODE_LABEL, NESTED_TX_MODE_COMBO_BOX, TLS_CHECK_BOX, TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, - TLS_CA_FILE_LABEL, TLS_CA_FILE_EDIT, + TLS_CA_FILE_LABEL, //SSL_MODE_LABEL, //SSL_MODE_COMBO_BOX, //SSL_KEY_FILE_LABEL, @@ -246,29 +254,53 @@ namespace ignite /** DSN schema edit field. */ std::auto_ptr schemaEdit; - /** DSN fetch page size edit field label. */ - std::auto_ptr pageSizeLabel; + /** Application name edit. */ + std::auto_ptr appNameEdit; + + /** Application name label. */ + std::auto_ptr appNameLabel; + + /** Login Timeout (seconds) edit. */ + std::auto_ptr loginTimeoutSecEdit; + + /** Login Timeout (seconds) label. */ + std::auto_ptr loginTimeoutSecLabel; + + /** Read preference edit. */ + std::auto_ptr readPreferenceEdit; + + /** Read preference label. */ + std::auto_ptr< Window > readPreferenceLabel; + + /** Fetch size edit. */ + std::auto_ptr fetchSizeEdit; + + /** Fetch size label. */ + std::auto_ptr fetchSizeLabel; + + ///** DSN fetch page size edit field label. */ + //std::auto_ptr pageSizeLabel; - /** DSN fetch page size edit field. */ - std::auto_ptr pageSizeEdit; + ///** DSN fetch page size edit field. */ + //std::auto_ptr pageSizeEdit; - /** Distributed joins CheckBox. */ - std::auto_ptr distributedJoinsCheckBox; + ///** Distributed joins CheckBox. */ + //std::auto_ptr distributedJoinsCheckBox; - /** Enforce join order CheckBox. */ - std::auto_ptr enforceJoinOrderCheckBox; + ///** Enforce join order CheckBox. */ + //std::auto_ptr enforceJoinOrderCheckBox; - /** Replicated only CheckBox. */ - std::auto_ptr replicatedOnlyCheckBox; + ///** Replicated only CheckBox. */ + //std::auto_ptr replicatedOnlyCheckBox; - /** Collocated CheckBox. */ - std::auto_ptr collocatedCheckBox; + ///** Collocated CheckBox. */ + //std::auto_ptr collocatedCheckBox; - /** Lazy CheckBox. */ - std::auto_ptr lazyCheckBox; + ///** Lazy CheckBox. */ + //std::auto_ptr lazyCheckBox; - /** Update on server CheckBox. */ - std::auto_ptr skipReducerOnUpdateCheckBox; + ///** Update on server CheckBox. */ + //std::auto_ptr skipReducerOnUpdateCheckBox; /** Protocol version edit field. */ std::auto_ptr protocolVersionLabel; @@ -330,11 +362,11 @@ namespace ignite /** Password edit. */ std::auto_ptr passwordEdit; - /** Nested transaction mode label. */ - std::auto_ptr nestedTxModeLabel; + ///** Nested transaction mode label. */ + //std::auto_ptr nestedTxModeLabel; - /** Nested transaction mode combo box. */ - std::auto_ptr nestedTxModeComboBox; + ///** Nested transaction mode combo box. */ + //std::auto_ptr nestedTxModeComboBox; /** Configuration. */ config::Configuration& config; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 45128ea42..33f359232 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -41,19 +41,25 @@ namespace ignite sslSettingsGroupBox(), // has a create... function defined tlsCheckBox(), authSettingsGroupBox(), - // additionalSettingsGroupBox(), + additionalSettingsGroupBox(), nameLabel(), nameEdit(), addressLabel(), addressEdit(), schemaLabel(), schemaEdit(), - pageSizeLabel(), - pageSizeEdit(), - distributedJoinsCheckBox(), - enforceJoinOrderCheckBox(), - replicatedOnlyCheckBox(), - // collocatedCheckBox(), // -AL- after commenting this out, the checkbox is intact? + appNameLabel(), + appNameEdit(), + readPreferenceLabel(), + readPreferenceEdit(), + fetchSizeLabel(), + fetchSizeEdit(), + // pageSizeLabel(), + // pageSizeEdit(), + //distributedJoinsCheckBox(), + //enforceJoinOrderCheckBox(), + //replicatedOnlyCheckBox(), + //collocatedCheckBox(), // -AL- after commenting this out, the checkbox is intact? // checkbox is created in function DsnConfigurationWindow::CreateAdditionalSettingsGroup protocolVersionLabel(), protocolVersionComboBox(), @@ -61,7 +67,7 @@ namespace ignite userEdit(), passwordLabel(), passwordEdit(), - nestedTxModeComboBox(), + //nestedTxModeComboBox(), okButton(), cancelButton(), config(config), @@ -314,7 +320,7 @@ namespace ignite int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) { - enum { LABEL_WIDTH = 130 }; + enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also change it to the same int labelPosX = posX + INTERVAL; @@ -323,28 +329,69 @@ namespace ignite int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; - ProtocolVersion version = ProtocolVersion::GetCurrent(); + //ProtocolVersion version = ProtocolVersion::GetCurrent(); - if (!version.IsSupported()) - version = ProtocolVersion::GetCurrent(); + //if (!version.IsSupported()) + // version = ProtocolVersion::GetCurrent(); int rowPos = posY + 2 * INTERVAL; - std::string tmp = common::LexicalCast(1000); - const char* val = tmp.c_str(); - pageSizeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, - ROW_HEIGHT, "Page size:", ChildId::PAGE_SIZE_LABEL); + const char* val = config.GetApplicationName().c_str(); + + appNameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, + ROW_HEIGHT, "Application Name:", ChildId::APP_NAME_LABEL); + appNameEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, ChildId::APP_NAME_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + std::string tmp = common::LexicalCast< std::string >(config.GetLoginTimeoutSeconds()); + val = tmp.c_str(); + loginTimeoutSecLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, + ROW_HEIGHT, "Login Timeout (s):", ChildId::LOGIN_TIMEOUT_SEC_LABEL); + + loginTimeoutSecEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, ChildId::LOGIN_TIMEOUT_SEC_EDIT, ES_NUMBER); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetReadPreference().c_str(); + + readPreferenceLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Read preference:", ChildId::READ_PREFERENCE_LABEL); + readPreferenceEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, + ChildId::READ_PREFERENCE_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + tmp = common::LexicalCast(config.GetFetchSize()); + val = tmp.c_str(); + fetchSizeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, + ROW_HEIGHT, "Fetch size:", ChildId::FETCH_SIZE_LABEL); - pageSizeEdit = CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT, val, ChildId::PAGE_SIZE_EDIT, ES_NUMBER); + fetchSizeEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, ChildId::FETCH_SIZE_EDIT, ES_NUMBER); rowPos += INTERVAL + ROW_HEIGHT; - nestedTxModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Nested Transaction Mode:", ChildId::NESTED_TX_MODE_LABEL); - nestedTxModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, - "", ChildId::NESTED_TX_MODE_COMBO_BOX); + //std::string tmp = common::LexicalCast< std::string >(1000); + //const char* val = tmp.c_str(); + //pageSizeLabel = + // CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + // "Page size:", ChildId::PAGE_SIZE_LABEL); + //pageSizeEdit = + // CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, + // ChildId::PAGE_SIZE_EDIT, ES_NUMBER); + + //rowPos += INTERVAL + ROW_HEIGHT; + + //nestedTxModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + // "Nested Transaction Mode:", ChildId::NESTED_TX_MODE_LABEL); + //nestedTxModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, + // "", ChildId::NESTED_TX_MODE_COMBO_BOX); + + /* int id = 0; const NestedTxMode::ModeSet& supported = NestedTxMode::GetValidValues(); @@ -353,52 +400,52 @@ namespace ignite { nestedTxModeComboBox->AddString(NestedTxMode::ToString(*it)); - /* if (*it == config.GetNestedTxMode()) - nestedTxModeComboBox->SetSelection(id); */ + if (*it == config.GetNestedTxMode()) + nestedTxModeComboBox->SetSelection(id); - ++id; - } - - nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0); + // ++id; + //} + //*/ + //nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0); - rowPos += INTERVAL + ROW_HEIGHT; + //rowPos += INTERVAL + ROW_HEIGHT; - distributedJoinsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Distributed Joins", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, false); + //distributedJoinsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + // "Distributed Joins", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, false); - enforceJoinOrderCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, - rowPos, checkBoxSize, ROW_HEIGHT, "Enforce Join Order", - ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX, false); + //enforceJoinOrderCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, + // rowPos, checkBoxSize, ROW_HEIGHT, "Enforce Join Order", + // ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX, false); - rowPos += ROW_HEIGHT; + //rowPos += ROW_HEIGHT; - replicatedOnlyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Replicated Only", ChildId::REPLICATED_ONLY_CHECK_BOX, false); - - collocatedCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize, - ROW_HEIGHT, "Collocated", ChildId::COLLOCATED_CHECK_BOX, false); + //replicatedOnlyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + // "Replicated Only", ChildId::REPLICATED_ONLY_CHECK_BOX, false); + // + //collocatedCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize, + // ROW_HEIGHT, "Collocated", ChildId::COLLOCATED_CHECK_BOX, false); - rowPos += ROW_HEIGHT; + //rowPos += ROW_HEIGHT; - lazyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Lazy", ChildId::LAZY_CHECK_BOX, false); + //lazyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + // "Lazy", ChildId::LAZY_CHECK_BOX, false); - lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5); + ////lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5); - skipReducerOnUpdateCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, - checkBoxSize, ROW_HEIGHT, "Skip reducer on update", ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX, - false); + //skipReducerOnUpdateCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, + // checkBoxSize, ROW_HEIGHT, "Skip reducer on update", ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX, + // false); - skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0); + //skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0); - rowPos += ROW_HEIGHT + INTERVAL; + //rowPos += ROW_HEIGHT + INTERVAL; additionalSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "Additional settings", ChildId::ADDITIONAL_SETTINGS_GROUP_BOX); return rowPos - posY; } - // -AL- I'm not changing this one yet. + bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) @@ -433,60 +480,60 @@ namespace ignite break; } - case ChildId::DISTRIBUTED_JOINS_CHECK_BOX: - { - distributedJoinsCheckBox->SetChecked(!distributedJoinsCheckBox->IsChecked()); + //case ChildId::DISTRIBUTED_JOINS_CHECK_BOX: + //{ + // distributedJoinsCheckBox->SetChecked(!distributedJoinsCheckBox->IsChecked()); - break; - } + // break; + //} - case ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX: - { - enforceJoinOrderCheckBox->SetChecked(!enforceJoinOrderCheckBox->IsChecked()); + //case ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX: + //{ + // enforceJoinOrderCheckBox->SetChecked(!enforceJoinOrderCheckBox->IsChecked()); - break; - } + // break; + //} - case ChildId::REPLICATED_ONLY_CHECK_BOX: - { - replicatedOnlyCheckBox->SetChecked(!replicatedOnlyCheckBox->IsChecked()); + //case ChildId::REPLICATED_ONLY_CHECK_BOX: + //{ + // replicatedOnlyCheckBox->SetChecked(!replicatedOnlyCheckBox->IsChecked()); - break; - } + // break; + //} - case ChildId::COLLOCATED_CHECK_BOX: - { - collocatedCheckBox->SetChecked(!collocatedCheckBox->IsChecked()); + //case ChildId::COLLOCATED_CHECK_BOX: + //{ + // collocatedCheckBox->SetChecked(!collocatedCheckBox->IsChecked()); - break; - } + // break; + //} - case ChildId::LAZY_CHECK_BOX: - { - lazyCheckBox->SetChecked(!lazyCheckBox->IsChecked()); + //case ChildId::LAZY_CHECK_BOX: + //{ + // lazyCheckBox->SetChecked(!lazyCheckBox->IsChecked()); - break; - } + // break; + //} - case ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX: - { - skipReducerOnUpdateCheckBox->SetChecked(!skipReducerOnUpdateCheckBox->IsChecked()); + //case ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX: + //{ + // skipReducerOnUpdateCheckBox->SetChecked(!skipReducerOnUpdateCheckBox->IsChecked()); - break; - } + // break; + //} - case ChildId::PROTOCOL_VERSION_COMBO_BOX: - { - std::string versionStr; - protocolVersionComboBox->GetText(versionStr); + //case ChildId::PROTOCOL_VERSION_COMBO_BOX: + //{ + // std::string versionStr; + // protocolVersionComboBox->GetText(versionStr); - ProtocolVersion version = ProtocolVersion::FromString(versionStr); - lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5); - skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0); - nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0); + // ProtocolVersion version = ProtocolVersion::FromString(versionStr); + // lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5); + // skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0); + // nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0); - break; - } + // break; + //} case ChildId::TLS_CHECK_BOX: { @@ -618,9 +665,9 @@ namespace ignite tlsCaFileEdit->GetText(tlsCaStr); - LOG_MSG("TLS/SSL Encryption: " << (tls ? "true" : "false")); - LOG_MSG("tls Allow Invalid Hostnames: " << (tlsAllowInvalidHostnames ? "true" : "false")); - LOG_MSG("TLS CA: " << tlsCaStr); + LOG_MSG("TLS/SSL Encryption: " << (tls ? "true" : "false")); + LOG_MSG("tls Allow Invalid Hostnames: " << (tlsAllowInvalidHostnames ? "true" : "false")); + LOG_MSG("TLS CA: " << tlsCaStr); cfg.SetTls(tls); cfg.SetTlsAllowInvalidHostnames(tlsAllowInvalidHostnames); @@ -652,18 +699,45 @@ namespace ignite void DsnConfigurationWindow::RetrieveAdditionalParameters(config::Configuration& cfg) const { - std::string pageSizeStr; - pageSizeEdit->GetText(pageSizeStr); + std::string appNameStr; + std::string readPreferenceStr; + + appNameEdit->GetText(appNameStr); + readPreferenceEdit->GetText(readPreferenceStr); + + std::string loginTimeoutSecStr; + + loginTimeoutSecEdit->GetText(loginTimeoutSecStr); + + int32_t loginTimeoutSec = + common::LexicalCast< int32_t >(loginTimeoutSecStr); + + if (loginTimeoutSec <= 0) + loginTimeoutSec = config.GetLoginTimeoutSeconds(); + + std::string fetchSizeStr; + + fetchSizeEdit->GetText(fetchSizeStr); + + int32_t fetchSize = + common::LexicalCast< int32_t >(fetchSizeStr); + + if (fetchSize <= 0) + fetchSize = config.GetFetchSize(); + + //std::string pageSizeStr; + + //pageSizeEdit->GetText(pageSizeStr); - int32_t pageSize = common::LexicalCast(pageSizeStr); + //int32_t pageSize = common::LexicalCast(pageSizeStr); - if (pageSize <= 0) - pageSize = config.GetDefaultFetchSize(); + //if (pageSize <= 0) + // pageSize = config.GetPageSize(); - std::string nestedTxModeStr; + //std::string nestedTxModeStr; - nestedTxModeComboBox->GetText(nestedTxModeStr); + //nestedTxModeComboBox->GetText(nestedTxModeStr); // unnecessary code is commented out -AL- //NestedTxMode::Type mode = NestedTxMode::FromString(nestedTxModeStr, config.GetNestedTxMode()); @@ -676,7 +750,10 @@ namespace ignite //bool skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked(); LOG_MSG("Retrieving arguments:"); - LOG_MSG("Page size: " << pageSize); + LOG_MSG("App name: " << appNameStr); + LOG_MSG("Login timeout (seconds): " << loginTimeoutSecStr); + LOG_MSG("Read preference: " << readPreferenceStr); + LOG_MSG("Fetch size: " << fetchSize); //LOG_MSG("Nested TX Mode: " << NestedTxMode::ToString(mode)); //LOG_MSG("Distributed Joins: " << (distributedJoins ? "true" : "false")); //LOG_MSG("Enforce Join Order: " << (enforceJoinOrder ? "true" : "false")); @@ -685,7 +762,9 @@ namespace ignite //LOG_MSG("Lazy: " << (lazy ? "true" : "false")); //LOG_MSG("Skip reducer on update: " << (skipReducerOnUpdate ? "true" : "false")); - cfg.SetDefaultFetchSize(pageSize); + cfg.SetApplicationName(appNameStr); + cfg.SetLoginTimeoutSeconds(loginTimeoutSec); + cfg.SetFetchSize(fetchSize); //cfg.SetNestedTxMode(mode); //cfg.SetDistributedJoins(distributedJoins); //cfg.SetEnforceJoinOrder(enforceJoinOrder); From 2bcd2a492bd69fbde5de986a03c5a407a729ba47 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 15:06:33 -0800 Subject: [PATCH 018/100] [AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h Files that had the change connection_string_parser.cpp, connection_string_parser.h, dsn_config.cpp, batch_query.cpp, data_query.cpp. --- .../ignite/odbc/config/connection_string_parser.h | 2 +- src/odbc/src/config/connection_string_parser.cpp | 6 +++--- src/odbc/src/dsn_config.cpp | 10 +++++----- src/odbc/src/query/batch_query.cpp | 2 +- src/odbc/src/query/data_query.cpp | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index 27e4f48d2..ba557d6c3 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -120,7 +120,7 @@ namespace ignite static const std::string protocolVersion; /** Connection attribute keyword for fetch results page size attribute. */ - static const std::string defaultFetchSize; + static const std::string fetchSize; /** Connection attribute keyword for sslMode attribute. */ static const std::string sslMode; diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 308bb225b..a05e2a530 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -57,7 +57,7 @@ namespace ignite const std::string ConnectionStringParser::Key::scanLimit = "scan_limit"; const std::string ConnectionStringParser::Key::schemaName = "schema_name"; const std::string ConnectionStringParser::Key::refreshSchema = "refresh_schema"; - const std::string ConnectionStringParser::Key::defaultFetchSize = "default_fetch_size"; + const std::string ConnectionStringParser::Key::fetchSize = "fetch_size"; const std::string ConnectionStringParser::Key::uid = "uid"; const std::string ConnectionStringParser::Key::pwd = "pwd"; @@ -399,7 +399,7 @@ namespace ignite cfg.SetTls(res == BoolParseResult::AI_TRUE); } - else if (lKey == Key::defaultFetchSize) + else if (lKey == Key::fetchSize) { if (!common::AllDigits(value)) { @@ -443,7 +443,7 @@ namespace ignite return; } - cfg.SetDefaultFetchSize(static_cast(numValue)); + cfg.SetFetchSize(static_cast(numValue)); } else if (lKey == Key::tlsCaFile) { diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 6526a38bd..9b02548ed 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -219,7 +219,7 @@ namespace ignite if (scanLimit.IsSet() && !config.IsScanLimitSet() && scanLimit.GetValue() > 0) - config.SetDefaultFetchSize(scanLimit.GetValue()); + config.SetFetchSize(scanLimit.GetValue()); SettableValue schemaName = ReadDsnString(dsn, ConnectionStringParser::Key::schemaName); @@ -231,11 +231,11 @@ namespace ignite if (refreshSchema.IsSet() && !config.IsSchemaRefreshSet()) config.SetSchemaRefresh(refreshSchema.GetValue()); - SettableValue defaultFetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::defaultFetchSize); + SettableValue fetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::fetchSize); - if (defaultFetchSize.IsSet() && !config.IsDefaultFetchSizeSet() - && defaultFetchSize.GetValue() > 0) - config.SetDefaultFetchSize(defaultFetchSize.GetValue()); + if (fetchSize.IsSet() && !config.IsFetchSizeSet() + && fetchSize.GetValue() > 0) + config.SetFetchSize(fetchSize.GetValue()); } } } diff --git a/src/odbc/src/query/batch_query.cpp b/src/odbc/src/query/batch_query.cpp index 7390b4f59..6a82d690e 100644 --- a/src/odbc/src/query/batch_query.cpp +++ b/src/odbc/src/query/batch_query.cpp @@ -52,7 +52,7 @@ namespace ignite if (executed) Close(); - int32_t maxPageSize = connection.GetConfiguration().GetDefaultFetchSize(); + int32_t maxPageSize = connection.GetConfiguration().GetFetchSize(); int32_t rowNum = params.GetParamSetSize(); SqlResult::Type res; diff --git a/src/odbc/src/query/data_query.cpp b/src/odbc/src/query/data_query.cpp index d5c4d6a6d..28a9ab72f 100644 --- a/src/odbc/src/query/data_query.cpp +++ b/src/odbc/src/query/data_query.cpp @@ -193,7 +193,7 @@ namespace ignite if (affected >= 0) return affected; - return connection.GetConfiguration().GetDefaultFetchSize(); + return connection.GetConfiguration().GetFetchSize(); } SqlResult::Type DataQuery::NextResultSet() @@ -320,7 +320,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); + QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetFetchSize()); QueryFetchResponse rsp(*resultPage); try @@ -361,7 +361,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); + QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetFetchSize()); QueryMoreResultsResponse rsp(*resultPage); try From eb03b9231c1d9f4d4b793fa8402d1fc2a79222eb Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 15:24:07 -0800 Subject: [PATCH 019/100] [AD-522] save read preference settings --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 33f359232..20355a1d7 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -764,6 +764,7 @@ namespace ignite cfg.SetApplicationName(appNameStr); cfg.SetLoginTimeoutSeconds(loginTimeoutSec); + cfg.SetReadPreference(readPreferenceStr); cfg.SetFetchSize(fetchSize); //cfg.SetNestedTxMode(mode); //cfg.SetDistributedJoins(distributedJoins); From 0401433e1f9756c3a02063725c4b5d04dc2dabfa Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 16:23:09 -0800 Subject: [PATCH 020/100] [AD-522] remove commented out code --- .../odbc/system/ui/dsn_configuration_window.h | 83 +----- .../system/ui/dsn_configuration_window.cpp | 272 +----------------- 2 files changed, 15 insertions(+), 340 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index a5274cfdc..27df1d8ba 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -53,20 +53,12 @@ namespace ignite SCHEMA_LABEL, APP_NAME_EDIT, APP_NAME_LABEL, - FETCH_SIZE_EDIT, - FETCH_SIZE_LABEL, - READ_PREFERENCE_EDIT, - READ_PREFERENCE_LABEL, LOGIN_TIMEOUT_SEC_EDIT, LOGIN_TIMEOUT_SEC_LABEL, - //PAGE_SIZE_EDIT, - //PAGE_SIZE_LABEL, - //DISTRIBUTED_JOINS_CHECK_BOX, - //ENFORCE_JOIN_ORDER_CHECK_BOX, - //REPLICATED_ONLY_CHECK_BOX, - //COLLOCATED_CHECK_BOX, - //LAZY_CHECK_BOX, - //SKIP_REDUCER_ON_UPDATE_CHECK_BOX, + READ_PREFERENCE_EDIT, + READ_PREFERENCE_LABEL, + FETCH_SIZE_EDIT, + FETCH_SIZE_LABEL, PROTOCOL_VERSION_LABEL, PROTOCOL_VERSION_COMBO_BOX, NESTED_TX_MODE_LABEL, @@ -75,14 +67,6 @@ namespace ignite TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, TLS_CA_FILE_EDIT, TLS_CA_FILE_LABEL, - //SSL_MODE_LABEL, - //SSL_MODE_COMBO_BOX, - //SSL_KEY_FILE_LABEL, - //SSL_KEY_FILE_EDIT, - //SSL_CERT_FILE_LABEL, - //SSL_CERT_FILE_EDIT, - //SSL_CA_FILE_LABEL, - //SSL_CA_FILE_EDIT, USER_LABEL, USER_EDIT, PASSWORD_LABEL, @@ -263,44 +247,21 @@ namespace ignite /** Login Timeout (seconds) edit. */ std::auto_ptr loginTimeoutSecEdit; - /** Login Timeout (seconds) label. */ + /** Login Timeout (seconds) label. */ std::auto_ptr loginTimeoutSecLabel; /** Read preference edit. */ std::auto_ptr readPreferenceEdit; /** Read preference label. */ - std::auto_ptr< Window > readPreferenceLabel; - - /** Fetch size edit. */ - std::auto_ptr fetchSizeEdit; - - /** Fetch size label. */ - std::auto_ptr fetchSizeLabel; - - ///** DSN fetch page size edit field label. */ - //std::auto_ptr pageSizeLabel; - - ///** DSN fetch page size edit field. */ - //std::auto_ptr pageSizeEdit; + std::auto_ptr readPreferenceLabel; - ///** Distributed joins CheckBox. */ - //std::auto_ptr distributedJoinsCheckBox; ///** Enforce join order CheckBox. */ //std::auto_ptr enforceJoinOrderCheckBox; - ///** Replicated only CheckBox. */ - //std::auto_ptr replicatedOnlyCheckBox; - ///** Collocated CheckBox. */ - //std::auto_ptr collocatedCheckBox; - ///** Lazy CheckBox. */ - //std::auto_ptr lazyCheckBox; - - ///** Update on server CheckBox. */ - //std::auto_ptr skipReducerOnUpdateCheckBox; /** Protocol version edit field. */ std::auto_ptr protocolVersionLabel; @@ -318,7 +279,7 @@ namespace ignite std::auto_ptr tlsCheckBox; /** TLS Allow Invalid Hostnames CheckBox. */ - std::auto_ptr< Window > tlsAllowInvalidHostnamesCheckBox; + std::auto_ptr tlsAllowInvalidHostnamesCheckBox; /** TLS Certificate Authority File label. */ std::auto_ptr tlsCaFileLabel; @@ -326,30 +287,6 @@ namespace ignite /** TLS Certificate Authority File edit. */ std::auto_ptr tlsCaFileEdit; - ///** SSL Mode label. */ - //std::auto_ptr sslModeLabel; - - ///** SSL Mode ComboBox. */ - //std::auto_ptr sslModeComboBox; - - ///** SSL Private Key File label. */ - //std::auto_ptr sslKeyFileLabel; - - ///** SSL Private Key File edit. */ - //std::auto_ptr sslKeyFileEdit; - - ///** SSL Certificate File label. */ - //std::auto_ptr sslCertFileLabel; - - ///** SSL Certificate File edit. */ - //std::auto_ptr sslCertFileEdit; - - ///** SSL Certificate Authority File label. */ - //std::auto_ptr sslCaFileLabel; - - ///** SSL Certificate Authority File edit. */ - //std::auto_ptr sslCaFileEdit; - /** User label. */ std::auto_ptr userLabel; @@ -362,12 +299,6 @@ namespace ignite /** Password edit. */ std::auto_ptr passwordEdit; - ///** Nested transaction mode label. */ - //std::auto_ptr nestedTxModeLabel; - - ///** Nested transaction mode combo box. */ - //std::auto_ptr nestedTxModeComboBox; - /** Configuration. */ config::Configuration& config; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 20355a1d7..fe7e0239b 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -54,20 +54,12 @@ namespace ignite readPreferenceEdit(), fetchSizeLabel(), fetchSizeEdit(), - // pageSizeLabel(), - // pageSizeEdit(), - //distributedJoinsCheckBox(), - //enforceJoinOrderCheckBox(), - //replicatedOnlyCheckBox(), - //collocatedCheckBox(), // -AL- after commenting this out, the checkbox is intact? - // checkbox is created in function DsnConfigurationWindow::CreateAdditionalSettingsGroup protocolVersionLabel(), protocolVersionComboBox(), userLabel(), userEdit(), passwordLabel(), passwordEdit(), - //nestedTxModeComboBox(), okButton(), cancelButton(), config(config), @@ -227,8 +219,7 @@ namespace ignite int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) { // TODO: rename function name from Ssl to TLS after UI works - //using ssl::SslMode; - + enum { LABEL_WIDTH = 120 }; int labelPosX = posX + INTERVAL; @@ -259,62 +250,11 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - //SslMode::Type sslMode = ssl::SslMode::REQUIRE; - //std::string sslModeStr = SslMode::ToString(sslMode); - - //const char* val = sslModeStr.c_str(); - - //sslModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - // "SSL Mode:", ChildId::SSL_MODE_LABEL); - //sslModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, - // "", ChildId::SSL_MODE_COMBO_BOX); - - //sslModeComboBox->AddString("disable"); - //sslModeComboBox->AddString("require"); - - //sslModeComboBox->SetSelection(sslMode); // set default value to require -AL- - - //rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight I believe - - //val = config.GetTlsCaFile().c_str(); - //sslKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - // "SSL Private Key:", ChildId::SSL_KEY_FILE_LABEL); - //sslKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - // val, ChildId::SSL_KEY_FILE_EDIT); - - //SHAutoComplete(sslKeyFileEdit->GetHandle(), SHACF_DEFAULT); - - //rowPos += INTERVAL + ROW_HEIGHT; - - //val = config.GetTlsCaFile().c_str(); - //sslCertFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - // "SSL Certificate:", ChildId::SSL_CERT_FILE_LABEL); - //sslCertFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - // val, ChildId::SSL_CERT_FILE_EDIT); - - //SHAutoComplete(sslCertFileEdit->GetHandle(), SHACF_DEFAULT); - - // rowPos += INTERVAL + ROW_HEIGHT; - - //val = config.GetTlsCaFile().c_str(); - //sslCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - // "SSL Certificate Authority:", ChildId::SSL_CA_FILE_LABEL); - //sslCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - // val, ChildId::SSL_CA_FILE_EDIT); - - //SHAutoComplete(sslCaFileEdit->GetHandle(), SHACF_DEFAULT); - - // rowPos += INTERVAL + ROW_HEIGHT; - sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "TLS/SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX); tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); - //sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - //sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - //sslCaFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - return rowPos - posY; } @@ -329,11 +269,6 @@ namespace ignite int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; - //ProtocolVersion version = ProtocolVersion::GetCurrent(); - - //if (!version.IsSupported()) - // version = ProtocolVersion::GetCurrent(); - int rowPos = posY + 2 * INTERVAL; const char* val = config.GetApplicationName().c_str(); @@ -374,72 +309,6 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - //std::string tmp = common::LexicalCast< std::string >(1000); - //const char* val = tmp.c_str(); - //pageSizeLabel = - // CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - // "Page size:", ChildId::PAGE_SIZE_LABEL); - - //pageSizeEdit = - // CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, - // ChildId::PAGE_SIZE_EDIT, ES_NUMBER); - - //rowPos += INTERVAL + ROW_HEIGHT; - - //nestedTxModeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - // "Nested Transaction Mode:", ChildId::NESTED_TX_MODE_LABEL); - //nestedTxModeComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, - // "", ChildId::NESTED_TX_MODE_COMBO_BOX); - - /* - int id = 0; - - const NestedTxMode::ModeSet& supported = NestedTxMode::GetValidValues(); - - for (NestedTxMode::ModeSet::const_iterator it = supported.begin(); it != supported.end(); ++it) - { - nestedTxModeComboBox->AddString(NestedTxMode::ToString(*it)); - - if (*it == config.GetNestedTxMode()) - nestedTxModeComboBox->SetSelection(id); - - // ++id; - //} - //*/ - //nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0); - - //rowPos += INTERVAL + ROW_HEIGHT; - - //distributedJoinsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - // "Distributed Joins", ChildId::DISTRIBUTED_JOINS_CHECK_BOX, false); - - //enforceJoinOrderCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, - // rowPos, checkBoxSize, ROW_HEIGHT, "Enforce Join Order", - // ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX, false); - - //rowPos += ROW_HEIGHT; - - //replicatedOnlyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - // "Replicated Only", ChildId::REPLICATED_ONLY_CHECK_BOX, false); - // - //collocatedCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, checkBoxSize, - // ROW_HEIGHT, "Collocated", ChildId::COLLOCATED_CHECK_BOX, false); - - //rowPos += ROW_HEIGHT; - - //lazyCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - // "Lazy", ChildId::LAZY_CHECK_BOX, false); - - ////lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5); - - //skipReducerOnUpdateCheckBox = CreateCheckBox(labelPosX + checkBoxSize + INTERVAL, rowPos, - // checkBoxSize, ROW_HEIGHT, "Skip reducer on update", ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX, - // false); - - //skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0); - - //rowPos += ROW_HEIGHT + INTERVAL; - additionalSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "Additional settings", ChildId::ADDITIONAL_SETTINGS_GROUP_BOX); @@ -480,61 +349,6 @@ namespace ignite break; } - //case ChildId::DISTRIBUTED_JOINS_CHECK_BOX: - //{ - // distributedJoinsCheckBox->SetChecked(!distributedJoinsCheckBox->IsChecked()); - - // break; - //} - - //case ChildId::ENFORCE_JOIN_ORDER_CHECK_BOX: - //{ - // enforceJoinOrderCheckBox->SetChecked(!enforceJoinOrderCheckBox->IsChecked()); - - // break; - //} - - //case ChildId::REPLICATED_ONLY_CHECK_BOX: - //{ - // replicatedOnlyCheckBox->SetChecked(!replicatedOnlyCheckBox->IsChecked()); - - // break; - //} - - //case ChildId::COLLOCATED_CHECK_BOX: - //{ - // collocatedCheckBox->SetChecked(!collocatedCheckBox->IsChecked()); - - // break; - //} - - //case ChildId::LAZY_CHECK_BOX: - //{ - // lazyCheckBox->SetChecked(!lazyCheckBox->IsChecked()); - - // break; - //} - - //case ChildId::SKIP_REDUCER_ON_UPDATE_CHECK_BOX: - //{ - // skipReducerOnUpdateCheckBox->SetChecked(!skipReducerOnUpdateCheckBox->IsChecked()); - - // break; - //} - - //case ChildId::PROTOCOL_VERSION_COMBO_BOX: - //{ - // std::string versionStr; - // protocolVersionComboBox->GetText(versionStr); - - // ProtocolVersion version = ProtocolVersion::FromString(versionStr); - // lazyCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_1_5); - // skipReducerOnUpdateCheckBox->SetEnabled(version >= ProtocolVersion::VERSION_2_3_0); - // nestedTxModeComboBox->SetEnabled(version >= ProtocolVersion::VERSION_2_5_0); - - // break; - //} - case ChildId::TLS_CHECK_BOX: { tlsCheckBox->SetChecked(!tlsCheckBox->IsChecked()); @@ -551,21 +365,9 @@ namespace ignite break; } - //case ChildId::SSL_MODE_COMBO_BOX: //-AL- may need to remove this later - //{ - // using ssl::SslMode; - - // std::string sslModeStr; - // sslModeComboBox->GetText(sslModeStr); - - // SslMode::Type sslMode = SslMode::FromString(sslModeStr, SslMode::DISABLE); - // sslKeyFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - // sslCertFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - // sslCaFileEdit->SetEnabled(sslMode != SslMode::DISABLE); - - // break; - //} + break; + } default: return false; @@ -673,28 +475,6 @@ namespace ignite cfg.SetTlsAllowInvalidHostnames(tlsAllowInvalidHostnames); cfg.SetTlsCaFile(tlsCaStr); - //std::string sslModeStr; - //std::string sslKeyStr; - //std::string sslCertStr; - //std::string sslCaStr; - - ////sslModeComboBox->GetText(sslModeStr); - ////sslKeyFileEdit->GetText(sslKeyStr); - ////sslCertFileEdit->GetText(sslCertStr); - ////sslCaFileEdit->GetText(sslCaStr); - - //LOG_MSG("Retrieving arguments:"); - //LOG_MSG("SSL Mode: " << sslModeStr); - //LOG_MSG("SSL Key: " << sslKeyStr); - //LOG_MSG("SSL Certificate: " << sslCertStr); - //LOG_MSG("SSL CA: " << sslCaStr); - - //ssl::SslMode::Type sslMode = ssl::SslMode::FromString(sslModeStr, ssl::SslMode::DISABLE); - - //cfg.SetSslMode(sslMode); - //cfg.SetSslKeyFile(sslKeyStr); - //cfg.SetSslCertFile(sslCertStr); - //cfg.SetTlsCaFile(sslCaStr); } void DsnConfigurationWindow::RetrieveAdditionalParameters(config::Configuration& cfg) const @@ -726,53 +506,17 @@ namespace ignite if (fetchSize <= 0) fetchSize = config.GetFetchSize(); - //std::string pageSizeStr; - - //pageSizeEdit->GetText(pageSizeStr); - - //int32_t pageSize = common::LexicalCast(pageSizeStr); - - //if (pageSize <= 0) - // pageSize = config.GetPageSize(); - - //std::string nestedTxModeStr; - - //nestedTxModeComboBox->GetText(nestedTxModeStr); - - // unnecessary code is commented out -AL- - //NestedTxMode::Type mode = NestedTxMode::FromString(nestedTxModeStr, config.GetNestedTxMode()); - - //bool distributedJoins = distributedJoinsCheckBox->IsChecked(); - //bool enforceJoinOrder = enforceJoinOrderCheckBox->IsChecked(); - //bool replicatedOnly = replicatedOnlyCheckBox->IsChecked(); - //bool collocated = collocatedCheckBox->IsChecked(); - //bool lazy = lazyCheckBox->IsChecked(); - //bool skipReducerOnUpdate = skipReducerOnUpdateCheckBox->IsChecked(); - LOG_MSG("Retrieving arguments:"); - LOG_MSG("App name: " << appNameStr); - LOG_MSG("Login timeout (seconds): " << loginTimeoutSecStr); - LOG_MSG("Read preference: " << readPreferenceStr); - LOG_MSG("Fetch size: " << fetchSize); - //LOG_MSG("Nested TX Mode: " << NestedTxMode::ToString(mode)); - //LOG_MSG("Distributed Joins: " << (distributedJoins ? "true" : "false")); - //LOG_MSG("Enforce Join Order: " << (enforceJoinOrder ? "true" : "false")); - //LOG_MSG("Replicated only: " << (replicatedOnly ? "true" : "false")); - //LOG_MSG("Collocated: " << (collocated ? "true" : "false")); - //LOG_MSG("Lazy: " << (lazy ? "true" : "false")); - //LOG_MSG("Skip reducer on update: " << (skipReducerOnUpdate ? "true" : "false")); + LOG_MSG("App name: " << appNameStr); + LOG_MSG("Login timeout (seconds): " << loginTimeoutSecStr); + LOG_MSG("Read preference: " << readPreferenceStr); + LOG_MSG("Fetch size: " << fetchSize); cfg.SetApplicationName(appNameStr); cfg.SetLoginTimeoutSeconds(loginTimeoutSec); cfg.SetReadPreference(readPreferenceStr); cfg.SetFetchSize(fetchSize); - //cfg.SetNestedTxMode(mode); - //cfg.SetDistributedJoins(distributedJoins); - //cfg.SetEnforceJoinOrder(enforceJoinOrder); - //cfg.SetReplicatedOnly(replicatedOnly); - //cfg.SetCollocated(collocated); - //cfg.SetLazy(lazy); - //cfg.SetSkipReducerOnUpdate(skipReducerOnUpdate); + } } } From 7e5288d303a5c4453477e3dc92fd8ab52a134155 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 19 Jan 2022 16:23:53 -0800 Subject: [PATCH 021/100] [AD-522] Implement replicaSet and retryReads on Configuration Window --- .../odbc/system/ui/dsn_configuration_window.h | 15 ++++++++-- .../system/ui/dsn_configuration_window.cpp | 28 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 27df1d8ba..ad8c45e99 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -57,6 +57,9 @@ namespace ignite LOGIN_TIMEOUT_SEC_LABEL, READ_PREFERENCE_EDIT, READ_PREFERENCE_LABEL, + REPLICA_SET_EDIT, + REPLICA_SET_LABEL, + RETRY_READS_CHECK_BOX, FETCH_SIZE_EDIT, FETCH_SIZE_LABEL, PROTOCOL_VERSION_LABEL, @@ -256,12 +259,20 @@ namespace ignite /** Read preference label. */ std::auto_ptr readPreferenceLabel; + /** Replica Set edit. */ + std::auto_ptr< Window > replicaSetEdit; - ///** Enforce join order CheckBox. */ - //std::auto_ptr enforceJoinOrderCheckBox; + /** Replica Set label. */ + std::auto_ptr< Window > replicaSetLabel; + /** Retry reads CheckBox. */ + std::auto_ptr retryReadsCheckBox; + /** Fetch size edit. */ + std::auto_ptr fetchSizeEdit; + /** Fetch size label. */ + std::auto_ptr fetchSizeLabel; /** Protocol version edit field. */ std::auto_ptr protocolVersionLabel; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index fe7e0239b..9a9f7e66d 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -52,6 +52,9 @@ namespace ignite appNameEdit(), readPreferenceLabel(), readPreferenceEdit(), + replicaSetLabel(), + replicaSetEdit(), + retryReadsCheckBox(), fetchSizeLabel(), fetchSizeEdit(), protocolVersionLabel(), @@ -299,6 +302,20 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; + val = config.GetReplicaSet().c_str(); + + replicaSetLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Replica Set:", ChildId::REPLICA_SET_LABEL); + replicaSetEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, + ChildId::REPLICA_SET_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + retryReadsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + "Retry Reads", ChildId::RETRY_READS_CHECK_BOX, config.IsRetryReads()); + + rowPos += INTERVAL + ROW_HEIGHT; + tmp = common::LexicalCast(config.GetFetchSize()); val = tmp.c_str(); fetchSizeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, @@ -365,6 +382,9 @@ namespace ignite break; } + case ChildId::RETRY_READS_CHECK_BOX: + { + retryReadsCheckBox->SetChecked(!retryReadsCheckBox->IsChecked()); break; } @@ -482,9 +502,13 @@ namespace ignite std::string appNameStr; std::string readPreferenceStr; + std::string replicaSetStr; appNameEdit->GetText(appNameStr); readPreferenceEdit->GetText(readPreferenceStr); + replicaSetEdit->GetText(replicaSetStr); + + bool retryReads = retryReadsCheckBox->IsChecked(); std::string loginTimeoutSecStr; @@ -510,11 +534,15 @@ namespace ignite LOG_MSG("App name: " << appNameStr); LOG_MSG("Login timeout (seconds): " << loginTimeoutSecStr); LOG_MSG("Read preference: " << readPreferenceStr); + LOG_MSG("Replica Set: " << replicaSetStr); + LOG_MSG("Retry reads: " << (retryReads ? "true" : "false")); LOG_MSG("Fetch size: " << fetchSize); cfg.SetApplicationName(appNameStr); cfg.SetLoginTimeoutSeconds(loginTimeoutSec); cfg.SetReadPreference(readPreferenceStr); + cfg.SetReplicaSet(replicaSetStr); + cfg.SetRetryReads(retryReads); cfg.SetFetchSize(fetchSize); } From 27b72e14aefae42457d579961ae734d2c4fdb789 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Wed, 19 Jan 2022 17:08:11 -0800 Subject: [PATCH 022/100] [AD-517] Re-enable unit tests - WIP - still need to cleanup --- src/odbc-test/CMakeLists.txt | 43 +- src/odbc-test/CMakeLists.txt.bak | 113 +++++ src/odbc-test/src/configuration_test.cpp | 469 +++++++++++------- .../ignite/odbc/config/configuration.h | 42 +- .../system/ui/dsn_configuration_window.cpp | 4 +- src/odbc/src/config/configuration.cpp | 26 +- .../src/config/connection_string_parser.cpp | 38 +- src/odbc/src/connection.cpp | 11 +- src/odbc/src/dsn_config.cpp | 11 - 9 files changed, 458 insertions(+), 299 deletions(-) create mode 100644 src/odbc-test/CMakeLists.txt.bak diff --git a/src/odbc-test/CMakeLists.txt b/src/odbc-test/CMakeLists.txt index 11aa3a60c..ae4ab2274 100644 --- a/src/odbc-test/CMakeLists.txt +++ b/src/odbc-test/CMakeLists.txt @@ -32,6 +32,7 @@ include_directories(include ../odbc/include ../network/include) set(SOURCES src/dummy_test.cpp + src/configuration_test.cpp # TODO uncomment/rework the tests after get some connectivity and functionalities working. # src/teamcity/teamcity_boost.cpp # src/teamcity/teamcity_messages.cpp @@ -71,27 +72,27 @@ set(SOURCES # src/streaming_test.cpp # src/cursor_binding_test.cpp # src/test_server.cpp -# ../odbc/src/log.cpp -# ../odbc/src/cursor.cpp -# ../odbc/src/diagnostic/diagnostic_record.cpp -# ../odbc/src/diagnostic/diagnostic_record_storage.cpp -# ../odbc/src/config/config_tools.cpp -# ../odbc/src/config/configuration.cpp -# ../odbc/src/config/connection_info.cpp -# ../odbc/src/config/connection_string_parser.cpp -# ../odbc/src/app/application_data_buffer.cpp -# ../odbc/src/ssl_mode.cpp -# ../odbc/src/sql/sql_parser.cpp -# ../odbc/src/sql/sql_lexer.cpp -# ../odbc/src/sql/sql_set_streaming_command.cpp -# ../odbc/src/sql/sql_utils.cpp -# ../odbc/src/row.cpp -# ../odbc/src/protocol_version.cpp -# ../odbc/src/column.cpp -# ../odbc/src/common_types.cpp -# ../odbc/src/utility.cpp -# ../odbc/src/result_page.cpp -# ../odbc/src/nested_tx_mode.cpp + ../odbc/src/log.cpp + ../odbc/src/cursor.cpp + ../odbc/src/diagnostic/diagnostic_record.cpp + ../odbc/src/diagnostic/diagnostic_record_storage.cpp + ../odbc/src/config/config_tools.cpp + ../odbc/src/config/configuration.cpp + ../odbc/src/config/connection_info.cpp + ../odbc/src/config/connection_string_parser.cpp + ../odbc/src/app/application_data_buffer.cpp + ../odbc/src/ssl_mode.cpp + ../odbc/src/sql/sql_parser.cpp + ../odbc/src/sql/sql_lexer.cpp + ../odbc/src/sql/sql_set_streaming_command.cpp + ../odbc/src/sql/sql_utils.cpp + ../odbc/src/row.cpp + ../odbc/src/protocol_version.cpp + ../odbc/src/column.cpp + ../odbc/src/common_types.cpp + ../odbc/src/utility.cpp + ../odbc/src/result_page.cpp + ../odbc/src/nested_tx_mode.cpp ) add_executable(${TARGET} ${SOURCES}) diff --git a/src/odbc-test/CMakeLists.txt.bak b/src/odbc-test/CMakeLists.txt.bak new file mode 100644 index 000000000..0d30d5356 --- /dev/null +++ b/src/odbc-test/CMakeLists.txt.bak @@ -0,0 +1,113 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +project(ignite-odbc-tests) + +set(TARGET ${PROJECT_NAME}) + +if (WIN32) + set(Boost_USE_STATIC_LIBS ON) +endif() + +find_package(Boost 1.53 REQUIRED COMPONENTS unit_test_framework chrono thread system regex) + +find_package(ODBC REQUIRED) + +include_directories(SYSTEM ${ODBC_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${JNI_INCLUDE_DIRS}) +include_directories(include ../odbc/include ../network/include) + +set(SOURCES + src/dummy_test.cpp + src/configuration_test.cpp +# TODO uncomment/rework the tests after get some connectivity and functionalities working. +# src/teamcity/teamcity_boost.cpp +# src/teamcity/teamcity_messages.cpp +# src/parser_test.cpp +# src/cursor_test.cpp +# src/connection_info_test.cpp +# src/connection_test.cpp +# src/application_data_buffer_test.cpp +# src/column_test.cpp +# src/configuration_test.cpp +# src/row_test.cpp +# src/meta_queries_test.cpp +# src/utility_test.cpp +# src/queries_test.cpp +# src/queries_ssl_test.cpp +# src/test_utils.cpp +# src/sql_test_suite_fixture.cpp +# src/sql_string_functions_test.cpp +# src/sql_numeric_functions_test.cpp +# src/sql_aggregate_functions_test.cpp +# src/sql_system_functions_test.cpp +# src/sql_esc_convert_function_test.cpp +# src/sql_operators_test.cpp +# src/sql_value_expressions_test.cpp +# src/sql_types_test.cpp +# src/sql_date_time_functions_test.cpp +# src/sql_outer_join_test.cpp +# src/sql_get_info_test.cpp +# src/api_robustness_test.cpp +# src/attributes_test.cpp +# src/errors_test.cpp +# src/odbc_test_suite.cpp +# src/types_test.cpp +# src/transaction_test.cpp +# src/authentication_test.cpp +# src/sql_parsing_test.cpp +# src/streaming_test.cpp +# src/cursor_binding_test.cpp +# src/test_server.cpp +# ../odbc/src/log.cpp +# ../odbc/src/cursor.cpp +# ../odbc/src/diagnostic/diagnostic_record.cpp +# ../odbc/src/diagnostic/diagnostic_record_storage.cpp +# ../odbc/src/config/config_tools.cpp +# ../odbc/src/config/configuration.cpp +# ../odbc/src/config/connection_info.cpp +# ../odbc/src/config/connection_string_parser.cpp +# ../odbc/src/app/application_data_buffer.cpp +# ../odbc/src/ssl_mode.cpp +# ../odbc/src/sql/sql_parser.cpp +# ../odbc/src/sql/sql_lexer.cpp +# ../odbc/src/sql/sql_set_streaming_command.cpp +# ../odbc/src/sql/sql_utils.cpp +# ../odbc/src/row.cpp +# ../odbc/src/protocol_version.cpp +# ../odbc/src/column.cpp +# ../odbc/src/common_types.cpp +# ../odbc/src/utility.cpp +# ../odbc/src/result_page.cpp +# ../odbc/src/nested_tx_mode.cpp + ) + +add_executable(${TARGET} ${SOURCES}) + +target_link_libraries(${TARGET} ${Boost_LIBRARIES} ignite ${ODBC_LIBRARY}) +target_code_coverage(${TARGET} PUBLIC AUTO ALL) + +if (WIN32) + remove_definitions(-DUNICODE=1) +else() + add_definitions(-DBOOST_TEST_DYN_LINK) +endif() + +set(TEST_TARGET IgniteOdbcTest) + +add_test(NAME ${TEST_TARGET} COMMAND ${TARGET} --catch_system_errors=no --log_level=all) + +set_tests_properties(${TEST_TARGET} PROPERTIES ENVIRONMENT IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH=${PROJECT_SOURCE_DIR}/config) diff --git a/src/odbc-test/src/configuration_test.cpp b/src/odbc-test/src/configuration_test.cpp index b6f793def..9d21d1f60 100644 --- a/src/odbc-test/src/configuration_test.cpp +++ b/src/odbc-test/src/configuration_test.cpp @@ -32,22 +32,34 @@ using namespace ignite::odbc::config; namespace { - const std::string testDriverName = "Ignite Driver"; - const std::string testServerHost = "testhost.com"; - const uint16_t testServerPort = 4242; - const std::string testSchemaName = "TestSchema"; - const std::string testDsn = "Ignite DSN"; - const int32_t testPageSize = 4321; - const bool testDistributedJoins = true; - const bool testEnforceJoinOrder = true; - const bool testReplicatedOnly = true; - const bool testCollocated = true; - const bool testLazy = true; - const bool testSkipReducerOnUpdate = true; - - const std::string testAddressStr = testServerHost + ':' + ignite::common::LexicalCast(testServerPort); - - const EndPoint testAddress(testServerHost, testServerPort, 10); + const std::string testDriverName = "Test Driver"; + const std::string testDsn = "Test DSN"; + const std::string testHostname = "testhost.com"; + const uint16_t testServerPort = 27019; + const std::string testDatabaseName = "testDatabase"; + const std::string testUsername = "testUser"; + const std::string testPassword = "testPassword"; + const std::string testAppName = "testAppName"; + const int32_t testLoginTimeoutSec = 3000; + const std::string testReadPreference = "primaryPreferred"; + const std::string testReplicaSet = "rs0"; + const bool testRetryReads = false; + const bool testTlsFlag = false; + const bool testTlsAllowInvalidHostnamesFlag = true; + const std::string testTlsCaFile = "/path/to/cafile"; + const std::string testSshUser = "testEc2User"; + const std::string testSshHost = "testsshhost.com"; + const std::string testSshPrivateKeyFile = "/path/to/keyfile"; + const std::string testSshPrivateKeyPassphrase = "testPassphrase"; + const bool testSshStrictHostKeyCheckingFlag = false; + const std::string testSshKnownHostsFile = "/path/to/knownhostsfile"; + const std::string testScanMethod = "idForward"; + const int32_t testScanLimit = 3000; + const std::string testSchemaName = "testSchemaName"; + const bool testRefreshSchemaFlag = true; + const int32_t testDefaultFetchSize = 4321; + + const EndPoint testAddress(testHostname, testServerPort, 10); } const char* BoolToStr(bool val, bool lowerCase = true) @@ -99,28 +111,8 @@ void CheckValidAddress(const char* connectStr, const EndPoint& endPoint) ParseValidConnectString(connectStr, cfg); - const std::vector& addrs = cfg.GetAddresses(); - - BOOST_REQUIRE_EQUAL(addrs.size(), 1); - BOOST_CHECK_EQUAL(addrs[0].host, endPoint.host); - BOOST_CHECK_EQUAL(addrs[0].port, endPoint.port); -} - -void CheckValidAddresses(const char* connectStr, const std::vector& endPoints) -{ - Configuration cfg; - - ParseValidConnectString(connectStr, cfg); - - const std::vector& addrs = cfg.GetAddresses(); - - BOOST_REQUIRE_EQUAL(addrs.size(), endPoints.size()); - - for (size_t i = 0; i < addrs.size(); ++i) - { - BOOST_CHECK_EQUAL(addrs[i].host, endPoints[i].host); - BOOST_CHECK_EQUAL(addrs[i].port, endPoints[i].port); - } + BOOST_CHECK_EQUAL(cfg.GetHostname(), endPoint.host); + BOOST_CHECK_EQUAL(cfg.GetTcpPort(), endPoint.port); } void CheckValidProtocolVersion(const char* connectStr, ProtocolVersion version) @@ -129,7 +121,7 @@ void CheckValidProtocolVersion(const char* connectStr, ProtocolVersion version) ParseValidConnectString(connectStr, cfg); - BOOST_CHECK(cfg.GetProtocolVersion() == version); + //BOOST_CHECK(cfg.GetProtocolVersion() == version); } void CheckSupportedProtocolVersion(const char* connectStr) @@ -138,7 +130,7 @@ void CheckSupportedProtocolVersion(const char* connectStr) ParseValidConnectString(connectStr, cfg); - BOOST_CHECK(cfg.GetProtocolVersion().IsSupported()); + //BOOST_CHECK(cfg.GetProtocolVersion().IsSupported()); } void CheckInvalidProtocolVersion(const char* connectStr) @@ -147,7 +139,7 @@ void CheckInvalidProtocolVersion(const char* connectStr) ParseConnectStringWithError(connectStr, cfg); - BOOST_CHECK(cfg.GetProtocolVersion() == Configuration::DefaultValue::protocolVersion); + //BOOST_CHECK(cfg.GetProtocolVersion() == Configuration::DefaultValue::protocolVersion); } void CheckValidBoolValue(const std::string& connectStr, const std::string& key, bool val) @@ -179,39 +171,60 @@ void CheckInvalidBoolValue(const std::string& connectStr, const std::string& key void CheckConnectionConfig(const Configuration& cfg) { BOOST_CHECK_EQUAL(cfg.GetDriver(), testDriverName); - BOOST_CHECK_EQUAL(cfg.GetSchema(), testSchemaName); - BOOST_CHECK_EQUAL(cfg.GetPageSize(), testPageSize); - BOOST_CHECK_EQUAL(cfg.IsDistributedJoins(), testDistributedJoins); - BOOST_CHECK_EQUAL(cfg.IsEnforceJoinOrder(), testEnforceJoinOrder); - BOOST_CHECK_EQUAL(cfg.IsReplicatedOnly(), testReplicatedOnly); - BOOST_CHECK_EQUAL(cfg.IsCollocated(), testCollocated); - BOOST_CHECK_EQUAL(cfg.IsLazy(), testLazy); - BOOST_CHECK_EQUAL(cfg.IsSkipReducerOnUpdate(), testSkipReducerOnUpdate); + BOOST_CHECK_EQUAL(cfg.GetDatabase(), testDatabaseName); + BOOST_CHECK_EQUAL(cfg.GetHostname(), testHostname); + BOOST_CHECK_EQUAL(cfg.GetTcpPort(), testServerPort); + BOOST_CHECK_EQUAL(cfg.GetUser(), testUsername); + BOOST_CHECK_EQUAL(cfg.GetPassword(), testPassword); + BOOST_CHECK_EQUAL(cfg.GetApplicationName(), testAppName); + BOOST_CHECK_EQUAL(cfg.GetLoginTimeoutSeconds(), testLoginTimeoutSec); + BOOST_CHECK_EQUAL(cfg.GetReadPreference(), testReadPreference); + BOOST_CHECK_EQUAL(cfg.GetReplicaSet(), testReplicaSet); + BOOST_CHECK_EQUAL(cfg.IsRetryReads(), testRetryReads); + BOOST_CHECK_EQUAL(cfg.IsTls(), testTlsFlag); + BOOST_CHECK_EQUAL(cfg.IsTlsAllowInvalidHostnames(), testTlsAllowInvalidHostnamesFlag); + BOOST_CHECK_EQUAL(cfg.GetTlsCaFile(), testTlsCaFile); + BOOST_CHECK_EQUAL(cfg.GetSshUser(), testSshUser); + BOOST_CHECK_EQUAL(cfg.GetSshHost(), testSshHost); + BOOST_CHECK_EQUAL(cfg.GetSshPrivateKeyFile(), testSshPrivateKeyFile); + BOOST_CHECK_EQUAL(cfg.GetSshPrivateKeyPassphrase(), testSshPrivateKeyPassphrase); + BOOST_CHECK_EQUAL(cfg.IsSshStrictHostKeyChecking(), testSshStrictHostKeyCheckingFlag); + BOOST_CHECK_EQUAL(cfg.GetSshKnownHostsFile(), testSshKnownHostsFile); + BOOST_CHECK_EQUAL(cfg.GetScanMethod(), testScanMethod); + BOOST_CHECK_EQUAL(cfg.GetScanLimit(), testScanLimit); + BOOST_CHECK_EQUAL(cfg.GetSchemaName(), testSchemaName); + BOOST_CHECK_EQUAL(cfg.IsSchemaRefresh(), testRefreshSchemaFlag); + BOOST_CHECK_EQUAL(cfg.GetDefaultFetchSize(), testDefaultFetchSize); BOOST_CHECK(!cfg.IsDsnSet()); - BOOST_CHECK(!cfg.IsHostSet()); - BOOST_CHECK(!cfg.IsTcpPortSet()); - - BOOST_CHECK(cfg.IsAddressesSet()); - - const std::vector& addrs = cfg.GetAddresses(); - - BOOST_REQUIRE(!addrs.empty()); - BOOST_CHECK_EQUAL(addrs[0].host, testAddress.host); - BOOST_CHECK_EQUAL(addrs[0].port, testAddress.port); std::stringstream constructor; - constructor << "address=" << testAddressStr << ';' - << "collocated=" << BoolToStr(testCollocated) << ';' - << "distributed_joins=" << BoolToStr(testDistributedJoins) << ';' + constructor << "app_name=" << testAppName << ';' + << "database=" << testDatabaseName << ';' + << "default_fetch_size=" << testDefaultFetchSize << ';' << "driver={" << testDriverName << "};" - << "enforce_join_order=" << BoolToStr(testEnforceJoinOrder) << ';' - << "lazy=" << BoolToStr(testLazy) << ';' - << "page_size=" << testPageSize << ';' - << "replicated_only=" << BoolToStr(testReplicatedOnly) << ';' - << "schema=" << testSchemaName << ';' - << "skip_reducer_on_update=" << BoolToStr(testReplicatedOnly) << ';'; + << "hostname=" << testHostname << ';' + << "login_timeout_sec=" << testLoginTimeoutSec << ';' + << "password=" << testPassword << ';' + << "port=" << testServerPort << ';' + << "read_preference=" << testReadPreference << ';' + << "refresh_schema=" << BoolToStr(testRefreshSchemaFlag) << ';' + << "replica_set=" << testReplicaSet << ';' + << "retry_reads=" << BoolToStr(testRetryReads) << ';' + << "scan_limit=" << testScanLimit << ';' + << "scan_method=" << testScanMethod << ';' + << "schema_name=" << testSchemaName << ';' + << "ssh_host=" << testSshHost << ';' + << "ssh_known_hosts_file=" << testSshKnownHostsFile << ';' + << "ssh_private_key_file=" << testSshPrivateKeyFile << ';' + << "ssh_private_key_passphrase=" << testSshPrivateKeyPassphrase << ';' + << "ssh_strict_host_key_checking=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' + << "ssh_user=" << testSshUser << ';' + << "tls=" << BoolToStr(testTlsFlag) << ';' + << "tls_allow_invalid_hostnames=" << BoolToStr(testTlsAllowInvalidHostnamesFlag) << ';' + << "tls_ca_file=" << testTlsCaFile << ';' + << "user=" << testUsername << ';'; const std::string& expectedStr = constructor.str(); @@ -222,35 +235,62 @@ void CheckDsnConfig(const Configuration& cfg) { BOOST_CHECK_EQUAL(cfg.GetDriver(), testDriverName); BOOST_CHECK_EQUAL(cfg.GetDsn(), testDsn); - BOOST_CHECK_EQUAL(cfg.GetSchema(), Configuration::DefaultValue::schema); - BOOST_CHECK_EQUAL(cfg.GetHost(), std::string()); + BOOST_CHECK_EQUAL(cfg.GetDatabase(), Configuration::DefaultValue::database); + BOOST_CHECK_EQUAL(cfg.GetHostname(), Configuration::DefaultValue::hostname); BOOST_CHECK_EQUAL(cfg.GetTcpPort(), Configuration::DefaultValue::port); - BOOST_CHECK_EQUAL(cfg.GetPageSize(), Configuration::DefaultValue::pageSize); - BOOST_CHECK_EQUAL(cfg.IsDistributedJoins(), false); - BOOST_CHECK_EQUAL(cfg.IsEnforceJoinOrder(), false); - BOOST_CHECK_EQUAL(cfg.IsReplicatedOnly(), false); - BOOST_CHECK_EQUAL(cfg.IsCollocated(), false); - BOOST_CHECK_EQUAL(cfg.IsLazy(), false); - BOOST_CHECK_EQUAL(cfg.IsSkipReducerOnUpdate(), false); - BOOST_CHECK(cfg.GetAddresses().empty()); + BOOST_CHECK_EQUAL(cfg.GetUser(), Configuration::DefaultValue::user); + BOOST_CHECK_EQUAL(cfg.GetPassword(), Configuration::DefaultValue::password); + BOOST_CHECK_EQUAL(cfg.GetApplicationName(), Configuration::DefaultValue::appName); + BOOST_CHECK_EQUAL(cfg.GetLoginTimeoutSeconds(), Configuration::DefaultValue::loginTimeoutSec); + BOOST_CHECK_EQUAL(cfg.GetReadPreference(), Configuration::DefaultValue::readPreference); + BOOST_CHECK_EQUAL(cfg.GetReplicaSet(), Configuration::DefaultValue::replicaSet); + BOOST_CHECK_EQUAL(cfg.IsRetryReads(), Configuration::DefaultValue::retryReads); + BOOST_CHECK_EQUAL(cfg.IsTls(), Configuration::DefaultValue::tls); + BOOST_CHECK_EQUAL(cfg.IsTlsAllowInvalidHostnames(), Configuration::DefaultValue::tlsAllowInvalidHostnames); + BOOST_CHECK_EQUAL(cfg.GetTlsCaFile(), Configuration::DefaultValue::tlsCaFile); + BOOST_CHECK_EQUAL(cfg.GetSshUser(), Configuration::DefaultValue::sshUser); + BOOST_CHECK_EQUAL(cfg.GetSshHost(), Configuration::DefaultValue::sshHost); + BOOST_CHECK_EQUAL(cfg.GetSshPrivateKeyFile(), Configuration::DefaultValue::sshPrivateKeyFile); + BOOST_CHECK_EQUAL(cfg.GetSshPrivateKeyPassphrase(), Configuration::DefaultValue::sshPrivateKeyPassphrase); + BOOST_CHECK_EQUAL(cfg.IsSshStrictHostKeyChecking(), Configuration::DefaultValue::sshStrictHostKeyChecking); + BOOST_CHECK_EQUAL(cfg.GetSshKnownHostsFile(), Configuration::DefaultValue::sshKnownHostsFile); + BOOST_CHECK_EQUAL(cfg.GetScanMethod(), Configuration::DefaultValue::scanMethod); + BOOST_CHECK_EQUAL(cfg.GetScanLimit(), Configuration::DefaultValue::scanLimit); + BOOST_CHECK_EQUAL(cfg.GetSchemaName(), Configuration::DefaultValue::schemaName); + BOOST_CHECK_EQUAL(cfg.IsSchemaRefresh(), Configuration::DefaultValue::refreshSchema); + BOOST_CHECK_EQUAL(cfg.GetDefaultFetchSize(), Configuration::DefaultValue::defaultFetchSize); } BOOST_AUTO_TEST_SUITE(ConfigurationTestSuite) -BOOST_AUTO_TEST_CASE(CheckTestValuesNotEquealDefault) +BOOST_AUTO_TEST_CASE(CheckTestValuesNotEqualDefault) { BOOST_CHECK_NE(testDriverName, Configuration::DefaultValue::driver); - BOOST_CHECK_NE(testAddressStr, Configuration::DefaultValue::address); - BOOST_CHECK_NE(testServerPort, Configuration::DefaultValue::port); - BOOST_CHECK_NE(testSchemaName, Configuration::DefaultValue::schema); BOOST_CHECK_NE(testDsn, Configuration::DefaultValue::dsn); - BOOST_CHECK_NE(testPageSize, Configuration::DefaultValue::pageSize); - BOOST_CHECK_NE(testDistributedJoins, Configuration::DefaultValue::distributedJoins); - BOOST_CHECK_NE(testEnforceJoinOrder, Configuration::DefaultValue::enforceJoinOrder); - BOOST_CHECK_NE(testReplicatedOnly, Configuration::DefaultValue::replicatedOnly); - BOOST_CHECK_NE(testCollocated, Configuration::DefaultValue::collocated); - BOOST_CHECK_NE(testLazy, Configuration::DefaultValue::lazy); - BOOST_CHECK_NE(testSkipReducerOnUpdate, Configuration::DefaultValue::skipReducerOnUpdate); + BOOST_CHECK_NE(testDatabaseName, Configuration::DefaultValue::database); + BOOST_CHECK_NE(testHostname, Configuration::DefaultValue::hostname); + BOOST_CHECK_NE(testServerPort, Configuration::DefaultValue::port); + BOOST_CHECK_NE(testUsername, Configuration::DefaultValue::user); + BOOST_CHECK_NE(testPassword, Configuration::DefaultValue::password); + BOOST_CHECK_NE(testAppName, Configuration::DefaultValue::appName); + BOOST_CHECK_NE(testLoginTimeoutSec, Configuration::DefaultValue::loginTimeoutSec); + BOOST_CHECK_NE(testReadPreference, Configuration::DefaultValue::readPreference); + BOOST_CHECK_NE(testReplicaSet, Configuration::DefaultValue::replicaSet); + BOOST_CHECK_NE(testRetryReads, Configuration::DefaultValue::retryReads); + BOOST_CHECK_NE(testTlsFlag, Configuration::DefaultValue::tls); + BOOST_CHECK_NE(testTlsAllowInvalidHostnamesFlag, Configuration::DefaultValue::tlsAllowInvalidHostnames); + BOOST_CHECK_NE(testTlsCaFile, Configuration::DefaultValue::tlsCaFile); + BOOST_CHECK_NE(testSshUser, Configuration::DefaultValue::sshUser); + BOOST_CHECK_NE(testSshHost, Configuration::DefaultValue::sshHost); + BOOST_CHECK_NE(testSshPrivateKeyFile, Configuration::DefaultValue::sshPrivateKeyFile); + BOOST_CHECK_NE(testSshPrivateKeyPassphrase, Configuration::DefaultValue::sshPrivateKeyPassphrase); + BOOST_CHECK_NE(testSshStrictHostKeyCheckingFlag, Configuration::DefaultValue::sshStrictHostKeyChecking); + BOOST_CHECK_NE(testSshKnownHostsFile, Configuration::DefaultValue::sshKnownHostsFile); + BOOST_CHECK_NE(testScanMethod, Configuration::DefaultValue::scanMethod); + BOOST_CHECK_NE(testScanLimit, Configuration::DefaultValue::scanLimit); + BOOST_CHECK_NE(testSchemaName, Configuration::DefaultValue::schemaName); + BOOST_CHECK_NE(testRefreshSchemaFlag, Configuration::DefaultValue::refreshSchema); + BOOST_CHECK_NE(testDefaultFetchSize, Configuration::DefaultValue::defaultFetchSize); } BOOST_AUTO_TEST_CASE(TestConnectStringUppercase) @@ -259,16 +299,31 @@ BOOST_AUTO_TEST_CASE(TestConnectStringUppercase) std::stringstream constructor; - constructor << "DRIVER={" << testDriverName << "};" - << "LAZY=" << BoolToStr(testLazy, false) << ';' - << "ADDRESS=" << testAddressStr << ';' - << "DISTRIBUTED_JOINS=" << BoolToStr(testDistributedJoins, false) << ';' - << "ENFORCE_JOIN_ORDER=" << BoolToStr(testEnforceJoinOrder, false) << ';' - << "COLLOCATED=" << BoolToStr(testCollocated, false) << ';' - << "REPLICATED_ONLY=" << BoolToStr(testReplicatedOnly, false) << ';' - << "PAGE_SIZE=" << testPageSize << ';' - << "SCHEMA=" << testSchemaName << ';' - << "SKIP_REDUCER_ON_UPDATE=" << BoolToStr(testSkipReducerOnUpdate, false); + constructor << "HOSTNAME=" << testHostname << ';' + << "PORT=" << testServerPort << ';' + << "DATABASE=" << testDatabaseName << ';' + << "USER=" << testUsername << ';' + << "PASSWORD=" << testPassword << ';' + << "APP_NAME=" << testAppName << ';' + << "LOGIN_TIMEOUT_SEC=" << testLoginTimeoutSec << ';' + << "READ_PREFERENCE=" << testReadPreference << ';' + << "REPLICA_SET=" << testReplicaSet << ';' + << "RETRY_READS=" << BoolToStr(testRetryReads) << ';' + << "TLS=" << BoolToStr(testTlsFlag) << ';' + << "TLS_ALLOW_INVALID_HOSTNAMES=" << BoolToStr(testTlsAllowInvalidHostnamesFlag) << ';' + << "TLS_CA_FILE=" << testTlsCaFile << ';' + << "SSH_USER=" << testSshUser << ';' + << "SSH_HOST=" << testSshHost << ';' + << "SSH_PRIVATE_KEY_FILE=" << testSshPrivateKeyFile << ';' + << "SSH_PRIVATE_KEY_PASSPHRASE=" << testSshPrivateKeyPassphrase << ';' + << "SSH_STRICT_HOST_KEY_CHECKING=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' + << "SSH_KNOWN_HOSTS_FILE=" << testSshKnownHostsFile << ';' + << "SCAN_METHOD=" << testScanMethod << ';' + << "SCAN_LIMIT=" << testScanLimit << ';' + << "SCHEMA_NAME=" << testSchemaName << ';' + << "REFRESH_SCHEMA=" << BoolToStr(testRefreshSchemaFlag) << ';' + << "DEFAULT_FETCH_SIZE=" << testDefaultFetchSize << ';' + << "DRIVER={" << testDriverName << "};"; const std::string& connectStr = constructor.str(); @@ -283,16 +338,31 @@ BOOST_AUTO_TEST_CASE(TestConnectStringLowercase) std::stringstream constructor; - constructor << "driver={" << testDriverName << "};" - << "lazy=" << BoolToStr(testLazy) << ';' - << "address=" << testAddressStr << ';' - << "page_size=" << testPageSize << ';' - << "distributed_joins=" << BoolToStr(testDistributedJoins) << ';' - << "enforce_join_order=" << BoolToStr(testEnforceJoinOrder) << ';' - << "replicated_only=" << BoolToStr(testReplicatedOnly) << ';' - << "collocated=" << BoolToStr(testCollocated) << ';' - << "schema=" << testSchemaName << ';' - << "skip_reducer_on_update=" << BoolToStr(testSkipReducerOnUpdate); + constructor << "hostname=" << testHostname << ';' + << "port=" << testServerPort << ';' + << "database=" << testDatabaseName << ';' + << "user=" << testUsername << ';' + << "password=" << testPassword << ';' + << "app_name=" << testAppName << ';' + << "login_timeout_sec=" << testLoginTimeoutSec << ';' + << "read_preference=" << testReadPreference << ';' + << "replica_set=" << testReplicaSet << ';' + << "retry_reads=" << BoolToStr(testRetryReads) << ';' + << "tls=" << BoolToStr(testTlsFlag) << ';' + << "tls_allow_invalid_hostnames=" << BoolToStr(testTlsAllowInvalidHostnamesFlag) << ';' + << "tls_ca_file=" << testTlsCaFile << ';' + << "ssh_user=" << testSshUser << ';' + << "ssh_host=" << testSshHost << ';' + << "ssh_private_key_file=" << testSshPrivateKeyFile << ';' + << "ssh_private_key_passphrase=" << testSshPrivateKeyPassphrase << ';' + << "ssh_strict_host_key_checking=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' + << "ssh_known_hosts_file=" << testSshKnownHostsFile << ';' + << "scan_method=" << testScanMethod << ';' + << "scan_limit=" << testScanLimit << ';' + << "schema_name=" << testSchemaName << ';' + << "refresh_schema=" << BoolToStr(testRefreshSchemaFlag) << ';' + << "default_fetch_size=" << testDefaultFetchSize << ';' + << "driver={" << testDriverName << "};"; const std::string& connectStr = constructor.str(); @@ -307,16 +377,31 @@ BOOST_AUTO_TEST_CASE(TestConnectStringZeroTerminated) std::stringstream constructor; - constructor << "driver={" << testDriverName << "};" - << "address=" << testAddressStr << ';' - << "lazy=" << BoolToStr(testLazy) << ';' - << "page_size=" << testPageSize << ';' - << "replicated_only=" << BoolToStr(testReplicatedOnly) << ';' - << "collocated=" << BoolToStr(testCollocated) << ';' - << "distributed_joins=" << BoolToStr(testDistributedJoins) << ';' - << "enforce_join_order=" << BoolToStr(testEnforceJoinOrder) << ';' - << "schema=" << testSchemaName << ';' - << "skip_reducer_on_update=" << BoolToStr(testSkipReducerOnUpdate); + constructor << "hostname=" << testHostname << ';' + << "port=" << testServerPort << ';' + << "database=" << testDatabaseName << ';' + << "user=" << testUsername << ';' + << "password=" << testPassword << ';' + << "app_name=" << testAppName << ';' + << "login_timeout_sec=" << testLoginTimeoutSec << ';' + << "read_preference=" << testReadPreference << ';' + << "replica_set=" << testReplicaSet << ';' + << "retry_reads=" << BoolToStr(testRetryReads) << ';' + << "tls=" << BoolToStr(testTlsFlag) << ';' + << "tls_allow_invalid_hostnames=" << BoolToStr(testTlsAllowInvalidHostnamesFlag) << ';' + << "tls_ca_file=" << testTlsCaFile << ';' + << "ssh_user=" << testSshUser << ';' + << "ssh_host=" << testSshHost << ';' + << "ssh_private_key_file=" << testSshPrivateKeyFile << ';' + << "ssh_private_key_passphrase=" << testSshPrivateKeyPassphrase << ';' + << "ssh_strict_host_key_checking=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' + << "ssh_known_hosts_file=" << testSshKnownHostsFile << ';' + << "scan_method=" << testScanMethod << ';' + << "scan_limit=" << testScanLimit << ';' + << "schema_name=" << testSchemaName << ';' + << "refresh_schema=" << BoolToStr(testRefreshSchemaFlag) << ';' + << "default_fetch_size=" << testDefaultFetchSize << ';' + << "driver={" << testDriverName << "};"; std::string connectStr = constructor.str(); @@ -333,16 +418,31 @@ BOOST_AUTO_TEST_CASE(TestConnectStringMixed) std::stringstream constructor; - constructor << "Driver={" << testDriverName << "};" - << "Lazy=" << BoolToStr(testLazy) << ';' - << "Address=" << testAddressStr << ';' - << "Page_Size=" << testPageSize << ';' - << "Distributed_Joins=" << BoolToStr(testDistributedJoins, false) << ';' - << "Enforce_Join_Order=" << BoolToStr(testEnforceJoinOrder) << ';' - << "Replicated_Only=" << BoolToStr(testReplicatedOnly, false) << ';' - << "Collocated=" << BoolToStr(testCollocated) << ';' - << "Schema=" << testSchemaName << ';' - << "Skip_Reducer_On_Update=" << BoolToStr(testSkipReducerOnUpdate); + constructor << "Hostname=" << testHostname << ';' + << "Port=" << testServerPort << ';' + << "Database=" << testDatabaseName << ';' + << "User=" << testUsername << ';' + << "Password=" << testPassword << ';' + << "App_Name=" << testAppName << ';' + << "Login_Timeout_Sec=" << testLoginTimeoutSec << ';' + << "Read_Preference=" << testReadPreference << ';' + << "Replica_Set=" << testReplicaSet << ';' + << "Retry_Reads=" << BoolToStr(testRetryReads) << ';' + << "Tls=" << BoolToStr(testTlsFlag) << ';' + << "Tls_Allow_Invalid_Hostnames=" << BoolToStr(testTlsAllowInvalidHostnamesFlag) << ';' + << "Tls_Ca_File=" << testTlsCaFile << ';' + << "Ssh_User=" << testSshUser << ';' + << "Ssh_Host=" << testSshHost << ';' + << "Ssh_Private_Key_File=" << testSshPrivateKeyFile << ';' + << "Ssh_Private_Key_Passphrase=" << testSshPrivateKeyPassphrase << ';' + << "Ssh_Strict_Host_Key_Checking=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' + << "Ssh_Known_Hosts_File=" << testSshKnownHostsFile << ';' + << "Scan_Method=" << testScanMethod << ';' + << "Scan_Limit=" << testScanLimit << ';' + << "Schema_Name=" << testSchemaName << ';' + << "Refresh_Schema=" << BoolToStr(testRefreshSchemaFlag) << ';' + << "Default_Fetch_Size=" << testDefaultFetchSize << ';' + << "Driver={" << testDriverName << "};"; const std::string& connectStr = constructor.str(); @@ -357,16 +457,31 @@ BOOST_AUTO_TEST_CASE(TestConnectStringWhitepaces) std::stringstream constructor; - constructor << "DRIVER = {" << testDriverName << "} ;\n" - << " ADDRESS =" << testAddressStr << "; " - << " PAGE_SIZE= " << testPageSize << ';' - << " DISTRIBUTED_JOINS=" << BoolToStr(testDistributedJoins, false) << ';' - << "LAZY=" << BoolToStr(testLazy, false) << ';' - << "COLLOCATED =" << BoolToStr(testCollocated, false) << " ;" - << " REPLICATED_ONLY= " << BoolToStr(testReplicatedOnly, false) << ';' - << "ENFORCE_JOIN_ORDER= " << BoolToStr(testEnforceJoinOrder, false) << " ;" - << "SCHEMA = \n\r" << testSchemaName << ';' - << " skip_reducer_on_update=" << BoolToStr(testSkipReducerOnUpdate, false); + constructor << " HOSTNAME=" << testHostname << ';' + << "PORT =" << testServerPort << ';' + << " DATABASE=" << testDatabaseName << ';' + << "USER =" << testUsername << ';' + << "PASSWORD=" << testPassword << ';' + << "APP_NAME=" << testAppName << ';' + << "LOGIN_TIMEOUT_SEC=" << testLoginTimeoutSec << ';' + << "READ_PREFERENCE=" << testReadPreference << ';' + << " REPLICA_SET=" << testReplicaSet << ';' + << "RETRY_READS=" << BoolToStr(testRetryReads) << ';' + << "TLS =" << BoolToStr(testTlsFlag) << ';' + << " TLS_ALLOW_INVALID_HOSTNAMES=" << BoolToStr(testTlsAllowInvalidHostnamesFlag) << ';' + << "TLS_CA_FILE=" << testTlsCaFile << ';' + << " SSH_USER=" << testSshUser << ';' + << "SSH_HOST=" << testSshHost << ';' + << "SSH_PRIVATE_KEY_FILE= " << testSshPrivateKeyFile << ';' + << " SSH_PRIVATE_KEY_PASSPHRASE= " << testSshPrivateKeyPassphrase << ';' + << " SSH_STRICT_HOST_KEY_CHECKING= " << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' + << " SSH_KNOWN_HOSTS_FILE = " << testSshKnownHostsFile << ';' + << " SCAN_METHOD = " << testScanMethod << ';' + << " SCAN_LIMIT= " << testScanLimit << ';' + << "SCHEMA_NAME=" << testSchemaName << " ; " + << " REFRESH_SCHEMA=" << BoolToStr(testRefreshSchemaFlag) << ';' + << " DEFAULT_FETCH_SIZE = " << testDefaultFetchSize << " ; " + << "DRIVER = {" << testDriverName << "};"; const std::string& connectStr = constructor.str(); @@ -379,50 +494,26 @@ BOOST_AUTO_TEST_CASE(TestConnectStringInvalidAddress) { Configuration cfg; - ParseConnectStringWithError("Address=example.com:0;", cfg); - ParseConnectStringWithError("Address=example.com:00000;", cfg); - ParseConnectStringWithError("Address=example.com:fdsf;", cfg); - ParseConnectStringWithError("Address=example.com:123:1;", cfg); - ParseConnectStringWithError("Address=example.com:12322221;", cfg); - ParseConnectStringWithError("Address=example.com:12322a;", cfg); - ParseConnectStringWithError("Address=example.com:;", cfg); + ParseConnectStringWithError("hostname=example.com:0;", cfg); + ParseConnectStringWithError("hostname=example.com:00000;", cfg); + ParseConnectStringWithError("hostname=example.com:fdsf;", cfg); + ParseConnectStringWithError("hostname=example.com:123:1;", cfg); + ParseConnectStringWithError("hostname=example.com:12322221;", cfg); + ParseConnectStringWithError("hostname=example.com:12322a;", cfg); + ParseConnectStringWithError("hostname=example.com:;", cfg); } BOOST_AUTO_TEST_CASE(TestConnectStringValidAddress) { - CheckValidAddress("Address=example.com:1;", EndPoint("example.com", 1)); - CheckValidAddress("Address=example.com:31242;", EndPoint("example.com", 31242)); - CheckValidAddress("Address=example.com:55555;", EndPoint("example.com", 55555)); - CheckValidAddress("Address=example.com:110;", EndPoint("example.com", 110)); - CheckValidAddress("Address=example.com;", EndPoint("example.com", Configuration::DefaultValue::port)); - CheckValidAddress("Address=example.com:1000..1010;", EndPoint("example.com", 1000, 10)); -} - -BOOST_AUTO_TEST_CASE(TestConnectStringValidAddress4) -{ - std::vector addrs; - - addrs.push_back(EndPoint("one.com", 1234)); - addrs.push_back(EndPoint("two.net", 42, 53-42)); - addrs.push_back(EndPoint("three.eu", Configuration::DefaultValue::port)); - addrs.push_back(EndPoint("some.long.name.org", 50141)); - - CheckValidAddresses("Address=some.long.name.org:50141,three.eu,two.net:42..53,one.com:1234", addrs); -} - -BOOST_AUTO_TEST_CASE(TestConnectStringValidAddress4Spaces) -{ - std::vector addrs; - - addrs.push_back(EndPoint("one.com", 1234)); - addrs.push_back(EndPoint("two.net", 42, 53 - 42)); - addrs.push_back(EndPoint("three.eu", Configuration::DefaultValue::port)); - addrs.push_back(EndPoint("some.long.name.org", 50141)); - - CheckValidAddresses("Address = some.long.name.org:50141, three.eu, two.net: 42 .. 53, one.com:1234", addrs); + CheckValidAddress("hostname=example.com:1;", EndPoint("example.com", 1)); + CheckValidAddress("hostname=example.com:31242;", EndPoint("example.com", 31242)); + CheckValidAddress("hostname=example.com:55555;", EndPoint("example.com", 55555)); + CheckValidAddress("hostname=example.com:110;port=27019;", EndPoint("example.com", 27019)); + CheckValidAddress("hostname=example.com;", EndPoint("example.com", Configuration::DefaultValue::port)); + CheckValidAddress("hostname=example.com:1000..1010;", EndPoint("example.com", 1000, 10)); } -BOOST_AUTO_TEST_CASE(TestConnectStringInvalidVersion) +/*BOOST_AUTO_TEST_CASE(TestConnectStringInvalidVersion) { CheckInvalidProtocolVersion("Protocol_Version=0;"); CheckInvalidProtocolVersion("Protocol_Version=1;"); @@ -443,7 +534,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringSupportedVersion) CheckSupportedProtocolVersion("Protocol_Version=2.1.5;"); CheckSupportedProtocolVersion("Protocol_Version=2.3.0;"); CheckSupportedProtocolVersion("Protocol_Version=2.3.2;"); -} +}*/ BOOST_AUTO_TEST_CASE(TestConnectStringInvalidBoolKeys) { @@ -451,12 +542,11 @@ BOOST_AUTO_TEST_CASE(TestConnectStringInvalidBoolKeys) Set keys; - keys.insert("distributed_joins"); - keys.insert("enforce_join_order"); - keys.insert("replicated_only"); - keys.insert("collocated"); - keys.insert("lazy"); - keys.insert("skip_reducer_on_update"); + keys.insert("retry_reads"); + keys.insert("tls"); + keys.insert("tls_allow_invalid_hostnames"); + keys.insert("ssh_strict_host_key_checking"); + keys.insert("refresh_schema"); for (Set::const_iterator it = keys.begin(); it != keys.end(); ++it) { @@ -479,12 +569,11 @@ BOOST_AUTO_TEST_CASE(TestConnectStringValidBoolKeys) Set keys; - keys.insert("distributed_joins"); - keys.insert("enforce_join_order"); - keys.insert("replicated_only"); - keys.insert("collocated"); - keys.insert("lazy"); - keys.insert("skip_reducer_on_update"); + keys.insert("retry_reads"); + keys.insert("tls"); + keys.insert("tls_allow_invalid_hostnames"); + keys.insert("ssh_strict_host_key_checking"); + keys.insert("refresh_schema"); for (Set::const_iterator it = keys.begin(); it != keys.end(); ++it) { diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index c5a021c2d..a377e2dd0 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -52,13 +52,10 @@ namespace ignite /** Default value for Driver attribute. */ static const std::string driver; - /** Default value for schema attribute. */ + /** Default value for database attribute. */ static const std::string database; - /** Default value for address attribute. */ - static const std::string address; - - /** Default value for server attribute. */ + /** Default value for hostname attribute. */ static const std::string hostname; /** Default value for port attribute. */ @@ -85,9 +82,6 @@ namespace ignite /** Default value for retryReads attribute. */ static const bool retryReads; - /** Default value for sslMode attribute. */ - static const ssl::SslMode::Type sslMode; - /** Default value for tls attribute. */ static const bool tls; @@ -133,14 +127,8 @@ namespace ignite /** Default value for sslCertFile attribute. */ static const std::string sslCertFile; - /** Default value for protocol version. */ - // static const ProtocolVersion& protocolVersion; - - /** Default value for fetch results page size attribute. */ + /** Default value for defaultFetchSize attribute. */ static const int32_t defaultFetchSize; - - /** Default value for nestedTxMode attribute. */ - static const NestedTxMode::Type nestedTxMode; }; /** @@ -677,27 +665,6 @@ namespace ignite */ bool IsSchemaRefreshSet() const; - /** - * Get addresses. - * - * @return Addresses. - */ - const std::vector& GetAddresses() const; - - /** - * Set addresses to connect to. - * - * @param endPoints Addresses. - */ - void SetAddresses(const std::vector& endPoints); - - /** - * Check if the value set. - * - * @return @true if the value set. - */ - bool IsAddressesSet() const; - /** * Get fetch results page size. * @@ -773,9 +740,6 @@ namespace ignite /** Retry reads flag. */ SettableValue retryReads; - /** Connection end-points. */ - SettableValue< std::vector > endPoints; // Remove in favor of deprecated one - /** Enable SSL/TLS. */ SettableValue tls; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index c8832697c..b82716dac 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -135,7 +135,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - std::string addr = config::AddressesToString(config.GetAddresses()); + std::string addr = config.GetHostname(); val = addr.c_str(); addressLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, @@ -549,7 +549,7 @@ namespace ignite throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Protocol version is not supported."); cfg.SetDsn(dsnStr); - cfg.SetAddresses(addresses); + //cfg.SetAddresses(addresses); cfg.SetDatabase(schemaStr); //cfg.SetProtocolVersion(version); } diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 198ecb9d0..bf4b9cadb 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -31,10 +31,9 @@ namespace ignite namespace config { - const std::string Configuration::DefaultValue::dsn = "Apache Ignite DSN"; - const std::string Configuration::DefaultValue::driver = "Apache Ignite"; + const std::string Configuration::DefaultValue::dsn = "DocumentDB DSN"; + const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB Driver"; // remove const std::string Configuration::DefaultValue::database = ""; - const std::string Configuration::DefaultValue::address = ""; // remove const std::string Configuration::DefaultValue::hostname = ""; const uint16_t Configuration::DefaultValue::port = 27017; const std::string Configuration::DefaultValue::user = ""; @@ -62,13 +61,11 @@ namespace ignite // Additional options const std::string Configuration::DefaultValue::appName = "Amazon DocumentDB ODBC Driver"; const int32_t Configuration::DefaultValue::loginTimeoutSec = 0; - const std::string Configuration::DefaultValue::readPreference = ""; + const std::string Configuration::DefaultValue::readPreference = "primary"; const std::string Configuration::DefaultValue::replicaSet = ""; const bool Configuration::DefaultValue::retryReads = true; const int32_t Configuration::DefaultValue::defaultFetchSize = 2000; - const NestedTxMode::Type Configuration::DefaultValue::nestedTxMode = NestedTxMode::AI_ERROR; // remove - Configuration::Configuration() : dsn(DefaultValue::dsn), driver(DefaultValue::driver), @@ -77,7 +74,6 @@ namespace ignite port(DefaultValue::port), user(DefaultValue::user), password(DefaultValue::password), - endPoints(std::vector()), appName(DefaultValue::appName), loginTimeoutSec(DefaultValue::loginTimeoutSec), readPreference(DefaultValue::readPreference), @@ -204,21 +200,6 @@ namespace ignite return database.IsSet(); } - const std::vector& Configuration::GetAddresses() const - { - return endPoints.GetValue(); - } - - void Configuration::SetAddresses(const std::vector& endPoints) - { - this->endPoints.SetValue(endPoints); - } - - bool Configuration::IsAddressesSet() const - { - return endPoints.IsSet(); - } - const std::string& Configuration::GetApplicationName() const { return appName.GetValue(); @@ -540,7 +521,6 @@ namespace ignite AddToMap(res, ConnectionStringParser::Key::dsn, dsn); AddToMap(res, ConnectionStringParser::Key::driver, driver); AddToMap(res, ConnectionStringParser::Key::database, database); - AddToMap(res, ConnectionStringParser::Key::address, endPoints); AddToMap(res, ConnectionStringParser::Key::server, hostname); AddToMap(res, ConnectionStringParser::Key::port, port); AddToMap(res, ConnectionStringParser::Key::user, user); diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 308bb225b..489fa624c 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -35,7 +35,7 @@ namespace ignite const std::string ConnectionStringParser::Key::driver = "driver"; const std::string ConnectionStringParser::Key::database = "database"; const std::string ConnectionStringParser::Key::address = "address"; - const std::string ConnectionStringParser::Key::server = "server"; + const std::string ConnectionStringParser::Key::server = "hostname"; const std::string ConnectionStringParser::Key::port = "port"; const std::string ConnectionStringParser::Key::user = "user"; const std::string ConnectionStringParser::Key::password = "password"; @@ -151,17 +151,16 @@ namespace ignite { cfg.SetDatabase(value); } - else if (lKey == Key::address) + else if (lKey == Key::server) { - std::vector endPoints; + EndPoint endpoint; - ParseAddress(value, endPoints, diag); + ParseSingleAddress(value, endpoint, diag); - cfg.SetAddresses(endPoints); - } - else if (lKey == Key::server) - { - cfg.SetHostname(value); + cfg.SetHostname(endpoint.host); + + if (!cfg.IsTcpPortSet()) + cfg.SetTcpPort(endpoint.port); } else if (lKey == Key::port) { @@ -255,7 +254,7 @@ namespace ignite return; } - cfg.SetScanLimit(static_cast(numValue)); + cfg.SetLoginTimeoutSeconds(static_cast(numValue)); } else if (lKey == Key::readPreference) { @@ -265,6 +264,23 @@ namespace ignite { cfg.SetReplicaSet(value); } + else if (lKey == Key::retryReads) + { + BoolParseResult::Type res = StringToBool(value); + + if (res == BoolParseResult::AI_UNRECOGNIZED) + { + if (diag) + { + diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, + MakeErrorMessage("Unrecognized bool value. Using default value.", key, value)); + } + + return; + } + + cfg.SetRetryReads(res == BoolParseResult::AI_TRUE); + } else if (lKey == Key::tls) { BoolParseResult::Type res = StringToBool(value); @@ -397,7 +413,7 @@ namespace ignite return; } - cfg.SetTls(res == BoolParseResult::AI_TRUE); + cfg.SetSchemaRefresh(res == BoolParseResult::AI_TRUE); } else if (lKey == Key::defaultFetchSize) { diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index c2875fd7e..b347c5035 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -188,7 +188,7 @@ namespace ignite return SqlResult::AI_ERROR; } - if (!config.IsHostnameSet() && config.IsAddressesSet() && config.GetAddresses().empty()) + if (!config.IsHostnameSet()) { AddStatusRecord("No valid address to connect."); @@ -780,7 +780,12 @@ namespace ignite { endPoints.clear(); - if (!cfg.IsAddressesSet()) + // DocumentDB driver is currently not supporting list of addresses. Always use this 'legacy' method. + LOG_MSG("'Address' is not set. Using legacy connection method."); + endPoints.push_back(EndPoint(cfg.GetHostname(), cfg.GetTcpPort())); + return; + + /*if (!cfg.IsAddressesSet()) { LOG_MSG("'Address' is not set. Using legacy connection method."); @@ -790,8 +795,10 @@ namespace ignite } endPoints = cfg.GetAddresses(); + std::random_shuffle(endPoints.begin(), endPoints.end()); + */ } int32_t Connection::RetrieveTimeout(void* value) diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 6526a38bd..564d6b272 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -104,17 +104,6 @@ namespace ignite void ReadDsnConfiguration(const char* dsn, Configuration& config, diagnostic::DiagnosticRecordStorage* diag) { - SettableValue address = ReadDsnString(dsn, ConnectionStringParser::Key::address); - - if (address.IsSet() && !config.IsAddressesSet()) - { - std::vector endPoints; - - ParseAddress(address.GetValue(), endPoints, diag); - - config.SetAddresses(endPoints); - } - SettableValue server = ReadDsnString(dsn, ConnectionStringParser::Key::server); if (server.IsSet() && !config.IsHostnameSet()) From 8a5a35749804915319b37c63a0004c749991b409 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 09:20:47 -0800 Subject: [PATCH 023/100] [AD-522] add space to code lines for format consistency in configuration_window.h --- .../odbc/system/ui/dsn_configuration_window.h | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index ad8c45e99..5779ee7bf 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -242,37 +242,37 @@ namespace ignite std::auto_ptr schemaEdit; /** Application name edit. */ - std::auto_ptr appNameEdit; + std::auto_ptr appNameEdit; /** Application name label. */ - std::auto_ptr appNameLabel; + std::auto_ptr appNameLabel; /** Login Timeout (seconds) edit. */ - std::auto_ptr loginTimeoutSecEdit; + std::auto_ptr loginTimeoutSecEdit; /** Login Timeout (seconds) label. */ - std::auto_ptr loginTimeoutSecLabel; + std::auto_ptr loginTimeoutSecLabel; /** Read preference edit. */ - std::auto_ptr readPreferenceEdit; + std::auto_ptr readPreferenceEdit; /** Read preference label. */ - std::auto_ptr readPreferenceLabel; + std::auto_ptr readPreferenceLabel; /** Replica Set edit. */ - std::auto_ptr< Window > replicaSetEdit; + std::auto_ptr< Window > replicaSetEdit; /** Replica Set label. */ - std::auto_ptr< Window > replicaSetLabel; + std::auto_ptr< Window > replicaSetLabel; /** Retry reads CheckBox. */ - std::auto_ptr retryReadsCheckBox; + std::auto_ptr retryReadsCheckBox; /** Fetch size edit. */ - std::auto_ptr fetchSizeEdit; + std::auto_ptr fetchSizeEdit; /** Fetch size label. */ - std::auto_ptr fetchSizeLabel; + std::auto_ptr fetchSizeLabel; /** Protocol version edit field. */ std::auto_ptr protocolVersionLabel; From 504d2bacc47bbfb4f33e968a6ae8af10633f523b Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Thu, 20 Jan 2022 09:25:19 -0800 Subject: [PATCH 024/100] Add more unit tests --- src/odbc-test/CMakeLists.txt | 54 +++-- src/odbc-test/src/configuration_test.cpp | 106 +++++---- src/odbc/CMakeLists.txt | 4 +- .../ignite/odbc/config/configuration.h | 217 +++++++++--------- .../include/ignite/odbc/read_preference.h | 61 +++++ src/odbc/include/ignite/odbc/scan_method.h | 59 +++++ src/odbc/src/config/configuration.cpp | 64 ++---- .../src/config/connection_string_parser.cpp | 32 ++- src/odbc/src/dsn_config.cpp | 14 +- src/odbc/src/read_preference.cpp | 74 ++++++ src/odbc/src/scan_method.cpp | 68 ++++++ 11 files changed, 528 insertions(+), 225 deletions(-) create mode 100644 src/odbc/include/ignite/odbc/read_preference.h create mode 100644 src/odbc/include/ignite/odbc/scan_method.h create mode 100644 src/odbc/src/read_preference.cpp create mode 100644 src/odbc/src/scan_method.cpp diff --git a/src/odbc-test/CMakeLists.txt b/src/odbc-test/CMakeLists.txt index ae4ab2274..96276e8e3 100644 --- a/src/odbc-test/CMakeLists.txt +++ b/src/odbc-test/CMakeLists.txt @@ -33,6 +33,18 @@ include_directories(include ../odbc/include ../network/include) set(SOURCES src/dummy_test.cpp src/configuration_test.cpp + ../odbc/src/config/config_tools.cpp + ../odbc/src/config/configuration.cpp + ../odbc/src/config/connection_info.cpp + ../odbc/src/config/connection_string_parser.cpp + ../odbc/src/scan_method.cpp + ../odbc/src/read_preference.cpp + ../odbc/src/diagnostic/diagnostic_record.cpp + ../odbc/src/diagnostic/diagnostic_record_storage.cpp + ../odbc/src/utility.cpp + ../odbc/src/common_types.cpp + ../odbc/src/app/application_data_buffer.cpp + ../odbc/src/log.cpp # TODO uncomment/rework the tests after get some connectivity and functionalities working. # src/teamcity/teamcity_boost.cpp # src/teamcity/teamcity_messages.cpp @@ -72,27 +84,27 @@ set(SOURCES # src/streaming_test.cpp # src/cursor_binding_test.cpp # src/test_server.cpp - ../odbc/src/log.cpp - ../odbc/src/cursor.cpp - ../odbc/src/diagnostic/diagnostic_record.cpp - ../odbc/src/diagnostic/diagnostic_record_storage.cpp - ../odbc/src/config/config_tools.cpp - ../odbc/src/config/configuration.cpp - ../odbc/src/config/connection_info.cpp - ../odbc/src/config/connection_string_parser.cpp - ../odbc/src/app/application_data_buffer.cpp - ../odbc/src/ssl_mode.cpp - ../odbc/src/sql/sql_parser.cpp - ../odbc/src/sql/sql_lexer.cpp - ../odbc/src/sql/sql_set_streaming_command.cpp - ../odbc/src/sql/sql_utils.cpp - ../odbc/src/row.cpp - ../odbc/src/protocol_version.cpp - ../odbc/src/column.cpp - ../odbc/src/common_types.cpp - ../odbc/src/utility.cpp - ../odbc/src/result_page.cpp - ../odbc/src/nested_tx_mode.cpp +# ../odbc/src/log.cpp +# ../odbc/src/cursor.cpp +# ../odbc/src/diagnostic/diagnostic_record.cpp +# ../odbc/src/diagnostic/diagnostic_record_storage.cpp +# ../odbc/src/config/config_tools.cpp +# ../odbc/src/config/configuration.cpp +# ../odbc/src/config/connection_info.cpp +# ../odbc/src/config/connection_string_parser.cpp +# ../odbc/src/app/application_data_buffer.cpp +# ../odbc/src/ssl_mode.cpp +# ../odbc/src/sql/sql_parser.cpp +# ../odbc/src/sql/sql_lexer.cpp +# ../odbc/src/sql/sql_set_streaming_command.cpp +# ../odbc/src/sql/sql_utils.cpp +# ../odbc/src/row.cpp +# ../odbc/src/protocol_version.cpp +# ../odbc/src/column.cpp +# ../odbc/src/common_types.cpp +# ../odbc/src/utility.cpp +# ../odbc/src/result_page.cpp +# ../odbc/src/nested_tx_mode.cpp ) add_executable(${TARGET} ${SOURCES}) diff --git a/src/odbc-test/src/configuration_test.cpp b/src/odbc-test/src/configuration_test.cpp index 9d21d1f60..d2c441280 100644 --- a/src/odbc-test/src/configuration_test.cpp +++ b/src/odbc-test/src/configuration_test.cpp @@ -41,7 +41,7 @@ namespace const std::string testPassword = "testPassword"; const std::string testAppName = "testAppName"; const int32_t testLoginTimeoutSec = 3000; - const std::string testReadPreference = "primaryPreferred"; + const ReadPreference::Type testReadPreference = ReadPreference::Type::PRIMARY_PREFERRED; const std::string testReplicaSet = "rs0"; const bool testRetryReads = false; const bool testTlsFlag = false; @@ -53,7 +53,7 @@ namespace const std::string testSshPrivateKeyPassphrase = "testPassphrase"; const bool testSshStrictHostKeyCheckingFlag = false; const std::string testSshKnownHostsFile = "/path/to/knownhostsfile"; - const std::string testScanMethod = "idForward"; + const ScanMethod::Type testScanMethod =ScanMethod::Type::ID_FORWARD; const int32_t testScanLimit = 3000; const std::string testSchemaName = "testSchemaName"; const bool testRefreshSchemaFlag = true; @@ -115,31 +115,42 @@ void CheckValidAddress(const char* connectStr, const EndPoint& endPoint) BOOST_CHECK_EQUAL(cfg.GetTcpPort(), endPoint.port); } -void CheckValidProtocolVersion(const char* connectStr, ProtocolVersion version) +void CheckValidScanMethod(const char* connectStr, ScanMethod::Type scanMethod) { Configuration cfg; ParseValidConnectString(connectStr, cfg); - //BOOST_CHECK(cfg.GetProtocolVersion() == version); + BOOST_CHECK(cfg.GetScanMethod() == scanMethod); } -void CheckSupportedProtocolVersion(const char* connectStr) + +void CheckInvalidScanMethod(const char* connectStr) +{ + Configuration cfg; + + ParseConnectStringWithError(connectStr, cfg); + + BOOST_CHECK(cfg.GetScanMethod() == Configuration::DefaultValue::scanMethod); +} + +void CheckValidReadPreference(const char* connectStr, ReadPreference::Type preference) { Configuration cfg; ParseValidConnectString(connectStr, cfg); - //BOOST_CHECK(cfg.GetProtocolVersion().IsSupported()); + BOOST_CHECK(cfg.GetReadPreference() == preference); } -void CheckInvalidProtocolVersion(const char* connectStr) + +void CheckInvalidReadPreference(const char* connectStr) { Configuration cfg; ParseConnectStringWithError(connectStr, cfg); - //BOOST_CHECK(cfg.GetProtocolVersion() == Configuration::DefaultValue::protocolVersion); + BOOST_CHECK(cfg.GetReadPreference() == Configuration::DefaultValue::readPreference); } void CheckValidBoolValue(const std::string& connectStr, const std::string& key, bool val) @@ -178,7 +189,6 @@ void CheckConnectionConfig(const Configuration& cfg) BOOST_CHECK_EQUAL(cfg.GetPassword(), testPassword); BOOST_CHECK_EQUAL(cfg.GetApplicationName(), testAppName); BOOST_CHECK_EQUAL(cfg.GetLoginTimeoutSeconds(), testLoginTimeoutSec); - BOOST_CHECK_EQUAL(cfg.GetReadPreference(), testReadPreference); BOOST_CHECK_EQUAL(cfg.GetReplicaSet(), testReplicaSet); BOOST_CHECK_EQUAL(cfg.IsRetryReads(), testRetryReads); BOOST_CHECK_EQUAL(cfg.IsTls(), testTlsFlag); @@ -190,13 +200,13 @@ void CheckConnectionConfig(const Configuration& cfg) BOOST_CHECK_EQUAL(cfg.GetSshPrivateKeyPassphrase(), testSshPrivateKeyPassphrase); BOOST_CHECK_EQUAL(cfg.IsSshStrictHostKeyChecking(), testSshStrictHostKeyCheckingFlag); BOOST_CHECK_EQUAL(cfg.GetSshKnownHostsFile(), testSshKnownHostsFile); - BOOST_CHECK_EQUAL(cfg.GetScanMethod(), testScanMethod); BOOST_CHECK_EQUAL(cfg.GetScanLimit(), testScanLimit); BOOST_CHECK_EQUAL(cfg.GetSchemaName(), testSchemaName); - BOOST_CHECK_EQUAL(cfg.IsSchemaRefresh(), testRefreshSchemaFlag); + BOOST_CHECK_EQUAL(cfg.IsRefreshSchema(), testRefreshSchemaFlag); BOOST_CHECK_EQUAL(cfg.GetDefaultFetchSize(), testDefaultFetchSize); - BOOST_CHECK(!cfg.IsDsnSet()); + BOOST_CHECK(cfg.GetReadPreference() == testReadPreference); + BOOST_CHECK(cfg.GetScanMethod() == testScanMethod); std::stringstream constructor; @@ -208,12 +218,12 @@ void CheckConnectionConfig(const Configuration& cfg) << "login_timeout_sec=" << testLoginTimeoutSec << ';' << "password=" << testPassword << ';' << "port=" << testServerPort << ';' - << "read_preference=" << testReadPreference << ';' + << "read_preference=" << ReadPreference::ToString(testReadPreference) << ';' << "refresh_schema=" << BoolToStr(testRefreshSchemaFlag) << ';' << "replica_set=" << testReplicaSet << ';' << "retry_reads=" << BoolToStr(testRetryReads) << ';' << "scan_limit=" << testScanLimit << ';' - << "scan_method=" << testScanMethod << ';' + << "scan_method=" << ScanMethod::ToString(testScanMethod) << ';' << "schema_name=" << testSchemaName << ';' << "ssh_host=" << testSshHost << ';' << "ssh_known_hosts_file=" << testSshKnownHostsFile << ';' @@ -242,7 +252,6 @@ void CheckDsnConfig(const Configuration& cfg) BOOST_CHECK_EQUAL(cfg.GetPassword(), Configuration::DefaultValue::password); BOOST_CHECK_EQUAL(cfg.GetApplicationName(), Configuration::DefaultValue::appName); BOOST_CHECK_EQUAL(cfg.GetLoginTimeoutSeconds(), Configuration::DefaultValue::loginTimeoutSec); - BOOST_CHECK_EQUAL(cfg.GetReadPreference(), Configuration::DefaultValue::readPreference); BOOST_CHECK_EQUAL(cfg.GetReplicaSet(), Configuration::DefaultValue::replicaSet); BOOST_CHECK_EQUAL(cfg.IsRetryReads(), Configuration::DefaultValue::retryReads); BOOST_CHECK_EQUAL(cfg.IsTls(), Configuration::DefaultValue::tls); @@ -254,11 +263,12 @@ void CheckDsnConfig(const Configuration& cfg) BOOST_CHECK_EQUAL(cfg.GetSshPrivateKeyPassphrase(), Configuration::DefaultValue::sshPrivateKeyPassphrase); BOOST_CHECK_EQUAL(cfg.IsSshStrictHostKeyChecking(), Configuration::DefaultValue::sshStrictHostKeyChecking); BOOST_CHECK_EQUAL(cfg.GetSshKnownHostsFile(), Configuration::DefaultValue::sshKnownHostsFile); - BOOST_CHECK_EQUAL(cfg.GetScanMethod(), Configuration::DefaultValue::scanMethod); BOOST_CHECK_EQUAL(cfg.GetScanLimit(), Configuration::DefaultValue::scanLimit); BOOST_CHECK_EQUAL(cfg.GetSchemaName(), Configuration::DefaultValue::schemaName); - BOOST_CHECK_EQUAL(cfg.IsSchemaRefresh(), Configuration::DefaultValue::refreshSchema); + BOOST_CHECK_EQUAL(cfg.IsRefreshSchema(), Configuration::DefaultValue::refreshSchema); BOOST_CHECK_EQUAL(cfg.GetDefaultFetchSize(), Configuration::DefaultValue::defaultFetchSize); + BOOST_CHECK(cfg.GetReadPreference() == Configuration::DefaultValue::readPreference); + BOOST_CHECK(cfg.GetScanMethod() == Configuration::DefaultValue::scanMethod); } BOOST_AUTO_TEST_SUITE(ConfigurationTestSuite) @@ -274,7 +284,6 @@ BOOST_AUTO_TEST_CASE(CheckTestValuesNotEqualDefault) BOOST_CHECK_NE(testPassword, Configuration::DefaultValue::password); BOOST_CHECK_NE(testAppName, Configuration::DefaultValue::appName); BOOST_CHECK_NE(testLoginTimeoutSec, Configuration::DefaultValue::loginTimeoutSec); - BOOST_CHECK_NE(testReadPreference, Configuration::DefaultValue::readPreference); BOOST_CHECK_NE(testReplicaSet, Configuration::DefaultValue::replicaSet); BOOST_CHECK_NE(testRetryReads, Configuration::DefaultValue::retryReads); BOOST_CHECK_NE(testTlsFlag, Configuration::DefaultValue::tls); @@ -286,11 +295,12 @@ BOOST_AUTO_TEST_CASE(CheckTestValuesNotEqualDefault) BOOST_CHECK_NE(testSshPrivateKeyPassphrase, Configuration::DefaultValue::sshPrivateKeyPassphrase); BOOST_CHECK_NE(testSshStrictHostKeyCheckingFlag, Configuration::DefaultValue::sshStrictHostKeyChecking); BOOST_CHECK_NE(testSshKnownHostsFile, Configuration::DefaultValue::sshKnownHostsFile); - BOOST_CHECK_NE(testScanMethod, Configuration::DefaultValue::scanMethod); BOOST_CHECK_NE(testScanLimit, Configuration::DefaultValue::scanLimit); BOOST_CHECK_NE(testSchemaName, Configuration::DefaultValue::schemaName); BOOST_CHECK_NE(testRefreshSchemaFlag, Configuration::DefaultValue::refreshSchema); BOOST_CHECK_NE(testDefaultFetchSize, Configuration::DefaultValue::defaultFetchSize); + BOOST_CHECK(testReadPreference != Configuration::DefaultValue::readPreference); + BOOST_CHECK(testScanMethod != Configuration::DefaultValue::scanMethod); } BOOST_AUTO_TEST_CASE(TestConnectStringUppercase) @@ -306,7 +316,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringUppercase) << "PASSWORD=" << testPassword << ';' << "APP_NAME=" << testAppName << ';' << "LOGIN_TIMEOUT_SEC=" << testLoginTimeoutSec << ';' - << "READ_PREFERENCE=" << testReadPreference << ';' + << "READ_PREFERENCE=" << ReadPreference::ToString(testReadPreference) << ';' << "REPLICA_SET=" << testReplicaSet << ';' << "RETRY_READS=" << BoolToStr(testRetryReads) << ';' << "TLS=" << BoolToStr(testTlsFlag) << ';' @@ -318,7 +328,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringUppercase) << "SSH_PRIVATE_KEY_PASSPHRASE=" << testSshPrivateKeyPassphrase << ';' << "SSH_STRICT_HOST_KEY_CHECKING=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' << "SSH_KNOWN_HOSTS_FILE=" << testSshKnownHostsFile << ';' - << "SCAN_METHOD=" << testScanMethod << ';' + << "SCAN_METHOD=" << ScanMethod::ToString(testScanMethod) << ';' << "SCAN_LIMIT=" << testScanLimit << ';' << "SCHEMA_NAME=" << testSchemaName << ';' << "REFRESH_SCHEMA=" << BoolToStr(testRefreshSchemaFlag) << ';' @@ -345,7 +355,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringLowercase) << "password=" << testPassword << ';' << "app_name=" << testAppName << ';' << "login_timeout_sec=" << testLoginTimeoutSec << ';' - << "read_preference=" << testReadPreference << ';' + << "read_preference=" << ReadPreference::ToString(testReadPreference) << ';' << "replica_set=" << testReplicaSet << ';' << "retry_reads=" << BoolToStr(testRetryReads) << ';' << "tls=" << BoolToStr(testTlsFlag) << ';' @@ -357,7 +367,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringLowercase) << "ssh_private_key_passphrase=" << testSshPrivateKeyPassphrase << ';' << "ssh_strict_host_key_checking=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' << "ssh_known_hosts_file=" << testSshKnownHostsFile << ';' - << "scan_method=" << testScanMethod << ';' + << "scan_method=" << ScanMethod::ToString(testScanMethod) << ';' << "scan_limit=" << testScanLimit << ';' << "schema_name=" << testSchemaName << ';' << "refresh_schema=" << BoolToStr(testRefreshSchemaFlag) << ';' @@ -384,7 +394,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringZeroTerminated) << "password=" << testPassword << ';' << "app_name=" << testAppName << ';' << "login_timeout_sec=" << testLoginTimeoutSec << ';' - << "read_preference=" << testReadPreference << ';' + << "read_preference=" << ReadPreference::ToString(testReadPreference) << ';' << "replica_set=" << testReplicaSet << ';' << "retry_reads=" << BoolToStr(testRetryReads) << ';' << "tls=" << BoolToStr(testTlsFlag) << ';' @@ -396,7 +406,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringZeroTerminated) << "ssh_private_key_passphrase=" << testSshPrivateKeyPassphrase << ';' << "ssh_strict_host_key_checking=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' << "ssh_known_hosts_file=" << testSshKnownHostsFile << ';' - << "scan_method=" << testScanMethod << ';' + << "scan_method=" << ScanMethod::ToString(testScanMethod) << ';' << "scan_limit=" << testScanLimit << ';' << "schema_name=" << testSchemaName << ';' << "refresh_schema=" << BoolToStr(testRefreshSchemaFlag) << ';' @@ -425,7 +435,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringMixed) << "Password=" << testPassword << ';' << "App_Name=" << testAppName << ';' << "Login_Timeout_Sec=" << testLoginTimeoutSec << ';' - << "Read_Preference=" << testReadPreference << ';' + << "Read_Preference=" << ReadPreference::ToString(testReadPreference) << ';' << "Replica_Set=" << testReplicaSet << ';' << "Retry_Reads=" << BoolToStr(testRetryReads) << ';' << "Tls=" << BoolToStr(testTlsFlag) << ';' @@ -437,7 +447,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringMixed) << "Ssh_Private_Key_Passphrase=" << testSshPrivateKeyPassphrase << ';' << "Ssh_Strict_Host_Key_Checking=" << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' << "Ssh_Known_Hosts_File=" << testSshKnownHostsFile << ';' - << "Scan_Method=" << testScanMethod << ';' + << "Scan_Method=" << ScanMethod::ToString(testScanMethod) << ';' << "Scan_Limit=" << testScanLimit << ';' << "Schema_Name=" << testSchemaName << ';' << "Refresh_Schema=" << BoolToStr(testRefreshSchemaFlag) << ';' @@ -464,7 +474,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringWhitepaces) << "PASSWORD=" << testPassword << ';' << "APP_NAME=" << testAppName << ';' << "LOGIN_TIMEOUT_SEC=" << testLoginTimeoutSec << ';' - << "READ_PREFERENCE=" << testReadPreference << ';' + << "READ_PREFERENCE=" << ReadPreference::ToString(testReadPreference) << ';' << " REPLICA_SET=" << testReplicaSet << ';' << "RETRY_READS=" << BoolToStr(testRetryReads) << ';' << "TLS =" << BoolToStr(testTlsFlag) << ';' @@ -476,7 +486,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringWhitepaces) << " SSH_PRIVATE_KEY_PASSPHRASE= " << testSshPrivateKeyPassphrase << ';' << " SSH_STRICT_HOST_KEY_CHECKING= " << BoolToStr(testSshStrictHostKeyCheckingFlag) << ';' << " SSH_KNOWN_HOSTS_FILE = " << testSshKnownHostsFile << ';' - << " SCAN_METHOD = " << testScanMethod << ';' + << " SCAN_METHOD = " << ScanMethod::ToString(testScanMethod) << ';' << " SCAN_LIMIT= " << testScanLimit << ';' << "SCHEMA_NAME=" << testSchemaName << " ; " << " REFRESH_SCHEMA=" << BoolToStr(testRefreshSchemaFlag) << ';' @@ -513,28 +523,34 @@ BOOST_AUTO_TEST_CASE(TestConnectStringValidAddress) CheckValidAddress("hostname=example.com:1000..1010;", EndPoint("example.com", 1000, 10)); } -/*BOOST_AUTO_TEST_CASE(TestConnectStringInvalidVersion) +BOOST_AUTO_TEST_CASE(TestConnectStringInvalidScanMethod) { - CheckInvalidProtocolVersion("Protocol_Version=0;"); - CheckInvalidProtocolVersion("Protocol_Version=1;"); - CheckInvalidProtocolVersion("Protocol_Version=2;"); - CheckInvalidProtocolVersion("Protocol_Version=2.1;"); + CheckInvalidScanMethod("scan_method=forward;"); + CheckInvalidScanMethod("scan_method=id_random;"); } -BOOST_AUTO_TEST_CASE(TestConnectStringUnsupportedVersion) +BOOST_AUTO_TEST_CASE(TestConnectStringValidScanMethod) { - CheckInvalidProtocolVersion("Protocol_Version=1.6.1;"); - CheckInvalidProtocolVersion("Protocol_Version=1.7.0;"); - CheckInvalidProtocolVersion("Protocol_Version=1.8.1;"); + CheckValidScanMethod("scan_method=all;", ScanMethod::Type::ALL); + CheckValidScanMethod("scan_method=id_forward;", ScanMethod::Type::ID_FORWARD); + CheckValidScanMethod("scan_method=id_reverse;", ScanMethod::Type::ID_REVERSE); + CheckValidScanMethod("scan_method=random;", ScanMethod::Type::RANDOM); } -BOOST_AUTO_TEST_CASE(TestConnectStringSupportedVersion) +BOOST_AUTO_TEST_CASE(TestConnectStringInvalidReadPreference) { - CheckSupportedProtocolVersion("Protocol_Version=2.1.0;"); - CheckSupportedProtocolVersion("Protocol_Version=2.1.5;"); - CheckSupportedProtocolVersion("Protocol_Version=2.3.0;"); - CheckSupportedProtocolVersion("Protocol_Version=2.3.2;"); -}*/ + CheckInvalidReadPreference("read_preference=primary_nearest;"); + CheckInvalidReadPreference("read_preference=nearest_preferred;"); +} + +BOOST_AUTO_TEST_CASE(TestConnectStringValidReadPreference) +{ + CheckValidReadPreference("read_preference=primary;", ReadPreference::Type::PRIMARY); + CheckValidReadPreference("read_preference=primary_preferred;", ReadPreference::Type::PRIMARY_PREFERRED); + CheckValidReadPreference("read_preference=secondary;", ReadPreference::Type::SECONDARY); + CheckValidReadPreference("read_preference=secondary_preferred;", ReadPreference::Type::SECONDARY_PREFERRED); + CheckValidReadPreference("read_preference=nearest;", ReadPreference::Type::NEAREST); +} BOOST_AUTO_TEST_CASE(TestConnectStringInvalidBoolKeys) { @@ -653,4 +669,4 @@ BOOST_AUTO_TEST_CASE(TestDsnStringWhitespaces) CheckDsnConfig(cfg); } -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/src/odbc/CMakeLists.txt b/src/odbc/CMakeLists.txt index 4c251a97b..522dd1392 100644 --- a/src/odbc/CMakeLists.txt +++ b/src/odbc/CMakeLists.txt @@ -68,7 +68,9 @@ set(SOURCES src/app/application_data_buffer.cpp src/statement.cpp src/type_traits.cpp src/utility.cpp - src/log.cpp) + src/log.cpp + src/read_preference.cpp + src/scan_method.cpp) if (WIN32) include_directories(os/win/include) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index a377e2dd0..a7b87ad5c 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -27,6 +27,8 @@ #include "ignite/odbc/ssl_mode.h" #include "ignite/odbc/end_point.h" #include "ignite/odbc/nested_tx_mode.h" +#include "ignite/odbc/read_preference.h" +#include "ignite/odbc/scan_method.h" namespace ignite { @@ -74,7 +76,7 @@ namespace ignite static const int32_t loginTimeoutSec; /** Default value for readPreference attribute. */ - static const std::string readPreference; + static const ReadPreference::Type readPreference; /** Default value for replicaSet attribute. */ static const std::string replicaSet; @@ -110,7 +112,7 @@ namespace ignite static const std::string sshKnownHostsFile; /** Default value for scanMethod attribute. */ - static const std::string scanMethod; + static const ScanMethod::Type scanMethod; /** Default value for scanLimit attribute. */ static const int32_t scanLimit; @@ -167,7 +169,7 @@ namespace ignite * * @param dsn Data Source Name. */ - void SetDsn(const std::string& dsn); + void SetDsn(const std::string& dsnName); /** * Get Driver. @@ -181,7 +183,7 @@ namespace ignite * * @param driver Driver. */ - void SetDriver(const std::string& driver); + void SetDriver(const std::string& driverName); /** * Get server host. @@ -214,9 +216,9 @@ namespace ignite /** * Set server port. * - * @param port Server port. + * @param portNumber Server port. */ - void SetTcpPort(uint16_t port); + void SetTcpPort(uint16_t portNumber); /** * Check if the value set. @@ -226,18 +228,18 @@ namespace ignite bool IsTcpPortSet() const; /** - * Get schema. + * Get database. * - * @return Schema. + * @return Database. */ const std::string& GetDatabase() const; /** * Set schema. * - * @param schema Schema name. + * @param database Database name. */ - void SetDatabase(const std::string& schema); + void SetDatabase(const std::string& databaseName); /** * Check if the value set. @@ -258,7 +260,7 @@ namespace ignite * * @param user User. */ - void SetUser(const std::string& user); + void SetUser(const std::string& username); /** * Check if the value set. @@ -289,16 +291,16 @@ namespace ignite bool IsPasswordSet() const; /** - * Get password. + * Get application name. * - * @return Password. + * @return Application name. */ const std::string& GetApplicationName() const; /** - * Set password. + * Set application name. * - * @param pass Password. + * @param name Application name. */ void SetApplicationName(const std::string& name); @@ -310,16 +312,16 @@ namespace ignite bool IsApplicationNameSet() const; /** - * Get fetch results page size. + * Get login timeout in seconds. * - * @return Fetch results page size. + * @return Login timeout in seconds. */ int32_t GetLoginTimeoutSeconds() const; /** - * Set fetch results page size. + * Set login timeout in seconds. * - * @param size Fetch results page size. + * @param seconds Login timeout in seconds. */ void SetLoginTimeoutSeconds(int32_t seconds); @@ -331,18 +333,18 @@ namespace ignite bool IsLoginTimeoutSecondsSet() const; /** - * Get password. + * Get read preference. * - * @return Password. + * @return Read preference. */ - const std::string& GetReadPreference() const; + ReadPreference::Type GetReadPreference() const; /** - * Set password. + * Set read preference. * - * @param pass Password. + * @param preference Read preference. */ - void SetReadPreference(const std::string& preference); + void SetReadPreference(const ReadPreference::Type preference); /** * Check if the value set. @@ -350,17 +352,18 @@ namespace ignite * @return @true if the value set. */ bool IsReadPreferenceSet() const; + /** - * Get password. + * Get replica set name. * - * @return Password. + * @return Replica set name. */ const std::string& GetReplicaSet() const; /** - * Set password. + * Set replica set name. * - * @param pass Password. + * @param name Replica set name. */ void SetReplicaSet(const std::string& name); @@ -372,16 +375,16 @@ namespace ignite bool IsReplicaSetSet() const; /** - * Get password. + * Get retry reads flag. * - * @return Password. + * @return @true if retry reads enabled. */ bool IsRetryReads() const; /** - * Set password. + * Set retry reads. * - * @param pass Password. + * @param val Value to set. */ void SetRetryReads(bool val); @@ -393,16 +396,16 @@ namespace ignite bool IsRetryReadsSet() const; /** - * Get password. + * Get TLS flag. * - * @return Password. + * @return @true if TLS is enabled. */ bool IsTls() const; /** - * Set password. + * Set TLS flag. * - * @param pass Password. + * @param val Value to set. */ void SetTls(bool val); @@ -414,16 +417,16 @@ namespace ignite bool IsTlsSet() const; /** - * Get password. + * Get TLS allow invalid hostnames flag. * - * @return Password. + * @return @true if invalid hostnames are allowed with TLS. */ bool IsTlsAllowInvalidHostnames() const; /** - * Set password. + * Set TLS allow invaid hostnames flag. * - * @param pass Password. + * @param val Value to set. */ void SetTlsAllowInvalidHostnames(bool val); @@ -435,16 +438,16 @@ namespace ignite bool IsTlsAllowInvalidHostnamesSet() const; /** - * Get password. + * Get path to TLS CA file. * - * @return Password. + * @return path to TLS CA file. */ const std::string& GetTlsCaFile() const; /** - * Set password. + * Set path to TLS CA file. * - * @param pass Password. + * @param path Path to TLS CA file. */ void SetTlsCaFile(const std::string& path); @@ -456,18 +459,18 @@ namespace ignite bool IsTlsCaFileSet() const; /** - * Get password. + * Get username for SSH host. * - * @return Password. + * @return SSH username. */ const std::string& GetSshUser() const; /** - * Set password. + * Set username for SSH host. * - * @param pass Password. + * @param username SSH username. */ - void SetSshUser(const std::string& user); + void SetSshUser(const std::string& username); /** * Check if the value set. @@ -477,16 +480,16 @@ namespace ignite bool IsSshUserSet() const; /** - * Get password. + * Get hostname for SSH host. * - * @return Password. + * @return SSH hostname. */ const std::string& GetSshHost() const; /** - * Set password. + * Set SSH hostname. * - * @param pass Password. + * @param host SSH hostname. */ void SetSshHost(const std::string& host); @@ -498,16 +501,16 @@ namespace ignite bool IsSshHostSet() const; /** - * Get password. + * Get path to private key file for SSH host. * - * @return Password. + * @return Path to private key file for SSH host. */ const std::string& GetSshPrivateKeyFile () const; /** - * Set password. + * Set path to private key file. * - * @param pass Password. + * @param path Path to private key file for SSH host. */ void SetSshPrivateKeyFile(const std::string& path); @@ -519,16 +522,16 @@ namespace ignite bool IsSshPrivateKeyFileSet() const; /** - * Get password. + * Get SSH private key passphrase. * - * @return Password. + * @return SSH private key passphrase. */ const std::string& GetSshPrivateKeyPassphrase() const; /** - * Set password. + * Set SSH private key file passphrase. * - * @param pass Password. + * @param passphrase SSH private key file passphrase. */ void SetSshPrivateKeyPassphrase(const std::string& passphrase); @@ -540,16 +543,16 @@ namespace ignite bool IsSshPrivateKeyPassphraseSet() const; /** - * Get password. + * Get SSH strict host key checking flag. * - * @return Password. + * @return @true if strict host key checking is enabled. */ bool IsSshStrictHostKeyChecking() const; /** - * Set password. + * Set strict host key checking flag. * - * @param pass Password. + * @param val Value to set. */ void SetSshStrictHostKeyChecking(bool val); @@ -561,16 +564,16 @@ namespace ignite bool IsSshStrictHostKeyCheckingSet() const; /** - * Get password. + * Get path to SSH known hosts file. * - * @return Password. + * @return Path to SSH known hosts file. */ const std::string& GetSshKnownHostsFile() const; /** - * Set password. + * Set path to SSH known hosts file. * - * @param pass Password. + * @param path Path to SSH known hosts file. */ void SetSshKnownHostsFile(const std::string& path); @@ -582,18 +585,18 @@ namespace ignite bool IsSshKnownHostsFileSet() const; /** - * Get password. + * Get scan method. * - * @return Password. + * @return Scan method. */ - const std::string& GetScanMethod() const; + ScanMethod::Type GetScanMethod() const; /** - * Set password. + * Set scan method. * - * @param pass Password. + * @param method Scan method. */ - void SetScanMethod(const std::string& method); + void SetScanMethod(const ScanMethod::Type method); /** * Check if the value set. @@ -603,16 +606,16 @@ namespace ignite bool IsScanMethodSet() const; /** - * Get fetch results page size. + * Get scan limit in # of documents. * - * @return Fetch results page size. + * @return Scan limit. */ int32_t GetScanLimit() const; /** - * Set fetch results page size. + * Set scan limit in # of documents. * - * @param size Fetch results page size. + * @param limit Scan limit in # of documents. */ void SetScanLimit(int32_t limit); @@ -624,18 +627,18 @@ namespace ignite bool IsScanLimitSet() const; /** - * Get password. + * Get schema name to save. * - * @return Password. + * @return Schema name. */ const std::string& GetSchemaName() const; /** - * Set password. + * Set schema name to save. * - * @param pass Password. + * @param name Schema name. */ - void SetSchemaName(const std::string& method); + void SetSchemaName(const std::string& name); /** * Check if the value set. @@ -645,37 +648,37 @@ namespace ignite bool IsSchemaNameSet() const; /** - * Get password. + * Get refresh schema flag. * * @return Password. */ - bool IsSchemaRefresh() const; + bool IsRefreshSchema() const; /** - * Set password. + * Set refresh schema flag. * - * @param pass Password. + * @return @true if the value set. */ - void SetSchemaRefresh(bool val); + void SetRefreshSchema(bool val); /** * Check if the value set. * * @return @true if the value set. */ - bool IsSchemaRefreshSet() const; + bool IsRefreshSchemaSet() const; /** - * Get fetch results page size. + * Get default fetch size. * - * @return Fetch results page size. + * @return Default fetch size. */ int32_t GetDefaultFetchSize() const; /** - * Set fetch results page size. + * Set default fetch size. * - * @param size Fetch results page size. + * @param size Default fetch size. */ void SetDefaultFetchSize(int32_t size); @@ -713,10 +716,10 @@ namespace ignite /** Schema. */ SettableValue database; - /** Server. Deprecated. */ + /** Hostname. */ SettableValue hostname; - /** TCP port. Deprecated. */ + /** Port. */ SettableValue port; /** User. */ @@ -732,7 +735,7 @@ namespace ignite SettableValue loginTimeoutSec; /** Read pereference. */ - SettableValue readPreference; + SettableValue readPreference; /** Replica set name. */ SettableValue replicaSet; @@ -768,7 +771,7 @@ namespace ignite SettableValue sshKnownHostsFile; /** Scan method. */ - SettableValue scanMethod; + SettableValue scanMethod; /** Scan limit. */ SettableValue scanLimit; @@ -800,20 +803,12 @@ namespace ignite const SettableValue& value); template<> - void Configuration::AddToMap(ArgumentMap& map, const std::string& key, - const SettableValue& value); - - template<> - void Configuration::AddToMap< std::vector >(ArgumentMap& map, const std::string& key, - const SettableValue< std::vector >& value); - - template<> - void Configuration::AddToMap(ArgumentMap& map, const std::string& key, - const SettableValue& value); + void Configuration::AddToMap(ArgumentMap& map, const std::string& key, + const SettableValue& value); template<> - void Configuration::AddToMap(ArgumentMap& map, const std::string& key, - const SettableValue& value); + void Configuration::AddToMap(ArgumentMap& map, const std::string& key, + const SettableValue& value); } } } diff --git a/src/odbc/include/ignite/odbc/read_preference.h b/src/odbc/include/ignite/odbc/read_preference.h new file mode 100644 index 000000000..8e522931a --- /dev/null +++ b/src/odbc/include/ignite/odbc/read_preference.h @@ -0,0 +1,61 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace ignite +{ + namespace odbc + { + /** Read Preference enum. */ + struct ReadPreference + { + enum class Type + { + PRIMARY, + + PRIMARY_PREFERRED, + + SECONDARY, + + SECONDARY_PREFERRED, + + NEAREST, + + UNKNOWN + }; + + /** + * Convert preference from string. + * + * @param val String value. + * @param dflt Default value to return on error. + * @return Corresponding enum value. + */ + static Type FromString(const std::string& val, Type dflt = Type::UNKNOWN); + + /** + * Convert mode to string. + * + * @param val Value to convert. + * @return String value. + */ + static std::string ToString(Type val); + + }; + } +} diff --git a/src/odbc/include/ignite/odbc/scan_method.h b/src/odbc/include/ignite/odbc/scan_method.h new file mode 100644 index 000000000..e6d088c91 --- /dev/null +++ b/src/odbc/include/ignite/odbc/scan_method.h @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace ignite +{ + namespace odbc + { + /** Scan method enum. */ + struct ScanMethod + { + enum class Type + { + RANDOM, + + ID_FORWARD, + + ID_REVERSE, + + ALL, + + UNKNOWN + }; + + /** + * Convert preference from string. + * + * @param val String value. + * @param dflt Default value to return on error. + * @return Corresponding enum value. + */ + static Type FromString(const std::string& val, Type dflt = Type::UNKNOWN); + + /** + * Convert mode to string. + * + * @param val Value to convert. + * @return String value. + */ + static std::string ToString(Type val); + + }; + } +} diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index bf4b9cadb..c43d8262e 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -32,7 +32,7 @@ namespace ignite { const std::string Configuration::DefaultValue::dsn = "DocumentDB DSN"; - const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB Driver"; // remove + const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB Driver"; const std::string Configuration::DefaultValue::database = ""; const std::string Configuration::DefaultValue::hostname = ""; const uint16_t Configuration::DefaultValue::port = 27017; @@ -45,7 +45,7 @@ namespace ignite const std::string Configuration::DefaultValue::tlsCaFile = ""; // Schema Generation and Discovery options - const std::string Configuration::DefaultValue::scanMethod = "random"; + const ScanMethod::Type Configuration::DefaultValue::scanMethod = ScanMethod::Type::RANDOM; const int32_t Configuration::DefaultValue::scanLimit = 1000; const std::string Configuration::DefaultValue::schemaName = "_default"; const bool Configuration::DefaultValue::refreshSchema = false; @@ -61,7 +61,7 @@ namespace ignite // Additional options const std::string Configuration::DefaultValue::appName = "Amazon DocumentDB ODBC Driver"; const int32_t Configuration::DefaultValue::loginTimeoutSec = 0; - const std::string Configuration::DefaultValue::readPreference = "primary"; + const ReadPreference::Type Configuration::DefaultValue::readPreference = ReadPreference::Type::PRIMARY; const std::string Configuration::DefaultValue::replicaSet = ""; const bool Configuration::DefaultValue::retryReads = true; const int32_t Configuration::DefaultValue::defaultFetchSize = 2000; @@ -132,9 +132,9 @@ namespace ignite return port.GetValue(); } - void Configuration::SetTcpPort(uint16_t port) + void Configuration::SetTcpPort(uint16_t portNumber) { - this->port.SetValue(port); + this->port.SetValue(portNumber); } bool Configuration::IsTcpPortSet() const @@ -155,9 +155,9 @@ namespace ignite return dsn.IsSet(); } - void Configuration::SetDsn(const std::string& dsn) + void Configuration::SetDsn(const std::string& dsnName) { - this->dsn.SetValue(dsn); + this->dsn.SetValue(dsnName); } const std::string& Configuration::GetDriver() const @@ -165,9 +165,9 @@ namespace ignite return driver.GetValue(); } - void Configuration::SetDriver(const std::string& driver) + void Configuration::SetDriver(const std::string& driverName) { - this->driver.SetValue(driver); + this->driver.SetValue(driverName); } const std::string& Configuration::GetHostname() const @@ -230,12 +230,12 @@ namespace ignite return loginTimeoutSec.IsSet(); } - const std::string& Configuration::GetReadPreference() const + ReadPreference::Type Configuration::GetReadPreference() const { return readPreference.GetValue(); } - void Configuration::SetReadPreference(const std::string& preference) + void Configuration::SetReadPreference(const ReadPreference::Type preference) { this->readPreference.SetValue(preference); } @@ -340,9 +340,9 @@ namespace ignite return sshHost.GetValue(); } - void Configuration::SetSshHost(const std::string& hostname) + void Configuration::SetSshHost(const std::string& host) { - this->sshHost.SetValue(hostname); + this->sshHost.SetValue(host); } bool Configuration::IsSshHostSet() const @@ -410,12 +410,12 @@ namespace ignite return sshKnownHostsFile.IsSet(); } - const std::string& Configuration::GetScanMethod() const + ScanMethod::Type Configuration::GetScanMethod() const { return scanMethod.GetValue(); } - void Configuration::SetScanMethod(const std::string& method) + void Configuration::SetScanMethod(const ScanMethod::Type method) { this->scanMethod.SetValue(method); } @@ -455,17 +455,17 @@ namespace ignite return schemaName.IsSet(); } - bool Configuration::IsSchemaRefresh() const + bool Configuration::IsRefreshSchema() const { return refreshSchema.GetValue(); } - void Configuration::SetSchemaRefresh(bool val) + void Configuration::SetRefreshSchema(bool val) { this->refreshSchema.SetValue(val); } - bool Configuration::IsSchemaRefreshSet() const + bool Configuration::IsRefreshSchemaSet() const { return refreshSchema.IsSet(); } @@ -475,9 +475,9 @@ namespace ignite return user.GetValue(); } - void Configuration::SetUser(const std::string& user) + void Configuration::SetUser(const std::string& username) { - this->user.SetValue(user); + this->user.SetValue(username); } bool Configuration::IsUserSet() const @@ -517,7 +517,6 @@ namespace ignite void Configuration::ToMap(ArgumentMap& res) const { - // Need to add properties here!! AddToMap(res, ConnectionStringParser::Key::dsn, dsn); AddToMap(res, ConnectionStringParser::Key::driver, driver); AddToMap(res, ConnectionStringParser::Key::database, database); @@ -578,35 +577,20 @@ namespace ignite template<> void Configuration::AddToMap(ArgumentMap& map, const std::string& key, - const SettableValue& value) + const SettableValue& value) { if (value.IsSet()) - map[key] = value.GetValue().ToString(); + map[key] = ReadPreference::ToString(value.GetValue()); } template<> void Configuration::AddToMap(ArgumentMap& map, const std::string& key, - const SettableValue< std::vector >& value) + const SettableValue& value) { if (value.IsSet()) - map[key] = AddressesToString(value.GetValue()); + map[key] = ScanMethod::ToString(value.GetValue()); } - template<> - void Configuration::AddToMap(ArgumentMap& map, const std::string& key, - const SettableValue& value) - { - if (value.IsSet()) - map[key] = ssl::SslMode::ToString(value.GetValue()); - } - - template<> - void Configuration::AddToMap(ArgumentMap& map, const std::string& key, - const SettableValue& value) - { - if (value.IsSet()) - map[key] = NestedTxMode::ToString(value.GetValue()); - } } } } diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 489fa624c..1a8997174 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -258,7 +258,20 @@ namespace ignite } else if (lKey == Key::readPreference) { - cfg.SetReadPreference(value); + ReadPreference::Type preference = ReadPreference::FromString(value); + + if (preference == ReadPreference::Type::UNKNOWN) + { + if (diag) + { + diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, + "Specified read preference is not supported. Default value used ('primary')."); + } + + return; + } + + cfg.SetReadPreference(preference); } else if (lKey == Key::replicaSet) { @@ -358,7 +371,20 @@ namespace ignite } else if (lKey == Key::scanMethod) { - cfg.SetScanMethod(value); + ScanMethod::Type method = ScanMethod::FromString(value); + + if (method == ScanMethod::Type::UNKNOWN) + { + if (diag) + { + diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, + "Specified scan method is not supported. Default value used ('random')."); + } + + return; + } + + cfg.SetScanMethod(method); } else if (lKey == Key::scanLimit) { @@ -413,7 +439,7 @@ namespace ignite return; } - cfg.SetSchemaRefresh(res == BoolParseResult::AI_TRUE); + cfg.SetRefreshSchema(res == BoolParseResult::AI_TRUE); } else if (lKey == Key::defaultFetchSize) { diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 564d6b272..c9fd4a0fb 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -142,7 +142,10 @@ namespace ignite SettableValue readPreference = ReadDsnString(dsn, ConnectionStringParser::Key::readPreference); if (readPreference.IsSet() && !config.IsReadPreferenceSet()) - config.SetReadPreference(readPreference.GetValue()); + { + ReadPreference::Type preference = ReadPreference::FromString(readPreference.GetValue(), ReadPreference::Type::PRIMARY); + config.SetReadPreference(preference); + } SettableValue replicaSet = ReadDsnString(dsn, ConnectionStringParser::Key::replicaSet); @@ -202,7 +205,10 @@ namespace ignite SettableValue scanMethod = ReadDsnString(dsn, ConnectionStringParser::Key::scanMethod); if (scanMethod.IsSet() && !config.IsScanMethodSet()) - config.SetScanMethod(scanMethod.GetValue()); + { + ScanMethod::Type method = ScanMethod::FromString(scanMethod.GetValue(), ScanMethod::Type::RANDOM); + config.SetScanMethod(method); + } SettableValue scanLimit = ReadDsnInt(dsn, ConnectionStringParser::Key::scanLimit); @@ -217,8 +223,8 @@ namespace ignite SettableValue refreshSchema = ReadDsnBool(dsn, ConnectionStringParser::Key::refreshSchema); - if (refreshSchema.IsSet() && !config.IsSchemaRefreshSet()) - config.SetSchemaRefresh(refreshSchema.GetValue()); + if (refreshSchema.IsSet() && !config.IsRefreshSchemaSet()) + config.SetRefreshSchema(refreshSchema.GetValue()); SettableValue defaultFetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::defaultFetchSize); diff --git a/src/odbc/src/read_preference.cpp b/src/odbc/src/read_preference.cpp new file mode 100644 index 000000000..43d81c4dc --- /dev/null +++ b/src/odbc/src/read_preference.cpp @@ -0,0 +1,74 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ignite/odbc/read_preference.h" + +namespace ignite +{ + namespace odbc + { + ReadPreference::Type ReadPreference::FromString(const std::string& val, Type dflt) + { + std::string lowerVal = common::ToLower(val); + + common::StripSurroundingWhitespaces(lowerVal); + + if (lowerVal == "primary") + return ReadPreference::Type::PRIMARY; + + if (lowerVal == "primary_preferred") + return ReadPreference::Type::PRIMARY_PREFERRED; + + if (lowerVal == "secondary") + return ReadPreference::Type::SECONDARY; + + if (lowerVal == "secondary_preferred") + return ReadPreference::Type::SECONDARY_PREFERRED; + + if (lowerVal == "nearest") + return ReadPreference::Type::NEAREST; + + return dflt; + } + + std::string ReadPreference::ToString(Type val) + { + switch (val) + { + case ReadPreference::Type::PRIMARY: + return "primary"; + + case ReadPreference::Type::PRIMARY_PREFERRED: + return "primary_preferred"; + + case ReadPreference::Type::SECONDARY: + return "secondary"; + + case ReadPreference::Type::SECONDARY_PREFERRED: + return "secondary_preferred"; + + case ReadPreference::Type::NEAREST: + return "nearest"; + + default: + return "unknown"; + } + } + } +} diff --git a/src/odbc/src/scan_method.cpp b/src/odbc/src/scan_method.cpp new file mode 100644 index 000000000..06400dd9a --- /dev/null +++ b/src/odbc/src/scan_method.cpp @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#include "ignite/odbc/scan_method.h" + +namespace ignite +{ + namespace odbc + { + ScanMethod::Type ScanMethod::FromString(const std::string& val, Type dflt) + { + std::string lowerVal = common::ToLower(val); + + common::StripSurroundingWhitespaces(lowerVal); + + if (lowerVal == "random") + return ScanMethod::Type::RANDOM; + + if (lowerVal == "id_forward") + return ScanMethod::Type::ID_FORWARD; + + if (lowerVal == "id_reverse") + return ScanMethod::Type::ID_REVERSE; + + if (lowerVal == "all") + return ScanMethod::Type::ALL; + + return dflt; + } + + std::string ScanMethod::ToString(Type val) + { + switch (val) + { + case ScanMethod::Type::ID_FORWARD: + return "id_forward"; + + case ScanMethod::Type::ID_REVERSE: + return "id_reverse"; + + case ScanMethod::Type::ALL: + return "all"; + + case ScanMethod::Type::RANDOM: + return "random"; + + default: + return "unknown"; + } + } + } +} From de1606c6c61ac5d4b054e0fc8aa5e4c987b5c136 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Thu, 20 Jan 2022 09:27:13 -0800 Subject: [PATCH 025/100] Remove extra file --- src/odbc-test/CMakeLists.txt.bak | 113 ------------------------------- 1 file changed, 113 deletions(-) delete mode 100644 src/odbc-test/CMakeLists.txt.bak diff --git a/src/odbc-test/CMakeLists.txt.bak b/src/odbc-test/CMakeLists.txt.bak deleted file mode 100644 index 0d30d5356..000000000 --- a/src/odbc-test/CMakeLists.txt.bak +++ /dev/null @@ -1,113 +0,0 @@ -# -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -project(ignite-odbc-tests) - -set(TARGET ${PROJECT_NAME}) - -if (WIN32) - set(Boost_USE_STATIC_LIBS ON) -endif() - -find_package(Boost 1.53 REQUIRED COMPONENTS unit_test_framework chrono thread system regex) - -find_package(ODBC REQUIRED) - -include_directories(SYSTEM ${ODBC_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${JNI_INCLUDE_DIRS}) -include_directories(include ../odbc/include ../network/include) - -set(SOURCES - src/dummy_test.cpp - src/configuration_test.cpp -# TODO uncomment/rework the tests after get some connectivity and functionalities working. -# src/teamcity/teamcity_boost.cpp -# src/teamcity/teamcity_messages.cpp -# src/parser_test.cpp -# src/cursor_test.cpp -# src/connection_info_test.cpp -# src/connection_test.cpp -# src/application_data_buffer_test.cpp -# src/column_test.cpp -# src/configuration_test.cpp -# src/row_test.cpp -# src/meta_queries_test.cpp -# src/utility_test.cpp -# src/queries_test.cpp -# src/queries_ssl_test.cpp -# src/test_utils.cpp -# src/sql_test_suite_fixture.cpp -# src/sql_string_functions_test.cpp -# src/sql_numeric_functions_test.cpp -# src/sql_aggregate_functions_test.cpp -# src/sql_system_functions_test.cpp -# src/sql_esc_convert_function_test.cpp -# src/sql_operators_test.cpp -# src/sql_value_expressions_test.cpp -# src/sql_types_test.cpp -# src/sql_date_time_functions_test.cpp -# src/sql_outer_join_test.cpp -# src/sql_get_info_test.cpp -# src/api_robustness_test.cpp -# src/attributes_test.cpp -# src/errors_test.cpp -# src/odbc_test_suite.cpp -# src/types_test.cpp -# src/transaction_test.cpp -# src/authentication_test.cpp -# src/sql_parsing_test.cpp -# src/streaming_test.cpp -# src/cursor_binding_test.cpp -# src/test_server.cpp -# ../odbc/src/log.cpp -# ../odbc/src/cursor.cpp -# ../odbc/src/diagnostic/diagnostic_record.cpp -# ../odbc/src/diagnostic/diagnostic_record_storage.cpp -# ../odbc/src/config/config_tools.cpp -# ../odbc/src/config/configuration.cpp -# ../odbc/src/config/connection_info.cpp -# ../odbc/src/config/connection_string_parser.cpp -# ../odbc/src/app/application_data_buffer.cpp -# ../odbc/src/ssl_mode.cpp -# ../odbc/src/sql/sql_parser.cpp -# ../odbc/src/sql/sql_lexer.cpp -# ../odbc/src/sql/sql_set_streaming_command.cpp -# ../odbc/src/sql/sql_utils.cpp -# ../odbc/src/row.cpp -# ../odbc/src/protocol_version.cpp -# ../odbc/src/column.cpp -# ../odbc/src/common_types.cpp -# ../odbc/src/utility.cpp -# ../odbc/src/result_page.cpp -# ../odbc/src/nested_tx_mode.cpp - ) - -add_executable(${TARGET} ${SOURCES}) - -target_link_libraries(${TARGET} ${Boost_LIBRARIES} ignite ${ODBC_LIBRARY}) -target_code_coverage(${TARGET} PUBLIC AUTO ALL) - -if (WIN32) - remove_definitions(-DUNICODE=1) -else() - add_definitions(-DBOOST_TEST_DYN_LINK) -endif() - -set(TEST_TARGET IgniteOdbcTest) - -add_test(NAME ${TEST_TARGET} COMMAND ${TARGET} --catch_system_errors=no --log_level=all) - -set_tests_properties(${TEST_TARGET} PROPERTIES ENVIRONMENT IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH=${PROJECT_SOURCE_DIR}/config) From c2f744ae0ff941a321c12acb62a437d665bc89f3 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 09:31:11 -0800 Subject: [PATCH 026/100] [AD-522] Add small letter case to keep format consistency in dsn_configuration_window.h Add small letter case to keep format consistency in dsn_configuration_window.h fixed one typo (Create authentication settings group box) --- .../odbc/system/ui/dsn_configuration_window.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 5779ee7bf..33c18ba41 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -176,7 +176,7 @@ namespace ignite int CreateConnectionSettingsGroup(int posX, int posY, int sizeX); /** - * Create aythentication settings group box. + * Create authentication settings group box. * * @param posX X position. * @param posY Y position. @@ -259,13 +259,13 @@ namespace ignite /** Read preference label. */ std::auto_ptr readPreferenceLabel; - /** Replica Set edit. */ + /** Replica set edit. */ std::auto_ptr< Window > replicaSetEdit; - /** Replica Set label. */ + /** Replica set label. */ std::auto_ptr< Window > replicaSetLabel; - /** Retry reads CheckBox. */ + /** Retry reads checkBox. */ std::auto_ptr retryReadsCheckBox; /** Fetch size edit. */ @@ -286,16 +286,16 @@ namespace ignite /** Cancel button. */ std::auto_ptr cancelButton; - /** TLS Encryption CheckBox. */ + /** TLS encryption checkBox. */ std::auto_ptr tlsCheckBox; - /** TLS Allow Invalid Hostnames CheckBox. */ + /** TLS allow invalid hostnames checkBox. */ std::auto_ptr tlsAllowInvalidHostnamesCheckBox; - /** TLS Certificate Authority File label. */ + /** TLS certificate authority file label. */ std::auto_ptr tlsCaFileLabel; - /** TLS Certificate Authority File edit. */ + /** TLS certificate authority file edit. */ std::auto_ptr tlsCaFileEdit; /** User label. */ From 68ab4b96158531572dc7828b940b240235ff88f1 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Thu, 20 Jan 2022 10:28:32 -0800 Subject: [PATCH 027/100] Remove redundant declaration --- src/odbc-test/CMakeLists.txt | 2 +- src/odbc/CMakeLists.txt | 2 +- .../odbc/config/connection_string_parser.h | 11 +----- .../include/ignite/odbc/read_preference.h | 38 +++++++++---------- src/odbc/include/ignite/odbc/scan_method.h | 36 +++++++++--------- .../src/config/connection_string_parser.cpp | 2 +- 6 files changed, 41 insertions(+), 50 deletions(-) diff --git a/src/odbc-test/CMakeLists.txt b/src/odbc-test/CMakeLists.txt index 96276e8e3..f81e1a103 100644 --- a/src/odbc-test/CMakeLists.txt +++ b/src/odbc-test/CMakeLists.txt @@ -32,7 +32,7 @@ include_directories(include ../odbc/include ../network/include) set(SOURCES src/dummy_test.cpp - src/configuration_test.cpp + src/configuration_test.cpp ../odbc/src/config/config_tools.cpp ../odbc/src/config/configuration.cpp ../odbc/src/config/connection_info.cpp diff --git a/src/odbc/CMakeLists.txt b/src/odbc/CMakeLists.txt index 522dd1392..e2021f3e7 100644 --- a/src/odbc/CMakeLists.txt +++ b/src/odbc/CMakeLists.txt @@ -70,7 +70,7 @@ set(SOURCES src/app/application_data_buffer.cpp src/utility.cpp src/log.cpp src/read_preference.cpp - src/scan_method.cpp) + src/scan_method.cpp) if (WIN32) include_directories(os/win/include) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index 27e4f48d2..f88411c7e 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -119,7 +119,7 @@ namespace ignite /** Connection attribute keyword for protocol version attribute. */ static const std::string protocolVersion; - /** Connection attribute keyword for fetch results page size attribute. */ + /** Connection attribute keyword for defaultFetchSize attribute. */ static const std::string defaultFetchSize; /** Connection attribute keyword for sslMode attribute. */ @@ -134,20 +134,11 @@ namespace ignite /** Connection attribute keyword for sslCaFile attribute. */ static const std::string sslCaFile; - /** Connection attribute keyword for username attribute. */ - static const std::string user; - - /** Connection attribute keyword for password attribute. */ - static const std::string password; - /** Connection attribute keyword for username attribute. */ static const std::string uid; /** Connection attribute keyword for password attribute. */ static const std::string pwd; - - /** Connection attribute keyword for nestedTxMode attribute. */ - static const std::string nestedTxMode; }; /** diff --git a/src/odbc/include/ignite/odbc/read_preference.h b/src/odbc/include/ignite/odbc/read_preference.h index 8e522931a..2859692b9 100644 --- a/src/odbc/include/ignite/odbc/read_preference.h +++ b/src/odbc/include/ignite/odbc/read_preference.h @@ -21,7 +21,7 @@ namespace ignite { namespace odbc { - /** Read Preference enum. */ + /** Read Preference enum. */ struct ReadPreference { enum class Type @@ -38,24 +38,24 @@ namespace ignite UNKNOWN }; - - /** - * Convert preference from string. - * - * @param val String value. - * @param dflt Default value to return on error. - * @return Corresponding enum value. - */ - static Type FromString(const std::string& val, Type dflt = Type::UNKNOWN); - - /** - * Convert mode to string. - * - * @param val Value to convert. - * @return String value. - */ - static std::string ToString(Type val); + + /** + * Convert preference from string. + * + * @param val String value. + * @param dflt Default value to return on error. + * @return Corresponding enum value. + */ + static Type FromString(const std::string& val, Type dflt = Type::UNKNOWN); + + /** + * Convert mode to string. + * + * @param val Value to convert. + * @return String value. + */ + static std::string ToString(Type val); - }; + }; } } diff --git a/src/odbc/include/ignite/odbc/scan_method.h b/src/odbc/include/ignite/odbc/scan_method.h index e6d088c91..1feb2f9ca 100644 --- a/src/odbc/include/ignite/odbc/scan_method.h +++ b/src/odbc/include/ignite/odbc/scan_method.h @@ -21,7 +21,7 @@ namespace ignite { namespace odbc { - /** Scan method enum. */ + /** Scan method enum. */ struct ScanMethod { enum class Type @@ -36,24 +36,24 @@ namespace ignite UNKNOWN }; - - /** - * Convert preference from string. - * - * @param val String value. - * @param dflt Default value to return on error. - * @return Corresponding enum value. - */ - static Type FromString(const std::string& val, Type dflt = Type::UNKNOWN); + + /** + * Convert scan method from string. + * + * @param val String value. + * @param dflt Default value to return on error. + * @return Corresponding enum value. + */ + static Type FromString(const std::string& val, Type dflt = Type::UNKNOWN); - /** - * Convert mode to string. - * - * @param val Value to convert. - * @return String value. - */ - static std::string ToString(Type val); + /** + * Convert method to string. + * + * @param val Value to convert. + * @return String value. + */ + static std::string ToString(Type val); - }; + }; } } diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 1a8997174..96ba6b58d 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -142,7 +142,7 @@ namespace ignite diagnostic::DiagnosticRecordStorage* diag) { std::string lKey = common::ToLower(key); - + if (lKey == Key::dsn) { cfg.SetDsn(value); From 9c52daf5c7ccd3bd9640e9618cdc965be80f1bbb Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 14:02:01 -0800 Subject: [PATCH 028/100] [AD-522] add variable definitions for SSH tunnel settings for config UI --- .../odbc/system/ui/dsn_configuration_window.h | 62 ++++++++++++++++++- .../system/ui/dsn_configuration_window.cpp | 18 ++++++ 2 files changed, 78 insertions(+), 2 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 33c18ba41..e17d0270c 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -42,6 +42,7 @@ namespace ignite enum Type { CONNECTION_SETTINGS_GROUP_BOX = 100, + SSH_SETTINGS_GROUP_BOX, SSL_SETTINGS_GROUP_BOX, ADDITIONAL_SETTINGS_GROUP_BOX, AUTH_SETTINGS_GROUP_BOX, @@ -51,6 +52,17 @@ namespace ignite ADDRESS_LABEL, SCHEMA_EDIT, SCHEMA_LABEL, + SSH_USER_EDIT, + SSH_USER_LABEL, + SSH_HOST_EDIT, + SSH_HOST_LABEL, + SSH_PRIVATE_KEY_FILE_EDIT, + SSH_PRIVATE_KEY_FILE_LABEL, + SSH_PRIVATE_KEY_PASSPHRASE_EDIT, + SSH_PRIVATE_KEY_PASSPHRASE_LABEL, + SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX, + SSH_KNOWN_HOSTS_FILE_EDIT, + SSH_KNOWN_HOSTS_FILE_LABEL, APP_NAME_EDIT, APP_NAME_LABEL, LOGIN_TIMEOUT_SEC_EDIT, @@ -185,6 +197,16 @@ namespace ignite */ int CreateAuthSettingsGroup(int posX, int posY, int sizeX); + /** + * Create internal SSH tunnel settings group box. + * + * @param posX X position. + * @param posY Y position. + * @param sizeX Width. + * @return Size by Y. + */ + int CreateSshSettingsGroup(int posX, int posY, int sizeX); + /** * Create SSL settings group box. * @@ -214,6 +236,9 @@ namespace ignite /** Connection settings group box. */ std::auto_ptr connectionSettingsGroupBox; + /** SSH settings group box. */ + std::auto_ptr sshSettingsGroupBox; + /** SSL settings group box. */ std::auto_ptr sslSettingsGroupBox; @@ -241,6 +266,39 @@ namespace ignite /** DSN schema edit field. */ std::auto_ptr schemaEdit; + /** SSH user edit. */ + std::auto_ptr sshUserEdit; + + /** SSH user label. */ + std::auto_ptr sshUserLabel; + + /** SSH host edit. */ + std::auto_ptr sshHostEdit; + + /** SSH host label. */ + std::auto_ptr sshHostLabel; + + /** SSH private key file edit. */ + std::auto_ptr sshPrivateKeyFileEdit; + + /** SSH private key file label. */ + std::auto_ptr sshPrivateKeyFileLabel; + + /** SSH private key passphrase edit. */ + std::auto_ptr sshPrivateKeyPassphraseEdit; + + /** SSH private key passphrase label. */ + std::auto_ptr sshPrivateKeyPassphraseLabel; + + /** SSH strict host key checking checkBox. */ + std::auto_ptr sshStrictHostKeyCheckingCheckBox; + + /** SSH known host file edit. */ + std::auto_ptr sshKnownHostsFileEdit; + + /** SSH know host file label. */ + std::auto_ptr sshKnownHostsFileLabel; + /** Application name edit. */ std::auto_ptr appNameEdit; @@ -260,10 +318,10 @@ namespace ignite std::auto_ptr readPreferenceLabel; /** Replica set edit. */ - std::auto_ptr< Window > replicaSetEdit; + std::auto_ptr replicaSetEdit; /** Replica set label. */ - std::auto_ptr< Window > replicaSetLabel; + std::auto_ptr replicaSetLabel; /** Retry reads checkBox. */ std::auto_ptr retryReadsCheckBox; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 9a9f7e66d..3d6885f44 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -48,6 +48,19 @@ namespace ignite addressEdit(), schemaLabel(), schemaEdit(), + // internal SSH tunnel vars + sshUserLabel(), + sshUserEdit(), + sshHostLabel(), + sshHostEdit(), + sshPrivateKeyFileLabel(), + sshPrivateKeyFileEdit(), + sshPrivateKeyPassphraseLabel(), + sshPrivateKeyPassphraseEdit(), + sshStrictHostKeyCheckingCheckBox(), + sshKnownHostsFileLabel(), + sshKnownHostsFileEdit(), + // end of SSH vars appNameLabel(), appNameEdit(), readPreferenceLabel(), @@ -109,6 +122,7 @@ namespace ignite groupPosY += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosY, groupSizeY); groupPosY += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosY, groupSizeY); + groupPosY += INTERVAL + CreateSshSettingsGroup(MARGIN, groupPosY, groupSizeY); groupPosY += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosY, groupSizeY); groupPosY += INTERVAL + CreateAdditionalSettingsGroup(MARGIN, groupPosY, groupSizeY); // test: if above code is commented out, additional settings shouldn't appear in config window. Result: Yes test success. @@ -220,6 +234,10 @@ namespace ignite return rowPos - posY; } + int DsnConfigurationWindow::CreateSshSettingsGroup(int posX, int posY, int sizeX) + { + } + int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) { // TODO: rename function name from Ssl to TLS after UI works From 07de6efed0b335f229809e4e4b1dda4fefa0acd4 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 14:03:42 -0800 Subject: [PATCH 029/100] [AD-522] add function definition for SSH Tunnel added SSH User, SSH Host. SSH Strict Host Key Checking, and SSH Known Hosts File onto the UI. However, the code to save the written values would be done in later commits. --- .../system/ui/dsn_configuration_window.cpp | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 3d6885f44..4c156b873 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -236,6 +236,53 @@ namespace ignite int DsnConfigurationWindow::CreateSshSettingsGroup(int posX, int posY, int sizeX) { + enum { LABEL_WIDTH = 120 }; // -AL- copied from above function + + int labelPosX = posX + INTERVAL; + + int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL; + int editPosX = labelPosX + LABEL_WIDTH + INTERVAL; + + int rowPos = posY + 2 * INTERVAL; + + int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; + + const char* val = config.GetSshUser().c_str(); + + sshUserLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSH user :", ChildId::SSH_USER_LABEL); + sshUserEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_USER_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetSshHost().c_str(); + + sshHostLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "SSH host :", ChildId::SSH_HOST_LABEL); + sshHostEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, ChildId::SSH_HOST_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + sshStrictHostKeyCheckingCheckBox = CreateCheckBox( + labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "SSH strict host key checking", + ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX, config.IsSshStrictHostKeyChecking()); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetSshKnownHostsFile().c_str(); + + sshKnownHostsFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "SSH known hosts:", ChildId::SSH_KNOWN_HOSTS_FILE_LABEL); + sshKnownHostsFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, + ChildId::SSH_KNOWN_HOST_FILE_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + sshSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, + "Internal SSH Tunnel settings", + ChildId::SSH_SETTINGS_GROUP_BOX); + + return rowPos - posY; } int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) From f2e92a497c072b83e5ec9873e94e7a7e5710f06d Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 14:04:54 -0800 Subject: [PATCH 030/100] [AD-522] code draft for configuration.cpp add draft variable definition to Enable ssh tunnel boolean value --- src/odbc/src/config/configuration.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index a0d11bc0b..8fe0e7567 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -45,13 +45,14 @@ namespace ignite const bool Configuration::DefaultValue::tlsAllowInvalidHostnames = false; // needs to be set to true for SSH; TLS Allow Invalid Hostnames const std::string Configuration::DefaultValue::tlsCaFile = ""; //renamed from SSL CA file - // Schema Generation and Discovery options // need to add to UI // I think I need a new group setting thing + // Schema Generation and Discovery options // need to add to UI // I think I need a new group setting function const std::string Configuration::DefaultValue::scanMethod = "random"; const int32_t Configuration::DefaultValue::scanLimit = 1000; const std::string Configuration::DefaultValue::schemaName = "_default"; const bool Configuration::DefaultValue::refreshSchema = false; // Internal SSH Tunnel options // need to add to UI + // const bool Configuration::DefaultValue::sshEnable = false; const std::string Configuration::DefaultValue::sshUser = ""; const std::string Configuration::DefaultValue::sshHost = ""; const std::string Configuration::DefaultValue::sshPrivateKeyFile = ""; From fbaa1033fd3ec3b06749e739a3ab284f8c634ecd Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 14:20:41 -0800 Subject: [PATCH 031/100] Revert "change defaultFetchSize to fetchSize in configuration.h" This reverts commit f311e3bc7df1fd66d7be66c8e60170a41d078c18. --- .../include/ignite/odbc/config/configuration.h | 10 +++++----- src/odbc/src/config/configuration.cpp | 18 +++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index 695f257e7..c5a021c2d 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -137,7 +137,7 @@ namespace ignite // static const ProtocolVersion& protocolVersion; /** Default value for fetch results page size attribute. */ - static const int32_t fetchSize; + static const int32_t defaultFetchSize; /** Default value for nestedTxMode attribute. */ static const NestedTxMode::Type nestedTxMode; @@ -703,21 +703,21 @@ namespace ignite * * @return Fetch results page size. */ - int32_t GetFetchSize() const; + int32_t GetDefaultFetchSize() const; /** * Set fetch results page size. * * @param size Fetch results page size. */ - void SetFetchSize(int32_t size); + void SetDefaultFetchSize(int32_t size); /** * Check if the value set. * * @return @true if the value set. */ - bool IsFetchSizeSet() const; + bool IsDefaultFetchSizeSet() const; /** * Get argument map. @@ -816,7 +816,7 @@ namespace ignite SettableValue refreshSchema; /** Request and response page size. */ - SettableValue fetchSize; + SettableValue defaultFetchSize; }; template<> diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 8fe0e7567..50aedf5c7 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -66,7 +66,7 @@ namespace ignite const std::string Configuration::DefaultValue::readPreference = ""; const std::string Configuration::DefaultValue::replicaSet = ""; const bool Configuration::DefaultValue::retryReads = true; - const int32_t Configuration::DefaultValue::fetchSize = 2000; + const int32_t Configuration::DefaultValue::defaultFetchSize = 2000; const NestedTxMode::Type Configuration::DefaultValue::nestedTxMode = NestedTxMode::AI_ERROR; // remove @@ -97,7 +97,7 @@ namespace ignite scanLimit(DefaultValue::scanLimit), schemaName(DefaultValue::schemaName), refreshSchema(DefaultValue::refreshSchema), - fetchSize(DefaultValue::fetchSize) + defaultFetchSize(DefaultValue::defaultFetchSize) { // No-op. } @@ -520,19 +520,19 @@ namespace ignite return password.IsSet(); } - int32_t Configuration::GetFetchSize() const + int32_t Configuration::GetDefaultFetchSize() const { - return fetchSize.GetValue(); + return defaultFetchSize.GetValue(); } - void Configuration::SetFetchSize(int32_t size) + void Configuration::SetDefaultFetchSize(int32_t size) { - this->fetchSize.SetValue(size); + this->defaultFetchSize.SetValue(size); } - bool Configuration::IsFetchSizeSet() const + bool Configuration::IsDefaultFetchSizeSet() const { - return fetchSize.IsSet(); + return defaultFetchSize.IsSet(); } void Configuration::ToMap(ArgumentMap& res) const @@ -564,7 +564,7 @@ namespace ignite AddToMap(res, ConnectionStringParser::Key::scanLimit, scanLimit); AddToMap(res, ConnectionStringParser::Key::schemaName, schemaName); AddToMap(res, ConnectionStringParser::Key::refreshSchema, refreshSchema); - AddToMap(res, ConnectionStringParser::Key::fetchSize, fetchSize); + AddToMap(res, ConnectionStringParser::Key::defaultFetchSize, defaultFetchSize); } template<> From 124b7256d8f96fb31363aa2efb0423b115b11b0a Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 14:21:28 -0800 Subject: [PATCH 032/100] Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h" This reverts commit 2bcd2a492bd69fbde5de986a03c5a407a729ba47. --- .../ignite/odbc/config/connection_string_parser.h | 2 +- src/odbc/src/config/connection_string_parser.cpp | 6 +++--- src/odbc/src/dsn_config.cpp | 10 +++++----- src/odbc/src/query/batch_query.cpp | 2 +- src/odbc/src/query/data_query.cpp | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index ba557d6c3..27e4f48d2 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -120,7 +120,7 @@ namespace ignite static const std::string protocolVersion; /** Connection attribute keyword for fetch results page size attribute. */ - static const std::string fetchSize; + static const std::string defaultFetchSize; /** Connection attribute keyword for sslMode attribute. */ static const std::string sslMode; diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index a05e2a530..308bb225b 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -57,7 +57,7 @@ namespace ignite const std::string ConnectionStringParser::Key::scanLimit = "scan_limit"; const std::string ConnectionStringParser::Key::schemaName = "schema_name"; const std::string ConnectionStringParser::Key::refreshSchema = "refresh_schema"; - const std::string ConnectionStringParser::Key::fetchSize = "fetch_size"; + const std::string ConnectionStringParser::Key::defaultFetchSize = "default_fetch_size"; const std::string ConnectionStringParser::Key::uid = "uid"; const std::string ConnectionStringParser::Key::pwd = "pwd"; @@ -399,7 +399,7 @@ namespace ignite cfg.SetTls(res == BoolParseResult::AI_TRUE); } - else if (lKey == Key::fetchSize) + else if (lKey == Key::defaultFetchSize) { if (!common::AllDigits(value)) { @@ -443,7 +443,7 @@ namespace ignite return; } - cfg.SetFetchSize(static_cast(numValue)); + cfg.SetDefaultFetchSize(static_cast(numValue)); } else if (lKey == Key::tlsCaFile) { diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 9b02548ed..6526a38bd 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -219,7 +219,7 @@ namespace ignite if (scanLimit.IsSet() && !config.IsScanLimitSet() && scanLimit.GetValue() > 0) - config.SetFetchSize(scanLimit.GetValue()); + config.SetDefaultFetchSize(scanLimit.GetValue()); SettableValue schemaName = ReadDsnString(dsn, ConnectionStringParser::Key::schemaName); @@ -231,11 +231,11 @@ namespace ignite if (refreshSchema.IsSet() && !config.IsSchemaRefreshSet()) config.SetSchemaRefresh(refreshSchema.GetValue()); - SettableValue fetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::fetchSize); + SettableValue defaultFetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::defaultFetchSize); - if (fetchSize.IsSet() && !config.IsFetchSizeSet() - && fetchSize.GetValue() > 0) - config.SetFetchSize(fetchSize.GetValue()); + if (defaultFetchSize.IsSet() && !config.IsDefaultFetchSizeSet() + && defaultFetchSize.GetValue() > 0) + config.SetDefaultFetchSize(defaultFetchSize.GetValue()); } } } diff --git a/src/odbc/src/query/batch_query.cpp b/src/odbc/src/query/batch_query.cpp index 6a82d690e..7390b4f59 100644 --- a/src/odbc/src/query/batch_query.cpp +++ b/src/odbc/src/query/batch_query.cpp @@ -52,7 +52,7 @@ namespace ignite if (executed) Close(); - int32_t maxPageSize = connection.GetConfiguration().GetFetchSize(); + int32_t maxPageSize = connection.GetConfiguration().GetDefaultFetchSize(); int32_t rowNum = params.GetParamSetSize(); SqlResult::Type res; diff --git a/src/odbc/src/query/data_query.cpp b/src/odbc/src/query/data_query.cpp index 28a9ab72f..d5c4d6a6d 100644 --- a/src/odbc/src/query/data_query.cpp +++ b/src/odbc/src/query/data_query.cpp @@ -193,7 +193,7 @@ namespace ignite if (affected >= 0) return affected; - return connection.GetConfiguration().GetFetchSize(); + return connection.GetConfiguration().GetDefaultFetchSize(); } SqlResult::Type DataQuery::NextResultSet() @@ -320,7 +320,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetFetchSize()); + QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); QueryFetchResponse rsp(*resultPage); try @@ -361,7 +361,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetFetchSize()); + QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); QueryMoreResultsResponse rsp(*resultPage); try From 1ce78789f90f2dee83c4bde19ef4dd9a0dfa4639 Mon Sep 17 00:00:00 2001 From: Bruce Irschick Date: Thu, 20 Jan 2022 14:27:33 -0800 Subject: [PATCH 033/100] [AD-517] * Change the C++ version to use to compile. --- src/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d996aafd9..dc04f9fda 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,7 +21,7 @@ project(Ignite.C++ VERSION 2.13.0.58917) include("${CMAKE_CURRENT_SOURCE_DIR}/modules/code-coverage.cmake") add_code_coverage_all_targets(EXCLUDE odbc-test) -set(CMAKE_CXX_STANDARD 98) +set(CMAKE_CXX_STANDARD 11) set(CMAKE_PROJECT_VERSION ${PROJECT_VERSION}) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") From 827f2bcf15dea7ad4ed8cd01e527412a4302444b Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 14:28:56 -0800 Subject: [PATCH 034/100] [AD-522] change fetchSize to defaultFetchSize on configuration window for consistency with JDBC driver --- .../odbc/system/ui/dsn_configuration_window.h | 12 +++++----- .../system/ui/dsn_configuration_window.cpp | 22 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index e17d0270c..bc1750d37 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -72,8 +72,8 @@ namespace ignite REPLICA_SET_EDIT, REPLICA_SET_LABEL, RETRY_READS_CHECK_BOX, - FETCH_SIZE_EDIT, - FETCH_SIZE_LABEL, + DEFAULT_FETCH_SIZE_EDIT, + DEFAULT_FETCH_SIZE_LABEL, PROTOCOL_VERSION_LABEL, PROTOCOL_VERSION_COMBO_BOX, NESTED_TX_MODE_LABEL, @@ -326,11 +326,11 @@ namespace ignite /** Retry reads checkBox. */ std::auto_ptr retryReadsCheckBox; - /** Fetch size edit. */ - std::auto_ptr fetchSizeEdit; + /** Default fetch size edit. */ + std::auto_ptr defaultFetchSizeEdit; - /** Fetch size label. */ - std::auto_ptr fetchSizeLabel; + /** Default fetch size label. */ + std::auto_ptr defaultFetchSizeLabel; /** Protocol version edit field. */ std::auto_ptr protocolVersionLabel; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 4c156b873..0ed0b9342 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -68,8 +68,8 @@ namespace ignite replicaSetLabel(), replicaSetEdit(), retryReadsCheckBox(), - fetchSizeLabel(), - fetchSizeEdit(), + defaultFetchSizeLabel(), + defaultFetchSizeEdit(), protocolVersionLabel(), protocolVersionComboBox(), userLabel(), @@ -274,7 +274,7 @@ namespace ignite sshKnownHostsFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSH known hosts:", ChildId::SSH_KNOWN_HOSTS_FILE_LABEL); sshKnownHostsFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, - ChildId::SSH_KNOWN_HOST_FILE_EDIT); + ChildId::SSH_KNOWN_HOSTS_FILE_EDIT); rowPos += INTERVAL + ROW_HEIGHT; @@ -381,13 +381,13 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - tmp = common::LexicalCast(config.GetFetchSize()); + tmp = common::LexicalCast(config.GetDefaultFetchSize()); val = tmp.c_str(); - fetchSizeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, - ROW_HEIGHT, "Fetch size:", ChildId::FETCH_SIZE_LABEL); + defaultFetchSizeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, + ROW_HEIGHT, "Fetch size:", ChildId::DEFAULT_FETCH_SIZE_LABEL); - fetchSizeEdit = CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT, val, ChildId::FETCH_SIZE_EDIT, ES_NUMBER); + defaultFetchSizeEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, ChildId::DEFAULT_FETCH_SIZE_EDIT, ES_NUMBER); rowPos += INTERVAL + ROW_HEIGHT; @@ -587,13 +587,13 @@ namespace ignite std::string fetchSizeStr; - fetchSizeEdit->GetText(fetchSizeStr); + defaultFetchSizeEdit->GetText(fetchSizeStr); int32_t fetchSize = common::LexicalCast< int32_t >(fetchSizeStr); if (fetchSize <= 0) - fetchSize = config.GetFetchSize(); + fetchSize = config.GetDefaultFetchSize(); LOG_MSG("Retrieving arguments:"); LOG_MSG("App name: " << appNameStr); @@ -608,7 +608,7 @@ namespace ignite cfg.SetReadPreference(readPreferenceStr); cfg.SetReplicaSet(replicaSetStr); cfg.SetRetryReads(retryReads); - cfg.SetFetchSize(fetchSize); + cfg.SetDefaultFetchSize(fetchSize); } } From 5c015497b4f7836f03f8daf870b4808be9bb1edb Mon Sep 17 00:00:00 2001 From: Bruce Irschick Date: Thu, 20 Jan 2022 14:56:36 -0800 Subject: [PATCH 035/100] [AD-517] * Changed checks.yml so that it doesn't fail on code review errors. --- .github/workflows/checks.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index ffa776c01..d3fec3b10 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -10,6 +10,5 @@ jobs: - uses: actions/checkout@v2 - uses: ZedThree/clang-tidy-review@v0.7.0 id: review - - if: steps.review.outputs.total_comments > 0 - run: exit 1 + continue-on-error: true From aa7731a67f123c8942b89cba8334efe15776f6c8 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 15:06:55 -0800 Subject: [PATCH 036/100] Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h"" This reverts commit 124b7256d8f96fb31363aa2efb0423b115b11b0a. --- .../ignite/odbc/config/connection_string_parser.h | 2 +- src/odbc/src/config/connection_string_parser.cpp | 6 +++--- src/odbc/src/dsn_config.cpp | 10 +++++----- src/odbc/src/query/batch_query.cpp | 2 +- src/odbc/src/query/data_query.cpp | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index 27e4f48d2..ba557d6c3 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -120,7 +120,7 @@ namespace ignite static const std::string protocolVersion; /** Connection attribute keyword for fetch results page size attribute. */ - static const std::string defaultFetchSize; + static const std::string fetchSize; /** Connection attribute keyword for sslMode attribute. */ static const std::string sslMode; diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 308bb225b..a05e2a530 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -57,7 +57,7 @@ namespace ignite const std::string ConnectionStringParser::Key::scanLimit = "scan_limit"; const std::string ConnectionStringParser::Key::schemaName = "schema_name"; const std::string ConnectionStringParser::Key::refreshSchema = "refresh_schema"; - const std::string ConnectionStringParser::Key::defaultFetchSize = "default_fetch_size"; + const std::string ConnectionStringParser::Key::fetchSize = "fetch_size"; const std::string ConnectionStringParser::Key::uid = "uid"; const std::string ConnectionStringParser::Key::pwd = "pwd"; @@ -399,7 +399,7 @@ namespace ignite cfg.SetTls(res == BoolParseResult::AI_TRUE); } - else if (lKey == Key::defaultFetchSize) + else if (lKey == Key::fetchSize) { if (!common::AllDigits(value)) { @@ -443,7 +443,7 @@ namespace ignite return; } - cfg.SetDefaultFetchSize(static_cast(numValue)); + cfg.SetFetchSize(static_cast(numValue)); } else if (lKey == Key::tlsCaFile) { diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 6526a38bd..9b02548ed 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -219,7 +219,7 @@ namespace ignite if (scanLimit.IsSet() && !config.IsScanLimitSet() && scanLimit.GetValue() > 0) - config.SetDefaultFetchSize(scanLimit.GetValue()); + config.SetFetchSize(scanLimit.GetValue()); SettableValue schemaName = ReadDsnString(dsn, ConnectionStringParser::Key::schemaName); @@ -231,11 +231,11 @@ namespace ignite if (refreshSchema.IsSet() && !config.IsSchemaRefreshSet()) config.SetSchemaRefresh(refreshSchema.GetValue()); - SettableValue defaultFetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::defaultFetchSize); + SettableValue fetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::fetchSize); - if (defaultFetchSize.IsSet() && !config.IsDefaultFetchSizeSet() - && defaultFetchSize.GetValue() > 0) - config.SetDefaultFetchSize(defaultFetchSize.GetValue()); + if (fetchSize.IsSet() && !config.IsFetchSizeSet() + && fetchSize.GetValue() > 0) + config.SetFetchSize(fetchSize.GetValue()); } } } diff --git a/src/odbc/src/query/batch_query.cpp b/src/odbc/src/query/batch_query.cpp index 7390b4f59..6a82d690e 100644 --- a/src/odbc/src/query/batch_query.cpp +++ b/src/odbc/src/query/batch_query.cpp @@ -52,7 +52,7 @@ namespace ignite if (executed) Close(); - int32_t maxPageSize = connection.GetConfiguration().GetDefaultFetchSize(); + int32_t maxPageSize = connection.GetConfiguration().GetFetchSize(); int32_t rowNum = params.GetParamSetSize(); SqlResult::Type res; diff --git a/src/odbc/src/query/data_query.cpp b/src/odbc/src/query/data_query.cpp index d5c4d6a6d..28a9ab72f 100644 --- a/src/odbc/src/query/data_query.cpp +++ b/src/odbc/src/query/data_query.cpp @@ -193,7 +193,7 @@ namespace ignite if (affected >= 0) return affected; - return connection.GetConfiguration().GetDefaultFetchSize(); + return connection.GetConfiguration().GetFetchSize(); } SqlResult::Type DataQuery::NextResultSet() @@ -320,7 +320,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); + QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetFetchSize()); QueryFetchResponse rsp(*resultPage); try @@ -361,7 +361,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); + QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetFetchSize()); QueryMoreResultsResponse rsp(*resultPage); try From 20a84063dcf61ea2301ea8b6b145289fa71f42eb Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 15:08:26 -0800 Subject: [PATCH 037/100] [AD-522] make TLS allow invalid hostnames checkbox enabled only when tls Check box is checked --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 0ed0b9342..03131910c 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -279,7 +279,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; sshSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "Internal SSH Tunnel settings", + "Internal SSH tunnel settings", ChildId::SSH_SETTINGS_GROUP_BOX); return rowPos - posY; @@ -321,6 +321,7 @@ namespace ignite sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "TLS/SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX); + tlsCheckBox->SetEnabled(tlsCheckBox->IsChecked()); tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); return rowPos - posY; @@ -434,6 +435,8 @@ namespace ignite case ChildId::TLS_CHECK_BOX: { tlsCheckBox->SetChecked(!tlsCheckBox->IsChecked()); + tlsAllowInvalidHostnamesCheckBox + ->SetEnabled(tlsCheckBox->IsChecked()); tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); break; From 0b1a768a349dc0c737a854cbaecff0629c52371d Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 20 Jan 2022 15:17:41 -0800 Subject: [PATCH 038/100] Revert "Revert "[AD-522] bugfix - change DefaultFetchSize to fetchSize in all related files to be consistent with configuration.h""" This reverts commit aa7731a67f123c8942b89cba8334efe15776f6c8. --- .../ignite/odbc/config/connection_string_parser.h | 2 +- src/odbc/src/config/connection_string_parser.cpp | 6 +++--- src/odbc/src/dsn_config.cpp | 10 +++++----- src/odbc/src/query/batch_query.cpp | 2 +- src/odbc/src/query/data_query.cpp | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index ba557d6c3..27e4f48d2 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -120,7 +120,7 @@ namespace ignite static const std::string protocolVersion; /** Connection attribute keyword for fetch results page size attribute. */ - static const std::string fetchSize; + static const std::string defaultFetchSize; /** Connection attribute keyword for sslMode attribute. */ static const std::string sslMode; diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index a05e2a530..308bb225b 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -57,7 +57,7 @@ namespace ignite const std::string ConnectionStringParser::Key::scanLimit = "scan_limit"; const std::string ConnectionStringParser::Key::schemaName = "schema_name"; const std::string ConnectionStringParser::Key::refreshSchema = "refresh_schema"; - const std::string ConnectionStringParser::Key::fetchSize = "fetch_size"; + const std::string ConnectionStringParser::Key::defaultFetchSize = "default_fetch_size"; const std::string ConnectionStringParser::Key::uid = "uid"; const std::string ConnectionStringParser::Key::pwd = "pwd"; @@ -399,7 +399,7 @@ namespace ignite cfg.SetTls(res == BoolParseResult::AI_TRUE); } - else if (lKey == Key::fetchSize) + else if (lKey == Key::defaultFetchSize) { if (!common::AllDigits(value)) { @@ -443,7 +443,7 @@ namespace ignite return; } - cfg.SetFetchSize(static_cast(numValue)); + cfg.SetDefaultFetchSize(static_cast(numValue)); } else if (lKey == Key::tlsCaFile) { diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 9b02548ed..6526a38bd 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -219,7 +219,7 @@ namespace ignite if (scanLimit.IsSet() && !config.IsScanLimitSet() && scanLimit.GetValue() > 0) - config.SetFetchSize(scanLimit.GetValue()); + config.SetDefaultFetchSize(scanLimit.GetValue()); SettableValue schemaName = ReadDsnString(dsn, ConnectionStringParser::Key::schemaName); @@ -231,11 +231,11 @@ namespace ignite if (refreshSchema.IsSet() && !config.IsSchemaRefreshSet()) config.SetSchemaRefresh(refreshSchema.GetValue()); - SettableValue fetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::fetchSize); + SettableValue defaultFetchSize = ReadDsnInt(dsn, ConnectionStringParser::Key::defaultFetchSize); - if (fetchSize.IsSet() && !config.IsFetchSizeSet() - && fetchSize.GetValue() > 0) - config.SetFetchSize(fetchSize.GetValue()); + if (defaultFetchSize.IsSet() && !config.IsDefaultFetchSizeSet() + && defaultFetchSize.GetValue() > 0) + config.SetDefaultFetchSize(defaultFetchSize.GetValue()); } } } diff --git a/src/odbc/src/query/batch_query.cpp b/src/odbc/src/query/batch_query.cpp index 6a82d690e..7390b4f59 100644 --- a/src/odbc/src/query/batch_query.cpp +++ b/src/odbc/src/query/batch_query.cpp @@ -52,7 +52,7 @@ namespace ignite if (executed) Close(); - int32_t maxPageSize = connection.GetConfiguration().GetFetchSize(); + int32_t maxPageSize = connection.GetConfiguration().GetDefaultFetchSize(); int32_t rowNum = params.GetParamSetSize(); SqlResult::Type res; diff --git a/src/odbc/src/query/data_query.cpp b/src/odbc/src/query/data_query.cpp index 28a9ab72f..d5c4d6a6d 100644 --- a/src/odbc/src/query/data_query.cpp +++ b/src/odbc/src/query/data_query.cpp @@ -193,7 +193,7 @@ namespace ignite if (affected >= 0) return affected; - return connection.GetConfiguration().GetFetchSize(); + return connection.GetConfiguration().GetDefaultFetchSize(); } SqlResult::Type DataQuery::NextResultSet() @@ -320,7 +320,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetFetchSize()); + QueryFetchRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); QueryFetchResponse rsp(*resultPage); try @@ -361,7 +361,7 @@ namespace ignite { std::auto_ptr resultPage(new ResultPage()); - QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetFetchSize()); + QueryMoreResultsRequest req(cursor->GetQueryId(), connection.GetConfiguration().GetDefaultFetchSize()); QueryMoreResultsResponse rsp(*resultPage); try From c34c5a2289f97b8e6ba05dd40cb59da963604615 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Thu, 20 Jan 2022 17:38:35 -0800 Subject: [PATCH 039/100] Improvements from review --- .../odbc/config/connection_string_parser.h | 10 ++-------- src/odbc/src/config/configuration.cpp | 4 ++-- .../src/config/connection_string_parser.cpp | 5 ++--- src/odbc/src/dsn_config.cpp | 6 +++--- src/odbc/src/message.cpp | 20 ------------------- 5 files changed, 9 insertions(+), 36 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index f88411c7e..6693eb706 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -47,11 +47,8 @@ namespace ignite /** Connection attribute keyword for schema attribute. */ static const std::string database; - /** Connection attribute keyword for address attribute. */ - static const std::string address; - - /** Connection attribute keyword for server attribute. */ - static const std::string server; + /** Connection attribute keyword for hostname attribute. */ + static const std::string hostname; /** Connection attribute keyword for port attribute. */ static const std::string port; @@ -116,9 +113,6 @@ namespace ignite /** Connection attribute keyword for password attribute. */ static const std::string refreshSchema; - /** Connection attribute keyword for protocol version attribute. */ - static const std::string protocolVersion; - /** Connection attribute keyword for defaultFetchSize attribute. */ static const std::string defaultFetchSize; diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index c43d8262e..d6a6e2cb9 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -32,7 +32,7 @@ namespace ignite { const std::string Configuration::DefaultValue::dsn = "DocumentDB DSN"; - const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB Driver"; + const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB ODBC Driver"; const std::string Configuration::DefaultValue::database = ""; const std::string Configuration::DefaultValue::hostname = ""; const uint16_t Configuration::DefaultValue::port = 27017; @@ -520,7 +520,7 @@ namespace ignite AddToMap(res, ConnectionStringParser::Key::dsn, dsn); AddToMap(res, ConnectionStringParser::Key::driver, driver); AddToMap(res, ConnectionStringParser::Key::database, database); - AddToMap(res, ConnectionStringParser::Key::server, hostname); + AddToMap(res, ConnectionStringParser::Key::hostname, hostname); AddToMap(res, ConnectionStringParser::Key::port, port); AddToMap(res, ConnectionStringParser::Key::user, user); AddToMap(res, ConnectionStringParser::Key::password, password); diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 96ba6b58d..6d6cff010 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -34,8 +34,7 @@ namespace ignite const std::string ConnectionStringParser::Key::dsn = "dsn"; const std::string ConnectionStringParser::Key::driver = "driver"; const std::string ConnectionStringParser::Key::database = "database"; - const std::string ConnectionStringParser::Key::address = "address"; - const std::string ConnectionStringParser::Key::server = "hostname"; + const std::string ConnectionStringParser::Key::hostname = "hostname"; const std::string ConnectionStringParser::Key::port = "port"; const std::string ConnectionStringParser::Key::user = "user"; const std::string ConnectionStringParser::Key::password = "password"; @@ -151,7 +150,7 @@ namespace ignite { cfg.SetDatabase(value); } - else if (lKey == Key::server) + else if (lKey == Key::hostname) { EndPoint endpoint; diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index c9fd4a0fb..9b2b7ac91 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -104,10 +104,10 @@ namespace ignite void ReadDsnConfiguration(const char* dsn, Configuration& config, diagnostic::DiagnosticRecordStorage* diag) { - SettableValue server = ReadDsnString(dsn, ConnectionStringParser::Key::server); + SettableValue hostname = ReadDsnString(dsn, ConnectionStringParser::Key::hostname); - if (server.IsSet() && !config.IsHostnameSet()) - config.SetHostname(server.GetValue()); + if (hostname.IsSet() && !config.IsHostnameSet()) + config.SetHostname(hostname.GetValue()); SettableValue port = ReadDsnInt(dsn, ConnectionStringParser::Key::port); diff --git a/src/odbc/src/message.cpp b/src/odbc/src/message.cpp index 80b809205..138c91485 100644 --- a/src/odbc/src/message.cpp +++ b/src/odbc/src/message.cpp @@ -68,26 +68,6 @@ namespace ignite writer.WriteInt16(version.GetMaintenance()); writer.WriteInt8(ClientType::ODBC); - - /*writer.WriteBool(config.IsDistributedJoins()); - writer.WriteBool(config.IsEnforceJoinOrder()); - writer.WriteBool(config.IsReplicatedOnly()); - writer.WriteBool(config.IsCollocated()); - - if (version >= ProtocolVersion::VERSION_2_1_5) - writer.WriteBool(config.IsLazy()); - - if (version >= ProtocolVersion::VERSION_2_3_0) - writer.WriteBool(config.IsSkipReducerOnUpdate()); - - if (version >= ProtocolVersion::VERSION_2_5_0) - { - utility::WriteString(writer, config.GetUser()); - utility::WriteString(writer, config.GetPassword()); - } - - if (version >= ProtocolVersion::VERSION_2_7_0) - writer.WriteInt8(config.GetNestedTxMode());*/ } QueryExecuteRequest::QueryExecuteRequest(const std::string& schema, const std::string& sql, From 1a66e9b41364ad48683864806bfd8c40ae8680ab Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Thu, 20 Jan 2022 17:49:29 -0800 Subject: [PATCH 040/100] Updated comments --- .../odbc/config/connection_string_parser.h | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index 6693eb706..16b02d484 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -44,7 +44,7 @@ namespace ignite /** Connection attribute keyword for Driver attribute. */ static const std::string driver; - /** Connection attribute keyword for schema attribute. */ + /** Connection attribute keyword for database attribute. */ static const std::string database; /** Connection attribute keyword for hostname attribute. */ @@ -59,58 +59,58 @@ namespace ignite /** Connection attribute keyword for password attribute. */ static const std::string password; - /** Connection attribute keyword for username attribute. */ + /** Connection attribute keyword for appName attribute. */ static const std::string appName; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for loginTimeoutSec attribute. */ static const std::string loginTimeoutSec; - /** Connection attribute keyword for username attribute. */ + /** Connection attribute keyword for readPreference attribute. */ static const std::string readPreference; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for replicaSet attribute. */ static const std::string replicaSet; - /** Connection attribute keyword for username attribute. */ + /** Connection attribute keyword for retryReads attribute. */ static const std::string retryReads; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for tls attribute. */ static const std::string tls; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for tlsAllowInvalidHostnames attribute. */ static const std::string tlsAllowInvalidHostnames; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for tlsCaFile attribute. */ static const std::string tlsCaFile; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for sshUser attribute. */ static const std::string sshUser; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for sshHost attribute. */ static const std::string sshHost; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for sshPrivateKeyFile attribute. */ static const std::string sshPrivateKeyFile; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for sshPrivateKeyPassphrase attribute. */ static const std::string sshPrivateKeyPassphrase; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for sshStrictHostKeyChecking attribute. */ static const std::string sshStrictHostKeyChecking; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for sshKnownHostsFile attribute. */ static const std::string sshKnownHostsFile; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for scanMethod attribute. */ static const std::string scanMethod; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for scanLimit attribute. */ static const std::string scanLimit; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for schemaName attribute. */ static const std::string schemaName; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for refreshSchema attribute. */ static const std::string refreshSchema; /** Connection attribute keyword for defaultFetchSize attribute. */ From 961d8cbee303fd2b25ed64bc5589f9fb4d8ac23e Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Fri, 21 Jan 2022 10:36:14 -0800 Subject: [PATCH 041/100] [AD-522] save SSH values for re-read, make settings window into 2 columns Make ssl and additional settings groups to be on the right side of the column on the configuration window. This is subject to change later. I created the function void DsnConfigurationWindow::RetrieveSshParameters(config::Configuration& cfg) const to save SSH values. The width value in the DsnConfigurationWindow constructor is doubled from 360 to 720 and added the margin value. The margins currently look imbalanced on the settings box, and will be fixed in later commits. Make Ok button and Cancel buttons aligned with the right column bugfix - allow the SSH strict host checking checkbox to be checked on and off by adding the case ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX definition. --- .../odbc/system/ui/dsn_configuration_window.h | 8 + .../system/ui/dsn_configuration_window.cpp | 252 +++++++++++++++++- 2 files changed, 246 insertions(+), 14 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index bc1750d37..448ba71e2 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -161,6 +161,14 @@ namespace ignite */ void RetrieveAuthParameters(config::Configuration& cfg) const; + /** + * Retrieves current values from the SSH tunnel UI group and + * stores them to the specified configuration. + * + * @param cfg Configuration. + */ + void RetrieveSshParameters(config::Configuration& cfg) const; + /** * Retrieves current values from the SSL UI group and * stores them to the specified configuration. diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 03131910c..835982444 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -35,8 +35,11 @@ namespace ignite { // -AL- the constructor. No-op means no operation I think? DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config): CustomWindow(parent, "IgniteConfigureDsn", "Configure Amazon DocumentDB DSN Latest"), - width(360), - height(600), + //width(360), // original width:360. + height(600), // original height:600 + width(730), // double the original width + //width(360), + //height(800), connectionSettingsGroupBox(), sslSettingsGroupBox(), // has a create... function defined tlsCheckBox(), @@ -117,23 +120,33 @@ namespace ignite // the function that actually creates the UI -AL- void DsnConfigurationWindow::OnCreate() { - int groupPosY = MARGIN; - int groupSizeY = width - 2 * MARGIN; - - groupPosY += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosY, groupSizeY); - groupPosY += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosY, groupSizeY); - groupPosY += INTERVAL + CreateSshSettingsGroup(MARGIN, groupPosY, groupSizeY); - groupPosY += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosY, groupSizeY); - groupPosY += INTERVAL + CreateAdditionalSettingsGroup(MARGIN, groupPosY, groupSizeY); + int groupPosYLeft = MARGIN; + //int groupSizeY = width - 2 * MARGIN; // original + int groupSizeY = (width - 2 * MARGIN) / 2; + int posXRight = MARGIN + (width - MARGIN) / 2; + int groupPosYRight = MARGIN; + + groupPosYLeft += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); + groupPosYLeft += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); + groupPosYLeft += INTERVAL + CreateSshSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); + groupPosYRight += INTERVAL + CreateSslSettingsGroup(posXRight, groupPosYRight, groupSizeY); + groupPosYRight += INTERVAL + CreateAdditionalSettingsGroup(posXRight, groupPosYRight, groupSizeY); + //groupPosY += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosY, groupSizeY); + //groupPosY += INTERVAL + CreateAdditionalSettingsGroup(MARGIN, groupPosY, groupSizeY); // test: if above code is commented out, additional settings shouldn't appear in config window. Result: Yes test success. // what happens here is the height of each subgroup is calculated and appended to the y position of the buttons int cancelPosX = width - MARGIN - BUTTON_WIDTH; int okPosX = cancelPosX - INTERVAL - BUTTON_WIDTH; - okButton = CreateButton(okPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, "Ok", ChildId::OK_BUTTON); - cancelButton = CreateButton(cancelPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, + okButton = CreateButton(okPosX, groupPosYRight, BUTTON_WIDTH, BUTTON_HEIGHT, "Ok", ChildId::OK_BUTTON); + cancelButton = CreateButton(cancelPosX, groupPosYRight, BUTTON_WIDTH, BUTTON_HEIGHT, "Cancel", ChildId::CANCEL_BUTTON); + + // original code by Ignite + //okButton = CreateButton(okPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, "Ok", ChildId::OK_BUTTON); + //cancelButton = CreateButton(cancelPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, + // "Cancel", ChildId::CANCEL_BUTTON); } int DsnConfigurationWindow::CreateConnectionSettingsGroup(int posX, int posY, int sizeX) @@ -285,6 +298,8 @@ namespace ignite return rowPos - posY; } + // old SSL settings group code for 1 column config window + /* int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) { // TODO: rename function name from Ssl to TLS after UI works @@ -326,7 +341,52 @@ namespace ignite return rowPos - posY; } + */ + + int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) + { // TODO: rename function name from Ssl to TLS after UI works + + enum { LABEL_WIDTH = 120 }; + + int labelPosX = posX + INTERVAL; + + int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL; + int editPosX = labelPosX + LABEL_WIDTH + INTERVAL; + int rowPos = posY + 2 * INTERVAL; + + int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; + + tlsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + "TLS", ChildId::TLS_CHECK_BOX, config.IsTls()); + + tlsAllowInvalidHostnamesCheckBox = CreateCheckBox( + labelPosX + checkBoxSize + INTERVAL, rowPos, + checkBoxSize, ROW_HEIGHT, "TLS Allow Invalid Hostnames", + ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, + config.IsTlsAllowInvalidHostnames()); + + rowPos += INTERVAL + ROW_HEIGHT; + + const char* val = config.GetTlsCaFile().c_str(); + tlsCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "TLS Certificate Authority:", ChildId::TLS_CA_FILE_LABEL); + tlsCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, + ChildId::TLS_CA_FILE_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, + "TLS/SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX); + + tlsAllowInvalidHostnamesCheckBox->SetEnabled(tlsCheckBox->IsChecked()); + tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); + + return rowPos - posY; + } + + // old additional settings group code for 1 column window + /* int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) { enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also change it to the same @@ -359,6 +419,25 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; + // useful draft code for changing read preference into a mode (check JDBC page for available options) + // const char* val = sslModeStr.c_str(); + + // sslModeLabel = CreateLabel(labelPosX, rowPos, + // LABEL_WIDTH, ROW_HEIGHT, + // "SSL Mode:", ChildId::SSL_MODE_LABEL); + // sslModeComboBox = CreateComboBox(editPosX, rowPos, + // editSizeX, ROW_HEIGHT, + // "", ChildId::SSL_MODE_COMBO_BOX); + + // sslModeComboBox->AddString("disable"); + // sslModeComboBox->AddString("require"); + + // sslModeComboBox->SetSelection(sslMode); // set default + // value to require -AL- + + // rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight + // I believe + val = config.GetReadPreference().c_str(); readPreferenceLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, @@ -397,7 +476,117 @@ namespace ignite return rowPos - posY; } - + */ + + int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) { + enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also + // change it to the same + + int labelPosX = posX + INTERVAL; + + int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL; + int editPosX = labelPosX + LABEL_WIDTH + INTERVAL; + + int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; + + int rowPos = posY + 2 * INTERVAL; + + const char* val = config.GetApplicationName().c_str(); + + appNameLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Application Name:", ChildId::APP_NAME_LABEL); + appNameEdit = + CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, + ChildId::APP_NAME_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + std::string tmp = common::LexicalCast< std::string >( + config.GetLoginTimeoutSeconds()); + val = tmp.c_str(); + loginTimeoutSecLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Login Timeout (s):", ChildId::LOGIN_TIMEOUT_SEC_LABEL); + + loginTimeoutSecEdit = CreateEdit( + editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::LOGIN_TIMEOUT_SEC_EDIT, ES_NUMBER); + + rowPos += INTERVAL + ROW_HEIGHT; + + // useful draft code for changing read preference into a + // mode (check JDBC page for available options) const char* + // val = sslModeStr.c_str(); + + // sslModeLabel = CreateLabel(labelPosX, rowPos, + // LABEL_WIDTH, ROW_HEIGHT, + // "SSL Mode:", ChildId::SSL_MODE_LABEL); + // sslModeComboBox = CreateComboBox(editPosX, rowPos, + // editSizeX, ROW_HEIGHT, + // "", ChildId::SSL_MODE_COMBO_BOX); + + // sslModeComboBox->AddString("disable"); + // sslModeComboBox->AddString("require"); + + // sslModeComboBox->SetSelection(sslMode); // set default + // value to require -AL- + + // rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight + // I believe + + val = config.GetReadPreference().c_str(); + + readPreferenceLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Read preference:", ChildId::READ_PREFERENCE_LABEL); + readPreferenceEdit = CreateEdit( + editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::READ_PREFERENCE_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetReplicaSet().c_str(); + + replicaSetLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Replica Set:", ChildId::REPLICA_SET_LABEL); + replicaSetEdit = + CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, + ChildId::REPLICA_SET_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + retryReadsCheckBox = CreateCheckBox( + labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + "Retry Reads", ChildId::RETRY_READS_CHECK_BOX, + config.IsRetryReads()); + + rowPos += INTERVAL + ROW_HEIGHT; + + tmp = common::LexicalCast< std::string >( + config.GetDefaultFetchSize()); + val = tmp.c_str(); + defaultFetchSizeLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Fetch size:", ChildId::DEFAULT_FETCH_SIZE_LABEL); + + defaultFetchSizeEdit = CreateEdit( + editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::DEFAULT_FETCH_SIZE_EDIT, ES_NUMBER); + + rowPos += INTERVAL + ROW_HEIGHT; + + additionalSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, + rowPos - posY, "Additional settings", + ChildId::ADDITIONAL_SETTINGS_GROUP_BOX); + + return rowPos - posY; + } + + bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) @@ -432,6 +621,13 @@ namespace ignite break; } + case ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX: + { + sshStrictHostKeyCheckingCheckBox + ->SetChecked(!sshStrictHostKeyCheckingCheckBox->IsChecked()); + break; + } + case ChildId::TLS_CHECK_BOX: { tlsCheckBox->SetChecked(!tlsCheckBox->IsChecked()); @@ -546,6 +742,34 @@ namespace ignite cfg.SetPassword(password); } + void DsnConfigurationWindow::RetrieveSshParameters(config::Configuration& cfg) const + { + std::string sshUserStr; + std::string sshHostStr; + std::string sshPrivateKeyFileStr; + std::string sshPrivateKeyPassphraseStr; + std::string sshKnownHostsFileStr; + + sshUserEdit->GetText(sshUserStr); + sshHostEdit->GetText(sshHostStr); + //sshPrivateKeyFileEdit->GetText(sshPrivateKeyFileStr); + //sshPrivateKeyPassphraseEdit->GetText(sshPrivateKeyPassphraseStr); + sshKnownHostsFileEdit->GetText(sshKnownHostsFileStr); + + bool sshStrictHostKeyChecking = sshStrictHostKeyCheckingCheckBox->IsChecked(); + + LOG_MSG("SSH user: " << sshUserStr); + LOG_MSG("SSH host: " << sshHostStr); + LOG_MSG("SSH known hosts file: " << sshKnownHostsFileStr); + LOG_MSG("SSH strict host key checking: " << (sshStrictHostKeyChecking ? "true" : "false")); + + cfg.SetSshUser(sshUserStr); + cfg.SetSshHost(sshHostStr); + cfg.SetSshKnownHostsFile(sshKnownHostsFileStr); + cfg.SetSshStrictHostKeyChecking(sshStrictHostKeyChecking); + + } + void DsnConfigurationWindow::RetrieveSslParameters(config::Configuration& cfg) const { @@ -557,7 +781,7 @@ namespace ignite LOG_MSG("TLS/SSL Encryption: " << (tls ? "true" : "false")); LOG_MSG("tls Allow Invalid Hostnames: " << (tlsAllowInvalidHostnames ? "true" : "false")); - LOG_MSG("TLS CA: " << tlsCaStr); + LOG_MSG("TLS CA (Certificate Authority): " << tlsCaStr); cfg.SetTls(tls); cfg.SetTlsAllowInvalidHostnames(tlsAllowInvalidHostnames); From adaf439164d3fcfde1287442d079b339dd6c6283 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Fri, 21 Jan 2022 11:29:59 -0800 Subject: [PATCH 042/100] Removed includes no longer being used in configuration.h --- src/odbc/include/ignite/odbc/config/configuration.h | 5 +---- src/odbc/include/ignite/odbc/connection.h | 1 + .../include/ignite/odbc/system/ui/dsn_configuration_window.h | 4 ++++ src/odbc/src/config/connection_string_parser.cpp | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index a7b87ad5c..e8381eb31 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -22,11 +22,8 @@ #include #include -#include "ignite/odbc/protocol_version.h" #include "ignite/odbc/config/settable_value.h" -#include "ignite/odbc/ssl_mode.h" -#include "ignite/odbc/end_point.h" -#include "ignite/odbc/nested_tx_mode.h" +#include "ignite/odbc/diagnostic/diagnosable.h" #include "ignite/odbc/read_preference.h" #include "ignite/odbc/scan_method.h" diff --git a/src/odbc/include/ignite/odbc/connection.h b/src/odbc/include/ignite/odbc/connection.h index b670ee074..3fefc8e33 100644 --- a/src/odbc/include/ignite/odbc/connection.h +++ b/src/odbc/include/ignite/odbc/connection.h @@ -30,6 +30,7 @@ #include "ignite/odbc/diagnostic/diagnosable_adapter.h" #include "ignite/odbc/streaming/streaming_context.h" #include "ignite/odbc/odbc_error.h" +#include "ignite/odbc/end_point.h" namespace ignite { diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 77974ade3..26acd47ac 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -20,6 +20,10 @@ #include "ignite/odbc/config/configuration.h" #include "ignite/odbc/system/ui/custom_window.h" +// TODO: Removed these from configuration.h since no longer used. Moved here since they are still referenced. Remove when no longer needed. +#include "ignite/odbc/nested_tx_mode.h" +#include "ignite/odbc/protocol_version.h" +#include "ignite/odbc/ssl_mode.h" namespace ignite { diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 6d6cff010..b6e7908fc 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -20,10 +20,10 @@ #include "ignite/common/utils.h" #include "ignite/odbc/utility.h" -#include "ignite/odbc/ssl_mode.h" +//#include "ignite/odbc/ssl_mode.h" #include "ignite/odbc/config/connection_string_parser.h" #include "ignite/odbc/config/config_tools.h" -#include "ignite/odbc/nested_tx_mode.h" +//#include "ignite/odbc/nested_tx_mode.h" namespace ignite { From 44f5c70159bc22ad6b98a4d5ba2a21f49faae3eb Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Fri, 21 Jan 2022 13:54:05 -0800 Subject: [PATCH 043/100] Some formatting improvements --- src/odbc/include/ignite/odbc/config/configuration.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index e8381eb31..ee52f697c 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -647,7 +647,7 @@ namespace ignite /** * Get refresh schema flag. * - * @return Password. + * @return @true if refreshing schema is enabled. */ bool IsRefreshSchema() const; From b9b2d031fe39ebf1421200c2cb2d38518850c4ab Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Fri, 21 Jan 2022 14:09:33 -0800 Subject: [PATCH 044/100] [Ad-522] add sshEnable variable in DSN config - added sshEnable variable definition and getter/setter for sshEnable. - added code for parsing sshEnable in the connection string parser --- .../ignite/odbc/config/configuration.h | 27 +++++++++++++++++++ .../odbc/config/connection_string_parser.h | 3 +++ src/odbc/src/config/configuration.cpp | 15 ++++++++++- .../src/config/connection_string_parser.cpp | 20 ++++++++++++++ src/odbc/src/dsn_config.cpp | 5 ++++ 5 files changed, 69 insertions(+), 1 deletion(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index c5a021c2d..254140b09 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -97,6 +97,9 @@ namespace ignite /** Default value for tlsCaFile attribute. */ static const std::string tlsCaFile; + /** Default value for sshEnable attribute. */ + static const bool sshEnable; + /** Default value for sshUser attribute. */ static const std::string sshUser; @@ -467,6 +470,27 @@ namespace ignite */ bool IsTlsCaFileSet() const; + /** + * Get ssh enable. + * + * @return sshEnable. + */ + bool GetSshEnable() const; + + /** + * Set ssh enable. + * + * @param bool ssh enable. + */ + void SetSshEnable(bool sshEnable); + + /** + * Check if the ssh enable value set. + * + * @return @true if the ssh enable value set. + */ + bool IsSshEnableSet() const; + /** * Get password. * @@ -785,6 +809,9 @@ namespace ignite /** SSL/TLS certificate authority file path. */ SettableValue tlsCaFile; + /** The SSH enable option for the internal SSH tunnel. */ + SettableValue sshEnable; + /** The SSH host username for the internal SSH tunnel. */ SettableValue sshUser; diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index 27e4f48d2..3e8169057 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -86,6 +86,9 @@ namespace ignite /** Connection attribute keyword for password attribute. */ static const std::string tlsCaFile; + /** Connection attribute keyword for ssh enable attribute. */ + static const std::string sshEnable; + /** Connection attribute keyword for password attribute. */ static const std::string sshUser; diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 50aedf5c7..67058770d 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -52,7 +52,7 @@ namespace ignite const bool Configuration::DefaultValue::refreshSchema = false; // Internal SSH Tunnel options // need to add to UI - // const bool Configuration::DefaultValue::sshEnable = false; + const bool Configuration::DefaultValue::sshEnable = false; const std::string Configuration::DefaultValue::sshUser = ""; const std::string Configuration::DefaultValue::sshHost = ""; const std::string Configuration::DefaultValue::sshPrivateKeyFile = ""; @@ -87,6 +87,7 @@ namespace ignite tls(DefaultValue::tls), tlsAllowInvalidHostnames(DefaultValue::tlsAllowInvalidHostnames), tlsCaFile(DefaultValue::tlsCaFile), + sshEnable(DefaultValue::sshEnable), sshUser(DefaultValue::sshUser), sshHost(DefaultValue::sshHost), sshPrivateKeyFile(DefaultValue::sshPrivateKeyFile), @@ -340,6 +341,18 @@ namespace ignite return tlsCaFile.IsSet(); } + bool Configuration::GetSshEnable() const { + return sshEnable.GetValue(); + } + + void Configuration::SetSshEnable(bool val) { + this->sshEnable.SetValue(val); + } + + bool Configuration::IsSshEnableSet() const { + return sshEnable.IsSet(); + } + const std::string& Configuration::GetSshUser() const { return sshUser.GetValue(); diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 308bb225b..3543986cc 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -47,6 +47,7 @@ namespace ignite const std::string ConnectionStringParser::Key::tls = "tls"; const std::string ConnectionStringParser::Key::tlsAllowInvalidHostnames = "tls_allow_invalid_hostnames"; const std::string ConnectionStringParser::Key::tlsCaFile = "tls_ca_file"; + const std::string ConnectionStringParser::Key::sshEnable = "ssh_enable"; const std::string ConnectionStringParser::Key::sshUser = "ssh_user"; const std::string ConnectionStringParser::Key::sshHost = "ssh_host"; const std::string ConnectionStringParser::Key::sshPrivateKeyFile = "ssh_private_key_file"; @@ -303,6 +304,25 @@ namespace ignite { cfg.SetTlsCaFile(value); } + else if (lKey == Key::sshEnable) + { + + BoolParseResult::Type res = StringToBool(value); + + if (res == BoolParseResult::AI_UNRECOGNIZED) { + if (diag) { + diag->AddStatusRecord( + SqlState::S01S02_OPTION_VALUE_CHANGED, + MakeErrorMessage("Unrecognized bool value. " + "Using default value.", + key, value)); + } + + return; + } + + cfg.SetSshEnable(res == BoolParseResult::AI_TRUE); + } else if (lKey == Key::sshUser) { cfg.SetSshUser(value); diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 6526a38bd..e306b9fb3 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -180,6 +180,11 @@ namespace ignite if (tlsCaFile.IsSet() && !config.IsTlsCaFileSet()) config.SetTlsCaFile(tlsCaFile.GetValue()); + SettableValue sshEnable = ReadDsnBool(dsn, ConnectionStringParser::Key::sshEnable); + + if (sshEnable.IsSet() && !config.IsSshEnableSet()) + config.SetSshEnable(sshEnable.GetValue()); + SettableValue sshUser = ReadDsnString(dsn, ConnectionStringParser::Key::sshUser); if (sshUser.IsSet() && !config.IsSshUserSet()) From 438a2277004179a954ef39adc8aeaf1b46a3a734 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Fri, 21 Jan 2022 14:30:37 -0800 Subject: [PATCH 045/100] [AD-522] change from GetSshEnable to IsSshEnable for consistency --- src/odbc/include/ignite/odbc/config/configuration.h | 6 +++--- src/odbc/src/config/configuration.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index 4d71e29c1..8327144df 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -459,11 +459,11 @@ namespace ignite bool IsTlsCaFileSet() const; /** - * Get ssh enable. + * Get SSH enable flag. * - * @return sshEnable. + * @return @true if SSH is enabled. */ - bool GetSshEnable() const; + bool IsSshEnable() const; /** * Set ssh enable. diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 580877b61..7f02db73a 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -322,7 +322,7 @@ namespace ignite return tlsCaFile.IsSet(); } - bool Configuration::GetSshEnable() const { + bool Configuration::IsSshEnable() const { return sshEnable.GetValue(); } From 4a640b750a2cf6f07554e820ca4f225bae491859 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 24 Jan 2022 11:25:12 -0800 Subject: [PATCH 046/100] [AD-522] comment out deprecated readPreference variable start on transitioning from readPreferenceEdit to readPreference combo box --- .../odbc/system/ui/dsn_configuration_window.h | 14 +++++++++----- .../src/system/ui/dsn_configuration_window.cpp | 18 +++++++++++------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 957a46e2a..235772710 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -71,8 +71,8 @@ namespace ignite APP_NAME_LABEL, LOGIN_TIMEOUT_SEC_EDIT, LOGIN_TIMEOUT_SEC_LABEL, - READ_PREFERENCE_EDIT, READ_PREFERENCE_LABEL, + READ_PREFERENCE_COMBO_BOX, REPLICA_SET_EDIT, REPLICA_SET_LABEL, RETRY_READS_CHECK_BOX, @@ -80,8 +80,8 @@ namespace ignite DEFAULT_FETCH_SIZE_LABEL, PROTOCOL_VERSION_LABEL, PROTOCOL_VERSION_COMBO_BOX, - NESTED_TX_MODE_LABEL, - NESTED_TX_MODE_COMBO_BOX, + //NESTED_TX_MODE_LABEL, + //NESTED_TX_MODE_COMBO_BOX, TLS_CHECK_BOX, TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, TLS_CA_FILE_EDIT, @@ -323,8 +323,12 @@ namespace ignite /** Login Timeout (seconds) label. */ std::auto_ptr loginTimeoutSecLabel; - /** Read preference edit. */ - std::auto_ptr readPreferenceEdit; + /** Nested Read Preference ComboBox **/ + std::auto_ptr readPreferenceComboBox; + + // -AL- remove later + ///** Read preference edit. */ + //std::auto_ptr readPreferenceEdit; /** Read preference label. */ std::auto_ptr readPreferenceLabel; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 9049ab05d..c7cbf0b2e 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -19,7 +19,8 @@ #include #include "ignite/odbc/log.h" -#include "ignite/odbc/ssl_mode.h" +//#include "ignite/odbc/read_preference.h" // causes build errors, comment out momentarily +// #include "ignite/odbc/ssl_mode.h" //TODO remove later #include "ignite/odbc/system/ui/dsn_configuration_window.h" #include "ignite/odbc/config/config_tools.h" @@ -67,7 +68,7 @@ namespace ignite appNameLabel(), appNameEdit(), readPreferenceLabel(), - readPreferenceEdit(), + //readPreferenceEdit(), replicaSetLabel(), replicaSetEdit(), retryReadsCheckBox(), @@ -536,17 +537,20 @@ namespace ignite // rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight // I believe + /* //TODO readPreference val = config.GetReadPreference().c_str(); + val = + readPreferenceLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "Read preference:", ChildId::READ_PREFERENCE_LABEL); - readPreferenceEdit = CreateEdit( + readPreferenceComboBox = CreateComboBox( editPosX, rowPos, editSizeX, ROW_HEIGHT, - val, ChildId::READ_PREFERENCE_EDIT); + "", ChildId::READ_PREFERENCE_COMBO_BOX); rowPos += INTERVAL + ROW_HEIGHT; - + */ val = config.GetReplicaSet().c_str(); replicaSetLabel = CreateLabel( @@ -797,7 +801,7 @@ namespace ignite std::string replicaSetStr; appNameEdit->GetText(appNameStr); - readPreferenceEdit->GetText(readPreferenceStr); + //readPreferenceEdit->GetText(readPreferenceStr); replicaSetEdit->GetText(replicaSetStr); bool retryReads = retryReadsCheckBox->IsChecked(); @@ -832,7 +836,7 @@ namespace ignite cfg.SetApplicationName(appNameStr); cfg.SetLoginTimeoutSeconds(loginTimeoutSec); - cfg.SetReadPreference(readPreferenceStr); + //cfg.SetReadPreference(readPreferenceStr); cfg.SetReplicaSet(replicaSetStr); cfg.SetRetryReads(retryReads); cfg.SetDefaultFetchSize(fetchSize); From a6f819442aeaf5eaef6d6ca6c3e406004979d4db Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 24 Jan 2022 11:29:43 -0800 Subject: [PATCH 047/100] [AD-522] add SSH enable checkbox, SSH private key passphrase, and SSH private key file * add SSH Enable variable in configuration.h and configuration.cpp * add SSH checkbox in SSH group setting * add SSH private key file edit in SSH group setting * add SSH private key pass phrase in SSH group setting ** SSH private key passphrase label requires double the row height due to the label being long. * make SSH setting items disabled/enabled as SSH enable checkbox is unchecked/checked * save SSH variables to configuration when Ok button is pressed. --- .../ignite/odbc/config/configuration.h | 2 +- .../odbc/system/ui/dsn_configuration_window.h | 4 + .../system/ui/dsn_configuration_window.cpp | 75 +++++++++++++++++-- src/odbc/src/config/configuration.cpp | 12 ++- 4 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index 8327144df..9e92311f9 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -470,7 +470,7 @@ namespace ignite * * @param bool ssh enable. */ - void SetSshEnable(bool sshEnable); + void SetSshEnable(bool val); /** * Check if the ssh enable value set. diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 235772710..f6e747eef 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -56,6 +56,7 @@ namespace ignite ADDRESS_LABEL, SCHEMA_EDIT, SCHEMA_LABEL, + SSH_ENABLE_CHECK_BOX, SSH_USER_EDIT, SSH_USER_LABEL, SSH_HOST_EDIT, @@ -278,6 +279,9 @@ namespace ignite /** DSN schema edit field. */ std::auto_ptr schemaEdit; + /** SSH enable checkBox. */ + std::auto_ptr sshEnableCheckBox; + /** SSH user edit. */ std::auto_ptr sshUserEdit; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index c7cbf0b2e..ce626cd20 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -53,6 +53,7 @@ namespace ignite schemaLabel(), schemaEdit(), // internal SSH tunnel vars + sshEnableCheckBox(), sshUserLabel(), sshUserEdit(), sshHostLabel(), @@ -127,10 +128,12 @@ namespace ignite int posXRight = MARGIN + (width - MARGIN) / 2; int groupPosYRight = MARGIN; + // create left column group settings groupPosYLeft += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); groupPosYLeft += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); - groupPosYLeft += INTERVAL + CreateSshSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); - groupPosYRight += INTERVAL + CreateSslSettingsGroup(posXRight, groupPosYRight, groupSizeY); + groupPosYLeft += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); + // create right column group settings + groupPosYRight += INTERVAL + CreateSshSettingsGroup(posXRight, groupPosYRight, groupSizeY); groupPosYRight += INTERVAL + CreateAdditionalSettingsGroup(posXRight, groupPosYRight, groupSizeY); //groupPosY += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosY, groupSizeY); //groupPosY += INTERVAL + CreateAdditionalSettingsGroup(MARGIN, groupPosY, groupSizeY); @@ -261,6 +264,12 @@ namespace ignite int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; + sshEnableCheckBox = CreateCheckBox( + labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "Enable SSH Tunnel", + ChildId::SSH_ENABLE_CHECK_BOX, config.IsSshEnable()); + + rowPos += INTERVAL + ROW_HEIGHT; + const char* val = config.GetSshUser().c_str(); sshUserLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSH user :", ChildId::SSH_USER_LABEL); @@ -277,6 +286,25 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; + val = config.GetSshPrivateKeyFile().c_str(); + + sshPrivateKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "SSH private key file :", ChildId::SSH_PRIVATE_KEY_FILE_LABEL); + sshPrivateKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, ChildId::SSH_PRIVATE_KEY_FILE_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetSshPrivateKeyPassphrase().c_str(); + + // ssh private key passphrase label requires double the row height due to the long label. + sshPrivateKeyPassphraseLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT * 2, + "SSH private key passphrase :", ChildId::SSH_PRIVATE_KEY_PASSPHRASE_LABEL); + sshPrivateKeyPassphraseEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT * 2, val, ChildId::SSH_PRIVATE_KEY_PASSPHRASE_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT * 2; + sshStrictHostKeyCheckingCheckBox = CreateCheckBox( labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "SSH strict host key checking", ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX, config.IsSshStrictHostKeyChecking()); @@ -296,6 +324,13 @@ namespace ignite "Internal SSH tunnel settings", ChildId::SSH_SETTINGS_GROUP_BOX); + sshUserEdit->SetEnabled(sshEnableCheckBox->IsChecked()); + sshHostEdit->SetEnabled(sshEnableCheckBox->IsChecked()); + sshPrivateKeyFileEdit->SetEnabled( sshEnableCheckBox->IsChecked()); + sshPrivateKeyPassphraseEdit->SetEnabled(sshEnableCheckBox->IsChecked()); + sshStrictHostKeyCheckingCheckBox->SetEnabled(sshEnableCheckBox->IsChecked()); + sshKnownHostsFileEdit->SetEnabled(sshEnableCheckBox->IsChecked()); + return rowPos - posY; } @@ -625,6 +660,25 @@ namespace ignite break; } + case ChildId::SSH_ENABLE_CHECK_BOX: + { + sshEnableCheckBox->SetChecked(!sshEnableCheckBox->IsChecked()); + sshUserEdit->SetEnabled( + sshEnableCheckBox->IsChecked()); + sshHostEdit->SetEnabled(sshEnableCheckBox->IsChecked()); + sshPrivateKeyFileEdit->SetEnabled( + sshEnableCheckBox->IsChecked()); + sshPrivateKeyPassphraseEdit->SetEnabled( + sshEnableCheckBox->IsChecked()); + sshStrictHostKeyCheckingCheckBox + ->SetEnabled( + sshEnableCheckBox->IsChecked()); + sshKnownHostsFileEdit->SetEnabled( + sshEnableCheckBox->IsChecked()); + + break; + } + case ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX: { sshStrictHostKeyCheckingCheckBox @@ -682,6 +736,7 @@ namespace ignite { RetrieveConnectionParameters(cfg); RetrieveAuthParameters(cfg); + RetrieveSshParameters(cfg); RetrieveSslParameters(cfg); RetrieveAdditionalParameters(cfg); } @@ -748,6 +803,9 @@ namespace ignite void DsnConfigurationWindow::RetrieveSshParameters(config::Configuration& cfg) const { + bool sshEnable = sshEnableCheckBox->IsChecked(); + bool sshStrictHostKeyChecking = sshStrictHostKeyCheckingCheckBox->IsChecked(); + std::string sshUserStr; std::string sshHostStr; std::string sshPrivateKeyFileStr; @@ -756,19 +814,24 @@ namespace ignite sshUserEdit->GetText(sshUserStr); sshHostEdit->GetText(sshHostStr); - //sshPrivateKeyFileEdit->GetText(sshPrivateKeyFileStr); - //sshPrivateKeyPassphraseEdit->GetText(sshPrivateKeyPassphraseStr); + sshPrivateKeyFileEdit->GetText(sshPrivateKeyFileStr); + sshPrivateKeyPassphraseEdit->GetText(sshPrivateKeyPassphraseStr); sshKnownHostsFileEdit->GetText(sshKnownHostsFileStr); - bool sshStrictHostKeyChecking = sshStrictHostKeyCheckingCheckBox->IsChecked(); - + LOG_MSG("Retrieving arguments:"); + LOG_MSG("SSH enable: " << (sshEnable ? "true" : "false")); LOG_MSG("SSH user: " << sshUserStr); LOG_MSG("SSH host: " << sshHostStr); + LOG_MSG("SSH private key file: " << sshPrivateKeyFileStr); + LOG_MSG("SSH private key passphrase: " << sshPrivateKeyPassphraseStr); LOG_MSG("SSH known hosts file: " << sshKnownHostsFileStr); LOG_MSG("SSH strict host key checking: " << (sshStrictHostKeyChecking ? "true" : "false")); + cfg.SetSshEnable(sshEnable); cfg.SetSshUser(sshUserStr); cfg.SetSshHost(sshHostStr); + cfg.SetSshPrivateKeyFile(sshPrivateKeyFileStr); + cfg.SetSshPrivateKeyPassphrase(sshPrivateKeyPassphraseStr); cfg.SetSshKnownHostsFile(sshKnownHostsFileStr); cfg.SetSshStrictHostKeyChecking(sshStrictHostKeyChecking); diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 7f02db73a..3d99ca6b9 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -51,7 +51,7 @@ namespace ignite const bool Configuration::DefaultValue::refreshSchema = false; // Internal SSH Tunnel options // need to add to UI - const bool Configuration::DefaultValue::sshEnable = false; + const bool Configuration::DefaultValue::sshEnable = false; const std::string Configuration::DefaultValue::sshUser = ""; const std::string Configuration::DefaultValue::sshHost = ""; const std::string Configuration::DefaultValue::sshPrivateKeyFile = ""; @@ -322,15 +322,18 @@ namespace ignite return tlsCaFile.IsSet(); } - bool Configuration::IsSshEnable() const { + bool Configuration::IsSshEnable() const + { return sshEnable.GetValue(); } - void Configuration::SetSshEnable(bool val) { + void Configuration::SetSshEnable(bool val) + { this->sshEnable.SetValue(val); } - bool Configuration::IsSshEnableSet() const { + bool Configuration::IsSshEnableSet() const + { return sshEnable.IsSet(); } @@ -546,6 +549,7 @@ namespace ignite AddToMap(res, ConnectionStringParser::Key::tls, tls); AddToMap(res, ConnectionStringParser::Key::tlsAllowInvalidHostnames, tlsAllowInvalidHostnames); AddToMap(res, ConnectionStringParser::Key::tlsCaFile, tlsCaFile); + AddToMap(res, ConnectionStringParser::Key::sshEnable, sshEnable); AddToMap(res, ConnectionStringParser::Key::sshUser, sshUser); AddToMap(res, ConnectionStringParser::Key::sshHost, sshHost); AddToMap(res, ConnectionStringParser::Key::sshPrivateKeyFile, sshPrivateKeyFile); From 82c97aeec110aee3afcb3c6357f7c3d511b927a9 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 24 Jan 2022 14:13:03 -0800 Subject: [PATCH 048/100] [AD-522] read_preference.h fix * add guards to read_preference.h fix * include read_preference.h in dsn_configuration_window.cpp * add draft code for read preference in dsn_configuration_window.cpp --- src/odbc/include/ignite/odbc/read_preference.h | 7 ++++++- .../src/system/ui/dsn_configuration_window.cpp | 15 +++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/odbc/include/ignite/odbc/read_preference.h b/src/odbc/include/ignite/odbc/read_preference.h index 2859692b9..7a90f5797 100644 --- a/src/odbc/include/ignite/odbc/read_preference.h +++ b/src/odbc/include/ignite/odbc/read_preference.h @@ -15,6 +15,9 @@ * limitations under the License. */ +#ifndef _IGNITE_ODBC_READ_PREFERENCE +#define _IGNITE_ODBC_READ_PREFERENCE + #include namespace ignite @@ -24,7 +27,7 @@ namespace ignite /** Read Preference enum. */ struct ReadPreference { - enum class Type + enum Type { PRIMARY, @@ -59,3 +62,5 @@ namespace ignite }; } } + +#endif //_IGNITE_ODBC_READ_PREFERENCE \ No newline at end of file diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index ce626cd20..a2e468820 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -19,7 +19,7 @@ #include #include "ignite/odbc/log.h" -//#include "ignite/odbc/read_preference.h" // causes build errors, comment out momentarily +#include "ignite/odbc/read_preference.h" // causes build errors, comment out momentarily // #include "ignite/odbc/ssl_mode.h" //TODO remove later #include "ignite/odbc/system/ui/dsn_configuration_window.h" @@ -69,6 +69,7 @@ namespace ignite appNameLabel(), appNameEdit(), readPreferenceLabel(), + readPreferenceComboBox(), //readPreferenceEdit(), replicaSetLabel(), replicaSetEdit(), @@ -572,10 +573,11 @@ namespace ignite // rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight // I believe - /* //TODO readPreference - val = config.GetReadPreference().c_str(); + /*//TODO readPreference + ReadPreference::Type readPreference = config.GetReadPreference(); + std::string readPreferenceStr = ReadPreference::ToString(readPreference); - val = + const char* val = readPreferenceStr.c_str(); readPreferenceLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, @@ -584,6 +586,11 @@ namespace ignite editPosX, rowPos, editSizeX, ROW_HEIGHT, "", ChildId::READ_PREFERENCE_COMBO_BOX); + readPreferenceComboBox->AddString("disable"); + sslModeComboBox->AddString("require"); + + sslModeComboBox->SetSelection(sslMode); // set default + rowPos += INTERVAL + ROW_HEIGHT; */ val = config.GetReplicaSet().c_str(); From 955e7baa8570030c6699f878a4ba5dfc7846e9f2 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 24 Jan 2022 14:18:12 -0800 Subject: [PATCH 049/100] [AD-522] update fields in configuration window * modified order of fields in the configuration window. - Retry reads checkbox is now in the first row under "Additional Settings". - SSH Strict host key check is now in the last row under "Internal SSH Tunnel Settings" - Allow invalid hostnames checkbox now is in 2nd row under "TLS/SSL settings" * added warning sentences for Allow invalid hostnames checkbox and SSH strict host key check --- .../system/ui/dsn_configuration_window.cpp | 122 +++++++++--------- 1 file changed, 59 insertions(+), 63 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index a2e468820..e7c02c5d3 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -125,8 +125,9 @@ namespace ignite { int groupPosYLeft = MARGIN; //int groupSizeY = width - 2 * MARGIN; // original - int groupSizeY = (width - 2 * MARGIN) / 2; + int groupSizeY = width / 2 - 2 * MARGIN; int posXRight = MARGIN + (width - MARGIN) / 2; + //int posXRight = MARGIN + groupSizeY; int groupPosYRight = MARGIN; // create left column group settings @@ -183,15 +184,15 @@ namespace ignite val = config.GetDatabase().c_str(); schemaLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Schema name:", ChildId::SCHEMA_LABEL); + "Schema Name:", ChildId::SCHEMA_LABEL); schemaEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SCHEMA_EDIT); rowPos += INTERVAL + ROW_HEIGHT; protocolVersionLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Protocol version:", ChildId::PROTOCOL_VERSION_LABEL); + "Protocol Version:", ChildId::PROTOCOL_VERSION_LABEL); protocolVersionComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, - "Protocol version", ChildId::PROTOCOL_VERSION_COMBO_BOX); + "Protocol Version", ChildId::PROTOCOL_VERSION_COMBO_BOX); int id = 0; @@ -215,7 +216,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; connectionSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "Connection settings", ChildId::CONNECTION_SETTINGS_GROUP_BOX); + "Connection Settings", ChildId::CONNECTION_SETTINGS_GROUP_BOX); return rowPos - posY; } @@ -232,7 +233,6 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; const char* val = config.GetUser().c_str(); - userLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "User :", ChildId::USER_LABEL); userEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::USER_EDIT); @@ -247,7 +247,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; authSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "Authentication settings", ChildId::AUTH_SETTINGS_GROUP_BOX); + "Authentication Settings", ChildId::AUTH_SETTINGS_GROUP_BOX); return rowPos - posY; } @@ -263,7 +263,8 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; - int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; + //int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; // original + int checkBoxSize = sizeX - 2 * MARGIN; sshEnableCheckBox = CreateCheckBox( labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "Enable SSH Tunnel", @@ -272,65 +273,60 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; const char* val = config.GetSshUser().c_str(); - - sshUserLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSH user :", ChildId::SSH_USER_LABEL); + sshUserLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSH User :", ChildId::SSH_USER_LABEL); sshUserEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_USER_EDIT); rowPos += INTERVAL + ROW_HEIGHT; val = config.GetSshHost().c_str(); - sshHostLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSH host :", ChildId::SSH_HOST_LABEL); + "SSH Hostname :", ChildId::SSH_HOST_LABEL); sshHostEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_HOST_EDIT); rowPos += INTERVAL + ROW_HEIGHT; val = config.GetSshPrivateKeyFile().c_str(); - sshPrivateKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSH private key file :", ChildId::SSH_PRIVATE_KEY_FILE_LABEL); + "SSH Private Key File :", ChildId::SSH_PRIVATE_KEY_FILE_LABEL); sshPrivateKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_PRIVATE_KEY_FILE_EDIT); rowPos += INTERVAL + ROW_HEIGHT; val = config.GetSshPrivateKeyPassphrase().c_str(); - // ssh private key passphrase label requires double the row height due to the long label. sshPrivateKeyPassphraseLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT * 2, - "SSH private key passphrase :", ChildId::SSH_PRIVATE_KEY_PASSPHRASE_LABEL); + "SSH Private Key Passphrase :", ChildId::SSH_PRIVATE_KEY_PASSPHRASE_LABEL); sshPrivateKeyPassphraseEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT * 2, val, ChildId::SSH_PRIVATE_KEY_PASSPHRASE_EDIT); rowPos += INTERVAL + ROW_HEIGHT * 2; - sshStrictHostKeyCheckingCheckBox = CreateCheckBox( - labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "SSH strict host key checking", - ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX, config.IsSshStrictHostKeyChecking()); - - rowPos += INTERVAL + ROW_HEIGHT; - val = config.GetSshKnownHostsFile().c_str(); - sshKnownHostsFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSH known hosts:", ChildId::SSH_KNOWN_HOSTS_FILE_LABEL); + "SSH Known Hosts:", ChildId::SSH_KNOWN_HOSTS_FILE_LABEL); sshKnownHostsFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_KNOWN_HOSTS_FILE_EDIT); + rowPos += INTERVAL + ROW_HEIGHT; + // SSH Strict Host Key Check check box needs to have editSizeX as size because the string is long + sshStrictHostKeyCheckingCheckBox = CreateCheckBox( + labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "SSH Strict Host Key Check (disabling option is less secure)", + ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX, config.IsSshStrictHostKeyChecking()); + rowPos += INTERVAL + ROW_HEIGHT; sshSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "Internal SSH tunnel settings", + "Internal SSH Tunnel Settings", ChildId::SSH_SETTINGS_GROUP_BOX); sshUserEdit->SetEnabled(sshEnableCheckBox->IsChecked()); sshHostEdit->SetEnabled(sshEnableCheckBox->IsChecked()); sshPrivateKeyFileEdit->SetEnabled( sshEnableCheckBox->IsChecked()); sshPrivateKeyPassphraseEdit->SetEnabled(sshEnableCheckBox->IsChecked()); - sshStrictHostKeyCheckingCheckBox->SetEnabled(sshEnableCheckBox->IsChecked()); sshKnownHostsFileEdit->SetEnabled(sshEnableCheckBox->IsChecked()); + sshStrictHostKeyCheckingCheckBox->SetEnabled(sshEnableCheckBox->IsChecked()); return rowPos - posY; } @@ -392,14 +388,16 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; - int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; + //int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; // original + int checkBoxSize = sizeX - 2 * MARGIN; tlsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "TLS", ChildId::TLS_CHECK_BOX, config.IsTls()); + "Enable TLS", ChildId::TLS_CHECK_BOX, config.IsTls()); + + rowPos += INTERVAL + ROW_HEIGHT; tlsAllowInvalidHostnamesCheckBox = CreateCheckBox( - labelPosX + checkBoxSize + INTERVAL, rowPos, - checkBoxSize, ROW_HEIGHT, "TLS Allow Invalid Hostnames", + labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "Allow Invalid Hostnames (enabling option is less secure)", ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, config.IsTlsAllowInvalidHostnames()); @@ -414,7 +412,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "TLS/SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX); + "TLS/SSL Settings", ChildId::SSL_SETTINGS_GROUP_BOX); tlsAllowInvalidHostnamesCheckBox->SetEnabled(tlsCheckBox->IsChecked()); tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); @@ -528,28 +526,10 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; - const char* val = config.GetApplicationName().c_str(); - - appNameLabel = CreateLabel( - labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Application Name:", ChildId::APP_NAME_LABEL); - appNameEdit = - CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT, val, - ChildId::APP_NAME_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - - std::string tmp = common::LexicalCast< std::string >( - config.GetLoginTimeoutSeconds()); - val = tmp.c_str(); - loginTimeoutSecLabel = CreateLabel( - labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Login Timeout (s):", ChildId::LOGIN_TIMEOUT_SEC_LABEL); - - loginTimeoutSecEdit = CreateEdit( - editPosX, rowPos, editSizeX, ROW_HEIGHT, - val, ChildId::LOGIN_TIMEOUT_SEC_EDIT, ES_NUMBER); + retryReadsCheckBox = CreateCheckBox( + labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + "Retry Reads", ChildId::RETRY_READS_CHECK_BOX, + config.IsRetryReads()); rowPos += INTERVAL + ROW_HEIGHT; @@ -593,8 +573,31 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; */ - val = config.GetReplicaSet().c_str(); + const char* val = config.GetApplicationName().c_str(); + appNameLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Application Name:", ChildId::APP_NAME_LABEL); + appNameEdit = + CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, + ChildId::APP_NAME_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + std::string tmp = common::LexicalCast< std::string >( + config.GetLoginTimeoutSeconds()); + val = tmp.c_str(); + loginTimeoutSecLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Login Timeout (s):", ChildId::LOGIN_TIMEOUT_SEC_LABEL); + + loginTimeoutSecEdit = + CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, + ChildId::LOGIN_TIMEOUT_SEC_EDIT, ES_NUMBER); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetReplicaSet().c_str(); replicaSetLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "Replica Set:", ChildId::REPLICA_SET_LABEL); @@ -605,19 +608,12 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - retryReadsCheckBox = CreateCheckBox( - labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Retry Reads", ChildId::RETRY_READS_CHECK_BOX, - config.IsRetryReads()); - - rowPos += INTERVAL + ROW_HEIGHT; - tmp = common::LexicalCast< std::string >( config.GetDefaultFetchSize()); val = tmp.c_str(); defaultFetchSizeLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Fetch size:", ChildId::DEFAULT_FETCH_SIZE_LABEL); + "Fetch Size:", ChildId::DEFAULT_FETCH_SIZE_LABEL); defaultFetchSizeEdit = CreateEdit( editPosX, rowPos, editSizeX, ROW_HEIGHT, @@ -626,7 +622,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; additionalSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, - rowPos - posY, "Additional settings", + rowPos - posY, "Additional Settings", ChildId::ADDITIONAL_SETTINGS_GROUP_BOX); return rowPos - posY; From 2f4b10878d22ecbfff1ce0c66ac7ba931dd3744f Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Mon, 24 Jan 2022 14:34:39 -0800 Subject: [PATCH 050/100] Improvements from code review + address some warnings --- src/odbc-test/CMakeLists.txt | 20 ++-- src/odbc-test/src/configuration_test.cpp | 34 +++---- .../ignite/odbc/config/configuration.h | 64 ++++++------- .../odbc/config/connection_string_parser.h | 4 +- src/odbc/include/ignite/odbc/connection.h | 1 + .../include/ignite/odbc/read_preference.h | 23 +++-- src/odbc/include/ignite/odbc/scan_method.h | 23 +++-- src/odbc/src/config/configuration.cpp | 42 +------- .../src/config/connection_string_parser.cpp | 78 ++++++++------- src/odbc/src/connection.cpp | 95 +++---------------- src/odbc/src/dsn_config.cpp | 4 +- src/odbc/src/read_preference.cpp | 23 +++-- src/odbc/src/scan_method.cpp | 23 +++-- 13 files changed, 171 insertions(+), 263 deletions(-) diff --git a/src/odbc-test/CMakeLists.txt b/src/odbc-test/CMakeLists.txt index dcee91837..e947b1f31 100644 --- a/src/odbc-test/CMakeLists.txt +++ b/src/odbc-test/CMakeLists.txt @@ -37,26 +37,30 @@ else () endif() set(SOURCES + src/configuration_test.cpp src/connection_test.cpp src/dummy_test.cpp src/odbc_test_suite.cpp - src/test_utils.cpp + src/test_utils.cpp + ../odbc/src/app/application_data_buffer.cpp + ../odbc/src/common_types.cpp + ../odbc/src/common/big_integer.cpp + ../odbc/src/common/bits.cpp ../odbc/src/common/concurrent.cpp + ../odbc/src/common/decimal.cpp ../odbc/src/common/utils.cpp - ../odbc/src/jni/java.cpp - src/configuration_test.cpp ../odbc/src/config/config_tools.cpp ../odbc/src/config/configuration.cpp ../odbc/src/config/connection_info.cpp ../odbc/src/config/connection_string_parser.cpp - ../odbc/src/scan_method.cpp - ../odbc/src/read_preference.cpp ../odbc/src/diagnostic/diagnostic_record.cpp ../odbc/src/diagnostic/diagnostic_record_storage.cpp - ../odbc/src/utility.cpp - ../odbc/src/common_types.cpp - ../odbc/src/app/application_data_buffer.cpp + ../odbc/src/ignite_error.cpp + ../odbc/src/jni/java.cpp ../odbc/src/log.cpp + ../odbc/src/read_preference.cpp + ../odbc/src/scan_method.cpp + ../odbc/src/utility.cpp # TODO uncomment/rework the tests after get some connectivity and functionalities working. # src/teamcity/teamcity_boost.cpp # src/teamcity/teamcity_messages.cpp diff --git a/src/odbc-test/src/configuration_test.cpp b/src/odbc-test/src/configuration_test.cpp index d2c441280..f4be22152 100644 --- a/src/odbc-test/src/configuration_test.cpp +++ b/src/odbc-test/src/configuration_test.cpp @@ -112,7 +112,7 @@ void CheckValidAddress(const char* connectStr, const EndPoint& endPoint) ParseValidConnectString(connectStr, cfg); BOOST_CHECK_EQUAL(cfg.GetHostname(), endPoint.host); - BOOST_CHECK_EQUAL(cfg.GetTcpPort(), endPoint.port); + BOOST_CHECK_EQUAL(cfg.GetPort(), endPoint.port); } void CheckValidScanMethod(const char* connectStr, ScanMethod::Type scanMethod) @@ -184,7 +184,7 @@ void CheckConnectionConfig(const Configuration& cfg) BOOST_CHECK_EQUAL(cfg.GetDriver(), testDriverName); BOOST_CHECK_EQUAL(cfg.GetDatabase(), testDatabaseName); BOOST_CHECK_EQUAL(cfg.GetHostname(), testHostname); - BOOST_CHECK_EQUAL(cfg.GetTcpPort(), testServerPort); + BOOST_CHECK_EQUAL(cfg.GetPort(), testServerPort); BOOST_CHECK_EQUAL(cfg.GetUser(), testUsername); BOOST_CHECK_EQUAL(cfg.GetPassword(), testPassword); BOOST_CHECK_EQUAL(cfg.GetApplicationName(), testAppName); @@ -247,7 +247,7 @@ void CheckDsnConfig(const Configuration& cfg) BOOST_CHECK_EQUAL(cfg.GetDsn(), testDsn); BOOST_CHECK_EQUAL(cfg.GetDatabase(), Configuration::DefaultValue::database); BOOST_CHECK_EQUAL(cfg.GetHostname(), Configuration::DefaultValue::hostname); - BOOST_CHECK_EQUAL(cfg.GetTcpPort(), Configuration::DefaultValue::port); + BOOST_CHECK_EQUAL(cfg.GetPort(), Configuration::DefaultValue::port); BOOST_CHECK_EQUAL(cfg.GetUser(), Configuration::DefaultValue::user); BOOST_CHECK_EQUAL(cfg.GetPassword(), Configuration::DefaultValue::password); BOOST_CHECK_EQUAL(cfg.GetApplicationName(), Configuration::DefaultValue::appName); @@ -554,17 +554,17 @@ BOOST_AUTO_TEST_CASE(TestConnectStringValidReadPreference) BOOST_AUTO_TEST_CASE(TestConnectStringInvalidBoolKeys) { - typedef std::set Set; + using Set = std::set>; Set keys; - keys.insert("retry_reads"); - keys.insert("tls"); - keys.insert("tls_allow_invalid_hostnames"); - keys.insert("ssh_strict_host_key_checking"); - keys.insert("refresh_schema"); + keys.emplace("retry_reads"); + keys.emplace("tls"); + keys.emplace("tls_allow_invalid_hostnames"); + keys.emplace("ssh_strict_host_key_checking"); + keys.emplace("refresh_schema"); - for (Set::const_iterator it = keys.begin(); it != keys.end(); ++it) + for (auto it = keys.begin(); it != keys.end(); ++it) { const std::string& key = *it; @@ -581,17 +581,17 @@ BOOST_AUTO_TEST_CASE(TestConnectStringInvalidBoolKeys) BOOST_AUTO_TEST_CASE(TestConnectStringValidBoolKeys) { - typedef std::set Set; + using Set = std::set>; Set keys; - keys.insert("retry_reads"); - keys.insert("tls"); - keys.insert("tls_allow_invalid_hostnames"); - keys.insert("ssh_strict_host_key_checking"); - keys.insert("refresh_schema"); + keys.emplace("retry_reads"); + keys.emplace("tls"); + keys.emplace("tls_allow_invalid_hostnames"); + keys.emplace("ssh_strict_host_key_checking"); + keys.emplace("refresh_schema"); - for (Set::const_iterator it = keys.begin(); it != keys.end(); ++it) + for (auto it = keys.begin(); it != keys.end(); ++it) { const std::string& key = *it; diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index ee52f697c..4d3908598 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -133,12 +133,12 @@ namespace ignite /** * Default constructor. */ - Configuration(); + Configuration() = default; /** * Destructor. */ - ~Configuration(); + ~Configuration() = default; /** * Convert configure to connect string. @@ -208,21 +208,21 @@ namespace ignite * * @return Server port. */ - uint16_t GetTcpPort() const; + uint16_t GetPort() const; /** * Set server port. * * @param portNumber Server port. */ - void SetTcpPort(uint16_t portNumber); + void SetPort(uint16_t portNumber); /** * Check if the value set. * * @return @true if the value set. */ - bool IsTcpPortSet() const; + bool IsPortSet() const; /** * Get database. @@ -705,82 +705,82 @@ namespace ignite static void AddToMap(ArgumentMap& map, const std::string& key, const SettableValue& value); /** DSN. */ - SettableValue dsn; + SettableValue dsn = DefaultValue::dsn; /** Driver name. */ - SettableValue driver; + SettableValue driver = DefaultValue::driver; /** Schema. */ - SettableValue database; + SettableValue database = DefaultValue::database; /** Hostname. */ - SettableValue hostname; + SettableValue hostname = DefaultValue::hostname; /** Port. */ - SettableValue port; + SettableValue port = DefaultValue::port; /** User. */ - SettableValue user; + SettableValue user = DefaultValue::user; /** Password. */ - SettableValue password; + SettableValue password = DefaultValue::password; /** Application name. */ - SettableValue appName; + SettableValue appName = DefaultValue::appName; /** Login timeout in seconds. */ - SettableValue loginTimeoutSec; + SettableValue loginTimeoutSec = DefaultValue::loginTimeoutSec; /** Read pereference. */ - SettableValue readPreference; + SettableValue readPreference = DefaultValue::readPreference; /** Replica set name. */ - SettableValue replicaSet; + SettableValue replicaSet = DefaultValue::replicaSet; /** Retry reads flag. */ - SettableValue retryReads; + SettableValue retryReads = DefaultValue::retryReads; /** Enable SSL/TLS. */ - SettableValue tls; + SettableValue tls = DefaultValue::tls; /** Flag for if invalid hostnames for the TLS certificate are allowed. */ - SettableValue tlsAllowInvalidHostnames; + SettableValue tlsAllowInvalidHostnames = DefaultValue::tlsAllowInvalidHostnames; /** SSL/TLS certificate authority file path. */ - SettableValue tlsCaFile; + SettableValue tlsCaFile = DefaultValue::tlsCaFile; /** The SSH host username for the internal SSH tunnel. */ - SettableValue sshUser; + SettableValue sshUser = DefaultValue::sshUser; /** The SSH host host name for the internal SSH tunnel. */ - SettableValue sshHost; + SettableValue sshHost = DefaultValue::sshHost; /** The SSH host private key file path for the internal SSH tunnel. */ - SettableValue sshPrivateKeyFile; + SettableValue sshPrivateKeyFile = DefaultValue::sshPrivateKeyFile; /** The SSH host private key file passphrase for the internal SSH tunnel. */ - SettableValue sshPrivateKeyPassphrase; + SettableValue sshPrivateKeyPassphrase = DefaultValue::sshPrivateKeyPassphrase; /** Strict host key checking flag for the internal SSH tunnel. */ - SettableValue sshStrictHostKeyChecking; + SettableValue sshStrictHostKeyChecking = DefaultValue::sshStrictHostKeyChecking; /** The known hosts file path for the internal SSH tunnel. */ - SettableValue sshKnownHostsFile; + SettableValue sshKnownHostsFile = DefaultValue::sshKnownHostsFile; /** Scan method. */ - SettableValue scanMethod; + SettableValue scanMethod = DefaultValue::scanMethod; /** Scan limit. */ - SettableValue scanLimit; + SettableValue scanLimit = DefaultValue::scanLimit; /** Schema name. */ - SettableValue schemaName; + SettableValue schemaName = DefaultValue::schemaName; /** Refresh schema flag. */ - SettableValue refreshSchema; + SettableValue refreshSchema = DefaultValue::refreshSchema; - /** Request and response page size. */ - SettableValue defaultFetchSize; + /** Default fetch size. */ + SettableValue defaultFetchSize = DefaultValue::defaultFetchSize; }; template<> diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index 16b02d484..42469d026 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -145,7 +145,7 @@ namespace ignite /** * Destructor. */ - ~ConnectionStringParser(); + ~ConnectionStringParser() = default; /** * Parse connect string. @@ -180,7 +180,7 @@ namespace ignite */ struct BoolParseResult { - enum Type + enum class Type { AI_FALSE, diff --git a/src/odbc/include/ignite/odbc/connection.h b/src/odbc/include/ignite/odbc/connection.h index 0a917a50d..d35b1ad40 100644 --- a/src/odbc/include/ignite/odbc/connection.h +++ b/src/odbc/include/ignite/odbc/connection.h @@ -31,6 +31,7 @@ #include "ignite/odbc/streaming/streaming_context.h" #include "ignite/odbc/odbc_error.h" #include "ignite/odbc/jni/java.h" +#include "ignite/odbc/end_point.h" namespace ignite { diff --git a/src/odbc/include/ignite/odbc/read_preference.h b/src/odbc/include/ignite/odbc/read_preference.h index 2859692b9..3ab19dcce 100644 --- a/src/odbc/include/ignite/odbc/read_preference.h +++ b/src/odbc/include/ignite/odbc/read_preference.h @@ -1,18 +1,17 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Copyright <2022> Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ #include diff --git a/src/odbc/include/ignite/odbc/scan_method.h b/src/odbc/include/ignite/odbc/scan_method.h index 1feb2f9ca..0267bdec2 100644 --- a/src/odbc/include/ignite/odbc/scan_method.h +++ b/src/odbc/include/ignite/odbc/scan_method.h @@ -1,18 +1,17 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Copyright <2022> Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ #include diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index d6a6e2cb9..9b66df00d 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -66,42 +66,6 @@ namespace ignite const bool Configuration::DefaultValue::retryReads = true; const int32_t Configuration::DefaultValue::defaultFetchSize = 2000; - Configuration::Configuration() : - dsn(DefaultValue::dsn), - driver(DefaultValue::driver), - database(DefaultValue::database), - hostname(DefaultValue::hostname), - port(DefaultValue::port), - user(DefaultValue::user), - password(DefaultValue::password), - appName(DefaultValue::appName), - loginTimeoutSec(DefaultValue::loginTimeoutSec), - readPreference(DefaultValue::readPreference), - replicaSet(DefaultValue::replicaSet), - retryReads(DefaultValue::retryReads), - tls(DefaultValue::tls), - tlsAllowInvalidHostnames(DefaultValue::tlsAllowInvalidHostnames), - tlsCaFile(DefaultValue::tlsCaFile), - sshUser(DefaultValue::sshUser), - sshHost(DefaultValue::sshHost), - sshPrivateKeyFile(DefaultValue::sshPrivateKeyFile), - sshPrivateKeyPassphrase(DefaultValue::sshPrivateKeyPassphrase), - sshStrictHostKeyChecking(DefaultValue::sshStrictHostKeyChecking), - sshKnownHostsFile(DefaultValue::sshKnownHostsFile), - scanMethod(DefaultValue::scanMethod), - scanLimit(DefaultValue::scanLimit), - schemaName(DefaultValue::schemaName), - refreshSchema(DefaultValue::refreshSchema), - defaultFetchSize(DefaultValue::defaultFetchSize) - { - // No-op. - } - - Configuration::~Configuration() - { - // No-op. - } - std::string Configuration::ToConnectString() const { ArgumentMap arguments; @@ -127,17 +91,17 @@ namespace ignite return connect_string_buffer.str(); } - uint16_t Configuration::GetTcpPort() const + uint16_t Configuration::GetPort() const { return port.GetValue(); } - void Configuration::SetTcpPort(uint16_t portNumber) + void Configuration::SetPort(uint16_t portNumber) { this->port.SetValue(portNumber); } - bool Configuration::IsTcpPortSet() const + bool Configuration::IsPortSet() const { return port.IsSet(); } diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index b6e7908fc..8882792b2 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -20,10 +20,8 @@ #include "ignite/common/utils.h" #include "ignite/odbc/utility.h" -//#include "ignite/odbc/ssl_mode.h" #include "ignite/odbc/config/connection_string_parser.h" #include "ignite/odbc/config/config_tools.h" -//#include "ignite/odbc/nested_tx_mode.h" namespace ignite { @@ -66,11 +64,6 @@ namespace ignite // No-op. } - ConnectionStringParser::~ConnectionStringParser() - { - // No-op. - } - void ConnectionStringParser::ParseConnectionString(const char* str, size_t len, char delimiter, diagnostic::DiagnosticRecordStorage* diag) { @@ -158,8 +151,8 @@ namespace ignite cfg.SetHostname(endpoint.host); - if (!cfg.IsTcpPortSet()) - cfg.SetTcpPort(endpoint.port); + if (!cfg.IsPortSet()) + cfg.SetPort(endpoint.port); } else if (lKey == Key::port) { @@ -203,7 +196,7 @@ namespace ignite conv << value; conv >> numValue; - if (numValue <= 0 || numValue > 0xFFFF) + if (numValue <= 0 || numValue > UINT16_MAX) { if (diag) { @@ -215,7 +208,7 @@ namespace ignite return; } - cfg.SetTcpPort(static_cast(numValue)); + cfg.SetPort(static_cast(numValue)); } else if (lKey == Key::appName) { @@ -235,13 +228,24 @@ namespace ignite return; } + if (value.size() >= sizeof("4294967295")) + { + if (diag) + { + diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, + MakeErrorMessage("Login timeout seconds attribute value is too large. Using default value.", key, value)); + } + + return; + } + int64_t numValue = 0; std::stringstream conv; conv << value; conv >> numValue; - if (numValue <= 0 || numValue > 0xFFFFFFFFL) + if (numValue <= 0 || numValue > UINT32_MAX) { if (diag) { @@ -280,7 +284,7 @@ namespace ignite { BoolParseResult::Type res = StringToBool(value); - if (res == BoolParseResult::AI_UNRECOGNIZED) + if (res == BoolParseResult::Type::AI_UNRECOGNIZED) { if (diag) { @@ -291,13 +295,13 @@ namespace ignite return; } - cfg.SetRetryReads(res == BoolParseResult::AI_TRUE); + cfg.SetRetryReads(res == BoolParseResult::Type::AI_TRUE); } else if (lKey == Key::tls) { BoolParseResult::Type res = StringToBool(value); - if (res == BoolParseResult::AI_UNRECOGNIZED) + if (res == BoolParseResult::Type::AI_UNRECOGNIZED) { if (diag) { @@ -308,13 +312,13 @@ namespace ignite return; } - cfg.SetTls(res == BoolParseResult::AI_TRUE); + cfg.SetTls(res == BoolParseResult::Type::AI_TRUE); } else if (lKey == Key::tlsAllowInvalidHostnames) { BoolParseResult::Type res = StringToBool(value); - if (res == BoolParseResult::AI_UNRECOGNIZED) + if (res == BoolParseResult::Type::AI_UNRECOGNIZED) { if (diag) { @@ -325,7 +329,7 @@ namespace ignite return; } - cfg.SetTlsAllowInvalidHostnames(res == BoolParseResult::AI_TRUE); + cfg.SetTlsAllowInvalidHostnames(res == BoolParseResult::Type::AI_TRUE); } else if (lKey == Key::tlsCaFile) { @@ -351,7 +355,7 @@ namespace ignite { BoolParseResult::Type res = StringToBool(value); - if (res == BoolParseResult::AI_UNRECOGNIZED) + if (res == BoolParseResult::Type::AI_UNRECOGNIZED) { if (diag) { @@ -362,7 +366,7 @@ namespace ignite return; } - cfg.SetSshStrictHostKeyChecking(res == BoolParseResult::AI_TRUE); + cfg.SetSshStrictHostKeyChecking(res == BoolParseResult::Type::AI_TRUE); } else if (lKey == Key::sshKnownHostsFile) { @@ -399,13 +403,25 @@ namespace ignite return; } + if (value.size() >= sizeof("4294967295")) + { + if (diag) + { + diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, + MakeErrorMessage("Default fetch size attribute value is too large." + " Using default value.", key, value)); + } + + return; + } + int64_t numValue = 0; std::stringstream conv; conv << value; conv >> numValue; - if (numValue <= 0 || numValue > 0xFFFFFFFFL) + if (numValue <= 0 || numValue > UINT32_MAX) { if (diag) { @@ -427,7 +443,7 @@ namespace ignite { BoolParseResult::Type res = StringToBool(value); - if (res == BoolParseResult::AI_UNRECOGNIZED) + if (res == BoolParseResult::Type::AI_UNRECOGNIZED) { if (diag) { @@ -438,7 +454,7 @@ namespace ignite return; } - cfg.SetRefreshSchema(res == BoolParseResult::AI_TRUE); + cfg.SetRefreshSchema(res == BoolParseResult::Type::AI_TRUE); } else if (lKey == Key::defaultFetchSize) { @@ -459,7 +475,7 @@ namespace ignite if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Page size attribute value is too large." + MakeErrorMessage("Default fetch size attribute value is too large." " Using default value.", key, value)); } @@ -472,12 +488,12 @@ namespace ignite conv << value; conv >> numValue; - if (numValue <= 0 || numValue > 0xFFFFFFFFL) + if (numValue <= 0 || numValue > UINT32_MAX) { if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Page size attribute value is out of range." + MakeErrorMessage("Default fetch size attribute value is out of range." " Using default value.", key, value)); } @@ -486,10 +502,6 @@ namespace ignite cfg.SetDefaultFetchSize(static_cast(numValue)); } - else if (lKey == Key::tlsCaFile) - { - cfg.SetTlsCaFile(value); - } else if (lKey == Key::driver) { cfg.SetDriver(value); @@ -529,12 +541,12 @@ namespace ignite std::string lower = common::ToLower(value); if (lower == "true") - return BoolParseResult::AI_TRUE; + return BoolParseResult::Type::AI_TRUE; if (lower == "false") - return BoolParseResult::AI_FALSE; + return BoolParseResult::Type::AI_FALSE; - return BoolParseResult::AI_UNRECOGNIZED; + return BoolParseResult::Type::AI_UNRECOGNIZED; } std::string ConnectionStringParser::MakeErrorMessage(const std::string& msg, const std::string& key, diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index 280a425c2..643875737 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -146,38 +146,6 @@ namespace ignite IGNITE_ODBC_API_CALL(InternalEstablish(cfg)); } - SqlResult::Type Connection::InitSocket() - { - // Removed SSL Mode in DSN. Replaced this with REQUIRE for now. - ssl::SslMode::Type sslMode = ssl::SslMode::REQUIRE; - - if (sslMode == ssl::SslMode::DISABLE) - { - socket.reset(network::ssl::MakeTcpSocketClient()); - - return SqlResult::AI_SUCCESS; - } - - try - { - network::ssl::EnsureSslLoaded(); - } - catch (const IgniteError &err) - { - LOG_MSG("Can not load OpenSSL library: " << err.GetText()); - - AddStatusRecord("Can not load OpenSSL library (did you set OPENSSL_HOME environment variable?)"); - - return SqlResult::AI_ERROR; - } - - // Removed SSL key and cert files from DSN. Replaced with empty string for now. - socket.reset(network::ssl::MakeSecureSocketClient( - "", "", config.GetTlsCaFile())); - - return SqlResult::AI_SUCCESS; - } - SqlResult::Type Connection::InternalEstablish(const config::Configuration& cfg) { using ssl::SslMode; @@ -553,25 +521,6 @@ namespace ignite SqlResult::Type Connection::MakeRequestHandshake() { - /* ProtocolVersion protocolVersion = config.GetProtocolVersion(); - - if (!protocolVersion.IsSupported()) - { - AddStatusRecord(SqlState::S01S00_INVALID_CONNECTION_STRING_ATTRIBUTE, - "Protocol version is not supported: " + protocolVersion.ToString()); - - return SqlResult::AI_ERROR; - } - - if (protocolVersion < ProtocolVersion::VERSION_2_5_0 && !config.GetUser().empty()) - { - AddStatusRecord(SqlState::S01S00_INVALID_CONNECTION_STRING_ATTRIBUTE, - "Authentication is not allowed for protocol version below 2.5.0"); - - return SqlResult::AI_ERROR; - } - */ - HandshakeRequest req(config); HandshakeResponse rsp; @@ -613,13 +562,6 @@ namespace ignite if (!rsp.GetError().empty()) constructor << "Additional info: " << rsp.GetError() << " "; - /* constructor - << "Current version of the protocol, used by the server " - "node is " - << rsp.GetCurrentVer().ToString() << ", " - << "driver protocol version introduced in version " - << protocolVersion.ToString() << "."; */ - AddStatusRecord(SqlState::S08004_CONNECTION_REJECTED, constructor.str()); return SqlResult::AI_ERROR; @@ -697,19 +639,23 @@ namespace ignite std::string Connection::FormatJdbcConnectionString() const { std::string host = "localhost"; - std::string port = "27017"; - if (!config.GetAddresses().empty()) { - host = config.GetAddresses()[0].host; - port = std::to_string(config.GetAddresses()[0].port); - } + uint16_t port = 27017; std::string jdbConnectionString; + if (config.IsHostnameSet()) { + host = config.GetHostname(); + } + + if (config.IsPortSet()) { + port = config.GetPort(); + } + jdbConnectionString = "jdbc:documentdb:"; jdbConnectionString.append("//" + config.GetUser()); jdbConnectionString.append(":" + config.GetPassword()); jdbConnectionString.append("@" + host); jdbConnectionString.append(":" + port); - jdbConnectionString.append("/" + config.GetSchema()); + jdbConnectionString.append("/" + config.GetDatabase()); jdbConnectionString.append("?tlsAllowInvalidHostnames=true"); // Check if internal SSH tunnel should be enabled. @@ -738,7 +684,7 @@ namespace ignite return jdbConnectionString; } - /** + /** * Create JVM options from configuration. * * @param cfg Configuration. @@ -805,25 +751,10 @@ namespace ignite { endPoints.clear(); - // DocumentDB driver is currently not supporting list of addresses. Always use this 'legacy' method. + // DocumentDB driver is currently not supporting list of addresses. Return vector with the one address for now. LOG_MSG("'Address' is not set. Using legacy connection method."); - endPoints.push_back(EndPoint(cfg.GetHostname(), cfg.GetTcpPort())); + endPoints.push_back(EndPoint(cfg.GetHostname(), cfg.GetPort())); return; - - /*if (!cfg.IsAddressesSet()) - { - LOG_MSG("'Address' is not set. Using legacy connection method."); - - endPoints.push_back(EndPoint(cfg.GetHostname(), cfg.GetTcpPort())); - - return; - } - - endPoints = cfg.GetAddresses(); - - - std::random_shuffle(endPoints.begin(), endPoints.end()); - */ } int32_t Connection::RetrieveTimeout(void* value) diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 9b2b7ac91..810fde66a 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -111,8 +111,8 @@ namespace ignite SettableValue port = ReadDsnInt(dsn, ConnectionStringParser::Key::port); - if (port.IsSet() && !config.IsTcpPortSet()) - config.SetTcpPort(static_cast(port.GetValue())); + if (port.IsSet() && !config.IsPortSet()) + config.SetPort(static_cast(port.GetValue())); SettableValue database = ReadDsnString(dsn, ConnectionStringParser::Key::database); diff --git a/src/odbc/src/read_preference.cpp b/src/odbc/src/read_preference.cpp index 43d81c4dc..ad955b57c 100644 --- a/src/odbc/src/read_preference.cpp +++ b/src/odbc/src/read_preference.cpp @@ -1,18 +1,17 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Copyright <2022> Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ #include diff --git a/src/odbc/src/scan_method.cpp b/src/odbc/src/scan_method.cpp index 06400dd9a..b9f4ee09b 100644 --- a/src/odbc/src/scan_method.cpp +++ b/src/odbc/src/scan_method.cpp @@ -1,18 +1,17 @@ /* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at + * Copyright <2022> Amazon.com, Inc. or its affiliates. All Rights Reserved. * - * http://www.apache.org/licenses/LICENSE-2.0 + * Licensed under the Apache License, Version 2.0 (the "License"). + * You may not use this file except in compliance with the License. + * A copy of the License is located at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * or in the "license" file accompanying this file. This file is distributed + * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either + * express or implied. See the License for the specific language governing + * permissions and limitations under the License. * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. */ #include From 095edf18b03dcba5cd08ddd0356d95828fc9dfe3 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Mon, 24 Jan 2022 15:14:12 -0800 Subject: [PATCH 051/100] Change connection _test to use hostname key instead of address --- src/odbc-test/src/configuration_test.cpp | 4 ++-- src/odbc-test/src/connection_test.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/odbc-test/src/configuration_test.cpp b/src/odbc-test/src/configuration_test.cpp index f4be22152..c943e24b8 100644 --- a/src/odbc-test/src/configuration_test.cpp +++ b/src/odbc-test/src/configuration_test.cpp @@ -554,7 +554,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringValidReadPreference) BOOST_AUTO_TEST_CASE(TestConnectStringInvalidBoolKeys) { - using Set = std::set>; + typedef std::set Set; Set keys; @@ -581,7 +581,7 @@ BOOST_AUTO_TEST_CASE(TestConnectStringInvalidBoolKeys) BOOST_AUTO_TEST_CASE(TestConnectStringValidBoolKeys) { - using Set = std::set>; + typedef std::set Set; Set keys; diff --git a/src/odbc-test/src/connection_test.cpp b/src/odbc-test/src/connection_test.cpp index 28714a040..211f1933b 100644 --- a/src/odbc-test/src/connection_test.cpp +++ b/src/odbc-test/src/connection_test.cpp @@ -96,7 +96,7 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite connectionString = "DRIVER={Apache Ignite};" - "ADDRESS=" + host + ":" + port + ";" + "HOSTNAME=" + host + ":" + port + ";" "SCHEMA=test;" "USER=" + user + ";" "PASSWORD=" + password + ";"; From 9e01a14ec4fb4d8ec669f24082e69933bc489636 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Mon, 24 Jan 2022 15:23:16 -0800 Subject: [PATCH 052/100] Change connection_test to use databse key instead of schema key --- src/odbc-test/src/connection_test.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc-test/src/connection_test.cpp b/src/odbc-test/src/connection_test.cpp index 211f1933b..1c2dafbf3 100644 --- a/src/odbc-test/src/connection_test.cpp +++ b/src/odbc-test/src/connection_test.cpp @@ -97,7 +97,7 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite connectionString = "DRIVER={Apache Ignite};" "HOSTNAME=" + host + ":" + port + ";" - "SCHEMA=test;" + "DATABASE=test;" "USER=" + user + ";" "PASSWORD=" + password + ";"; } From cbaeedd0cde8b82bc29134efcad28dba943751c2 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 24 Jan 2022 16:09:55 -0800 Subject: [PATCH 053/100] [AD-522] implement read Preference * add SpaceToUnderscore function * implement read Preference in Config window and save the value --- src/common/include/ignite/common/utils.h | 10 ++++++ .../system/ui/dsn_configuration_window.cpp | 31 +++++++++++-------- src/odbc/os/win/src/system/ui/window.cpp | 14 +++++++++ src/odbc/src/read_preference.cpp | 2 ++ 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/src/common/include/ignite/common/utils.h b/src/common/include/ignite/common/utils.h index 9d17d655d..4a8369f1f 100644 --- a/src/common/include/ignite/common/utils.h +++ b/src/common/include/ignite/common/utils.h @@ -65,6 +65,16 @@ namespace ignite return res; } + /** + * Replaces whitespaces in string with underscores. + * + * @param str String to be transformed. + */ + inline void SpaceToUnderscore(std::string& str) + { + std::replace(str.begin(), str.end(), ' ', '_'); + } + /** * Strips leading and trailing whitespaces from string. * diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index e7c02c5d3..c35bde41a 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -70,7 +70,6 @@ namespace ignite appNameEdit(), readPreferenceLabel(), readPreferenceComboBox(), - //readPreferenceEdit(), replicaSetLabel(), replicaSetEdit(), retryReadsCheckBox(), @@ -553,7 +552,7 @@ namespace ignite // rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight // I believe - /*//TODO readPreference + //TODO readPreference ReadPreference::Type readPreference = config.GetReadPreference(); std::string readPreferenceStr = ReadPreference::ToString(readPreference); @@ -566,15 +565,18 @@ namespace ignite editPosX, rowPos, editSizeX, ROW_HEIGHT, "", ChildId::READ_PREFERENCE_COMBO_BOX); - readPreferenceComboBox->AddString("disable"); - sslModeComboBox->AddString("require"); + readPreferenceComboBox->AddString("Primary"); + readPreferenceComboBox->AddString("Primary Preferred"); + readPreferenceComboBox->AddString("Secondary"); + readPreferenceComboBox->AddString("Secondary Preferred"); + readPreferenceComboBox->AddString("Nearest"); - sslModeComboBox->SetSelection(sslMode); // set default + readPreferenceComboBox->SetSelection(readPreference); // set default rowPos += INTERVAL + ROW_HEIGHT; - */ + - const char* val = config.GetApplicationName().c_str(); + val = config.GetApplicationName().c_str(); appNameLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "Application Name:", ChildId::APP_NAME_LABEL); @@ -862,12 +864,12 @@ namespace ignite void DsnConfigurationWindow::RetrieveAdditionalParameters(config::Configuration& cfg) const { - std::string appNameStr; std::string readPreferenceStr; + std::string appNameStr; std::string replicaSetStr; + readPreferenceComboBox->GetText(readPreferenceStr); appNameEdit->GetText(appNameStr); - //readPreferenceEdit->GetText(readPreferenceStr); replicaSetEdit->GetText(replicaSetStr); bool retryReads = retryReadsCheckBox->IsChecked(); @@ -893,18 +895,21 @@ namespace ignite fetchSize = config.GetDefaultFetchSize(); LOG_MSG("Retrieving arguments:"); + LOG_MSG("Retry reads: " << (retryReads ? "true" : "false")); + LOG_MSG("Read preference: " << readPreferenceStr); LOG_MSG("App name: " << appNameStr); LOG_MSG("Login timeout (seconds): " << loginTimeoutSecStr); - LOG_MSG("Read preference: " << readPreferenceStr); LOG_MSG("Replica Set: " << replicaSetStr); - LOG_MSG("Retry reads: " << (retryReads ? "true" : "false")); LOG_MSG("Fetch size: " << fetchSize); + ReadPreference::Type readPreference = ReadPreference::FromString( + readPreferenceStr, ReadPreference::Type::PRIMARY); + + cfg.SetReadPreference(readPreference); + cfg.SetRetryReads(retryReads); cfg.SetApplicationName(appNameStr); cfg.SetLoginTimeoutSeconds(loginTimeoutSec); - //cfg.SetReadPreference(readPreferenceStr); cfg.SetReplicaSet(replicaSetStr); - cfg.SetRetryReads(retryReads); cfg.SetDefaultFetchSize(fetchSize); } diff --git a/src/odbc/os/win/src/system/ui/window.cpp b/src/odbc/os/win/src/system/ui/window.cpp index 8f2340a12..b4a64bd8b 100644 --- a/src/odbc/os/win/src/system/ui/window.cpp +++ b/src/odbc/os/win/src/system/ui/window.cpp @@ -159,6 +159,20 @@ namespace ignite SNDMSG(handle, WM_SETTEXT, 0, reinterpret_cast(text.c_str())); } + bool Window::HasText() const { + if (!IsEnabled()) { + return false; + } + + int len = GetWindowTextLength(handle); + + if (len <= 0) { + return false; + } + + return true; + } + bool Window::IsChecked() const { return IsEnabled() && Button_GetCheck(handle) == BST_CHECKED; diff --git a/src/odbc/src/read_preference.cpp b/src/odbc/src/read_preference.cpp index 43d81c4dc..0b0696e97 100644 --- a/src/odbc/src/read_preference.cpp +++ b/src/odbc/src/read_preference.cpp @@ -29,6 +29,8 @@ namespace ignite common::StripSurroundingWhitespaces(lowerVal); + common::SpaceToUnderscore(lowerVal); + if (lowerVal == "primary") return ReadPreference::Type::PRIMARY; From 2345c4104a1b5d89654f5fbb7bf03d84c5641b06 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Mon, 24 Jan 2022 16:17:35 -0800 Subject: [PATCH 054/100] Attempt to fix windows 32 build --- src/odbc/src/connection.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index 643875737..b2a471529 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -639,7 +639,7 @@ namespace ignite std::string Connection::FormatJdbcConnectionString() const { std::string host = "localhost"; - uint16_t port = 27017; + std::string port = "27017"; std::string jdbConnectionString; if (config.IsHostnameSet()) { @@ -647,7 +647,7 @@ namespace ignite } if (config.IsPortSet()) { - port = config.GetPort(); + port = std::to_string(config.GetPort()); } jdbConnectionString = "jdbc:documentdb:"; From 3f6b3762b90b74f591b46f0dcdcdf909583c670a Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 24 Jan 2022 17:00:51 -0800 Subject: [PATCH 055/100] [AD-522] refactor dsn_configuration_window.cpp refactor code format; remove spaces and unnecessary comments --- .../os/win/src/system/ui/dsn_configuration_window.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index c35bde41a..cf36773c4 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -19,8 +19,7 @@ #include #include "ignite/odbc/log.h" -#include "ignite/odbc/read_preference.h" // causes build errors, comment out momentarily -// #include "ignite/odbc/ssl_mode.h" //TODO remove later +#include "ignite/odbc/read_preference.h" #include "ignite/odbc/system/ui/dsn_configuration_window.h" #include "ignite/odbc/config/config_tools.h" @@ -512,7 +511,8 @@ namespace ignite } */ - int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) { + int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) + { enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also // change it to the same @@ -879,7 +879,7 @@ namespace ignite loginTimeoutSecEdit->GetText(loginTimeoutSecStr); int32_t loginTimeoutSec = - common::LexicalCast< int32_t >(loginTimeoutSecStr); + common::LexicalCast(loginTimeoutSecStr); if (loginTimeoutSec <= 0) loginTimeoutSec = config.GetLoginTimeoutSeconds(); @@ -889,7 +889,7 @@ namespace ignite defaultFetchSizeEdit->GetText(fetchSizeStr); int32_t fetchSize = - common::LexicalCast< int32_t >(fetchSizeStr); + common::LexicalCast(fetchSizeStr); if (fetchSize <= 0) fetchSize = config.GetDefaultFetchSize(); From 13786309aa1cb5e1feccb54b50e7e6c4a0da574b Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 24 Jan 2022 17:02:46 -0800 Subject: [PATCH 056/100] [AD-522] fix config window margins now the config window is symmetric --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index cf36773c4..2259797b4 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -124,8 +124,10 @@ namespace ignite int groupPosYLeft = MARGIN; //int groupSizeY = width - 2 * MARGIN; // original int groupSizeY = width / 2 - 2 * MARGIN; - int posXRight = MARGIN + (width - MARGIN) / 2; + int posXRight = width / 2 + MARGIN; + //int posXRight = MARGIN + (width - MARGIN) / 2; //int posXRight = MARGIN + groupSizeY; + //int posXRight = 2 * MARGIN + groupSizeY; int groupPosYRight = MARGIN; // create left column group settings From a014cac5b180856e2fa302defd2cd9f834905df9 Mon Sep 17 00:00:00 2001 From: Andie Montoya Date: Mon, 24 Jan 2022 17:18:10 -0800 Subject: [PATCH 057/100] Fix formatting --- src/odbc/src/config/connection_string_parser.cpp | 2 +- src/odbc/src/connection.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index 8882792b2..e6857dcf1 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -408,7 +408,7 @@ namespace ignite if (diag) { diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Default fetch size attribute value is too large." + MakeErrorMessage("Scan limit size attribute value is too large." " Using default value.", key, value)); } diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index b2a471529..db1a0fec2 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -684,7 +684,7 @@ namespace ignite return jdbConnectionString; } - /** + /** * Create JVM options from configuration. * * @param cfg Configuration. From 4c49492cad9728ecd4003f7847f0e65228b6d9e2 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 09:16:49 -0800 Subject: [PATCH 058/100] [AD-522] add HasText() function to window.h * previously, the definition of HasText was mistakenly committed in commit cbaeedd0cde8b82bc29134efcad28dba943751c2. * add header of HasText() to resolve building errors in origin * update HasText() function to make code simpler --- .../win/include/ignite/odbc/system/ui/window.h | 7 +++++++ src/odbc/os/win/src/system/ui/window.cpp | 17 +++++++++-------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/odbc/os/win/include/ignite/odbc/system/ui/window.h b/src/odbc/os/win/include/ignite/odbc/system/ui/window.h index 32a54b200..86681af9c 100644 --- a/src/odbc/os/win/include/ignite/odbc/system/ui/window.h +++ b/src/odbc/os/win/include/ignite/odbc/system/ui/window.h @@ -115,6 +115,13 @@ namespace ignite */ void SetText(const std::string& text) const; + /** + * Check if the window has text. + * + * @return True if has text. + */ + bool HasText() const; + /** * Get CheckBox state. * diff --git a/src/odbc/os/win/src/system/ui/window.cpp b/src/odbc/os/win/src/system/ui/window.cpp index b4a64bd8b..097dee836 100644 --- a/src/odbc/os/win/src/system/ui/window.cpp +++ b/src/odbc/os/win/src/system/ui/window.cpp @@ -160,17 +160,18 @@ namespace ignite } bool Window::HasText() const { - if (!IsEnabled()) { - return false; - } + return IsEnabled() && GetWindowTextLength(handle) > 0; + //if (!IsEnabled()) { + // return false; + //} - int len = GetWindowTextLength(handle); + //int len = GetWindowTextLength(handle); - if (len <= 0) { - return false; - } + //if (len <= 0) { + // return false; + //} - return true; + //return true; } bool Window::IsChecked() const From b0b731bd7416fab92084c87beebdff60c6c7514d Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 11:09:05 -0800 Subject: [PATCH 059/100] [AD-522] make "rs0" the default value of replicaSet --- src/odbc/src/config/configuration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 3d99ca6b9..43289d4ab 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -63,7 +63,7 @@ namespace ignite const std::string Configuration::DefaultValue::appName = "Amazon DocumentDB ODBC Driver"; const int32_t Configuration::DefaultValue::loginTimeoutSec = 0; const ReadPreference::Type Configuration::DefaultValue::readPreference = ReadPreference::Type::PRIMARY; - const std::string Configuration::DefaultValue::replicaSet = ""; + const std::string Configuration::DefaultValue::replicaSet = "rs0"; const bool Configuration::DefaultValue::retryReads = true; const int32_t Configuration::DefaultValue::defaultFetchSize = 2000; From b7d3b881f1c516fc362ef669f03c711030934647 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 11:14:14 -0800 Subject: [PATCH 060/100] [AD-522] implement database, hostname, port fields. And disable ok button unless all required fields are filled * implement database, hostname, port fields. * disable ok button unless all required fields (database, hostname, port, username, password) are filled * added boolean created to indicate whether the configuration window has been created. If has, then check for disabling/enabling the Ok button --- .../odbc/system/ui/dsn_configuration_window.h | 35 +++++++ .../system/ui/dsn_configuration_window.cpp | 99 ++++++++++++++++--- 2 files changed, 123 insertions(+), 11 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index f6e747eef..0bf963e57 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -87,6 +87,14 @@ namespace ignite TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, TLS_CA_FILE_EDIT, TLS_CA_FILE_LABEL, + DRIVER_LABEL, + DRIVER_EDIT, + DATABASE_LABEL, + DATABASE_EDIT, + HOST_NAME_LABEL, + HOST_NAME_EDIT, + PORT_LABEL, + PORT_EDIT, USER_LABEL, USER_EDIT, PASSWORD_LABEL, @@ -376,6 +384,30 @@ namespace ignite /** TLS certificate authority file edit. */ std::auto_ptr tlsCaFileEdit; + ///** Driver label. */ + //std::auto_ptr driverLabel; + + ///** Driver edit. */ + //std::auto_ptr driverEdit; + + /** Database label. */ + std::auto_ptr databaseLabel; + + /** Database edit. */ + std::auto_ptr databaseEdit; + + /** Hostname label. */ + std::auto_ptr hostnameLabel; + + /** Hostname edit. */ + std::auto_ptr hostnameEdit; + + /** Port label. */ + std::auto_ptr portLabel; + + /** Port edit. */ + std::auto_ptr portEdit; + /** User label. */ std::auto_ptr userLabel; @@ -393,6 +425,9 @@ namespace ignite /** Flag indicating whether OK option was selected. */ bool accepted; + + /** Flag indicating whether the configuration window has been created. */ + bool created; }; } } diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 2259797b4..bf37bc883 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -76,6 +76,14 @@ namespace ignite defaultFetchSizeEdit(), protocolVersionLabel(), protocolVersionComboBox(), + //driverLabel(), + //driverEdit(), + databaseLabel(), + databaseEdit(), + hostnameLabel(), + hostnameEdit(), + portLabel(), + portEdit(), userLabel(), userEdit(), passwordLabel(), @@ -83,7 +91,8 @@ namespace ignite okButton(), cancelButton(), config(config), - accepted(false) + accepted(false), + created(false) { // No-op. } @@ -149,6 +158,13 @@ namespace ignite cancelButton = CreateButton(cancelPosX, groupPosYRight, BUTTON_WIDTH, BUTTON_HEIGHT, "Cancel", ChildId::CANCEL_BUTTON); + // check whether the required fields are filled. If not, Ok button is disabled. + created = true; + okButton->SetEnabled( + userEdit->HasText() && passwordEdit->HasText() + && databaseEdit->HasText() && hostnameEdit->HasText() + && portEdit->HasText()); + // original code by Ignite //okButton = CreateButton(okPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, "Ok", ChildId::OK_BUTTON); //cancelButton = CreateButton(cancelPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, @@ -232,7 +248,35 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; - const char* val = config.GetUser().c_str(); + const char* val = config.GetHostname().c_str(); + hostnameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Hostname :", ChildId::HOST_NAME_LABEL); + hostnameEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::HOST_NAME_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + std::string tmp = common::LexicalCast(config.GetTcpPort()); + val = tmp.c_str(); + portLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Port:", ChildId::PORT_LABEL); + portEdit = CreateEdit( + editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::PORT_EDIT, ES_NUMBER); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetDatabase().c_str(); + databaseLabel = + CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Database :", ChildId::DATABASE_LABEL); + databaseEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, ChildId::DATABASE_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetUser().c_str(); userLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "User :", ChildId::USER_LABEL); userEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::USER_EDIT); @@ -554,7 +598,6 @@ namespace ignite // rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight // I believe - //TODO readPreference ReadPreference::Type readPreference = config.GetReadPreference(); std::string readPreferenceStr = ReadPreference::ToString(readPreference); @@ -667,6 +710,25 @@ namespace ignite break; } + case ChildId::HOST_NAME_EDIT: + case ChildId::PORT_EDIT: + case ChildId::DATABASE_EDIT: + case ChildId::USER_EDIT: + case ChildId::PASSWORD_EDIT: + { + // if window has been created. Check + if (created) { + okButton->SetEnabled( + userEdit->HasText() + && passwordEdit->HasText() + && databaseEdit->HasText() + && hostnameEdit->HasText() + && portEdit->HasText()); + } + break; + } + + case ChildId::SSH_ENABLE_CHECK_BOX: { sshEnableCheckBox->SetChecked(!sshEnableCheckBox->IsChecked()); @@ -798,14 +860,29 @@ namespace ignite void DsnConfigurationWindow::RetrieveAuthParameters(config::Configuration& cfg) const { - std::string user; - std::string password; - - userEdit->GetText(user); - passwordEdit->GetText(password); - - cfg.SetUser(user); - cfg.SetPassword(password); + std::string hostnameStr; + std::string portStr; + std::string databaseStr; + std::string userStr; + std::string passwordStr; + + hostnameEdit->GetText(hostnameStr); + portEdit->GetText(portStr); + databaseEdit->GetText(databaseStr); + userEdit->GetText(userStr); + passwordEdit->GetText(passwordStr); + + int16_t port = + common::LexicalCast(portStr); + + if (port <= 0) + port = config.GetTcpPort(); + + cfg.SetTcpPort(port); + cfg.SetHostname(hostnameStr); + cfg.SetDatabase(databaseStr); + cfg.SetUser(userStr); + cfg.SetPassword(passwordStr); } void DsnConfigurationWindow::RetrieveSshParameters(config::Configuration& cfg) const From 78426888d6bbaa09e74984d2e8ef2a6d28ca9ea8 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 11:34:37 -0800 Subject: [PATCH 061/100] [AD-522] rename SSH Known Hosts File label for clarity --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index bf37bc883..ae945b509 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -349,7 +349,7 @@ namespace ignite val = config.GetSshKnownHostsFile().c_str(); sshKnownHostsFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSH Known Hosts:", ChildId::SSH_KNOWN_HOSTS_FILE_LABEL); + "SSH Known Hosts File:", ChildId::SSH_KNOWN_HOSTS_FILE_LABEL); sshKnownHostsFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_KNOWN_HOSTS_FILE_EDIT); From 95fda4cb484513094bd5dc2d88c1daa97152f39a Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 11:35:44 -0800 Subject: [PATCH 062/100] [AD-522] refactor logs for retrieving TSL settings Make the sentences align --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index ae945b509..d10a63976 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -930,9 +930,9 @@ namespace ignite tlsCaFileEdit->GetText(tlsCaStr); - LOG_MSG("TLS/SSL Encryption: " << (tls ? "true" : "false")); - LOG_MSG("tls Allow Invalid Hostnames: " << (tlsAllowInvalidHostnames ? "true" : "false")); - LOG_MSG("TLS CA (Certificate Authority): " << tlsCaStr); + LOG_MSG("TLS/SSL Encryption: " << (tls ? "true" : "false")); + LOG_MSG("tls Allow Invalid Hostnames: " << (tlsAllowInvalidHostnames ? "true" : "false")); + LOG_MSG("TLS CA (Certificate Authority) File name: " << tlsCaStr); cfg.SetTls(tls); cfg.SetTlsAllowInvalidHostnames(tlsAllowInvalidHostnames); From 0018921a3bc58eb259423299b1db7adce30139e7 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 11:41:03 -0800 Subject: [PATCH 063/100] [AD-522] rename TLS CA File label for clarity * change label length to the same label length as connection settings group --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index d10a63976..3c50fe2be 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -422,8 +422,8 @@ namespace ignite int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) { // TODO: rename function name from Ssl to TLS after UI works - - enum { LABEL_WIDTH = 120 }; + + enum { LABEL_WIDTH = 100 }; int labelPosX = posX + INTERVAL; @@ -449,7 +449,7 @@ namespace ignite const char* val = config.GetTlsCaFile().c_str(); tlsCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "TLS Certificate Authority:", ChildId::TLS_CA_FILE_LABEL); + "TLS CA File:", ChildId::TLS_CA_FILE_LABEL); tlsCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::TLS_CA_FILE_EDIT); From 982ac4ee97b67125439f24489b94141a413c9d73 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 11:47:44 -0800 Subject: [PATCH 064/100] [AD-522] move authorization setting fields to connection fields reason: only username and password are authorization settings, the rest are not. We chose to put username, password in the connections group because all fields in the connections group are required. --- .../odbc/system/ui/dsn_configuration_window.h | 10 +-- .../system/ui/dsn_configuration_window.cpp | 81 ++++++++++++++++++- 2 files changed, 83 insertions(+), 8 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 0bf963e57..41114e706 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -49,7 +49,7 @@ namespace ignite SSH_SETTINGS_GROUP_BOX, SSL_SETTINGS_GROUP_BOX, ADDITIONAL_SETTINGS_GROUP_BOX, - AUTH_SETTINGS_GROUP_BOX, + //AUTH_SETTINGS_GROUP_BOX, NAME_EDIT, NAME_LABEL, ADDRESS_EDIT, @@ -172,7 +172,7 @@ namespace ignite * * @param cfg Configuration. */ - void RetrieveAuthParameters(config::Configuration& cfg) const; + //void RetrieveAuthParameters(config::Configuration& cfg) const; /** * Retrieves current values from the SSH tunnel UI group and @@ -216,7 +216,7 @@ namespace ignite * @param sizeX Width. * @return Size by Y. */ - int CreateAuthSettingsGroup(int posX, int posY, int sizeX); + //int CreateAuthSettingsGroup(int posX, int posY, int sizeX); /** * Create internal SSH tunnel settings group box. @@ -263,8 +263,8 @@ namespace ignite /** SSL settings group box. */ std::auto_ptr sslSettingsGroupBox; - /** Authentication settings group box. */ - std::auto_ptr authSettingsGroupBox; + ///** Authentication settings group box. */ + //std::auto_ptr authSettingsGroupBox; /** Additional settings group box. */ std::auto_ptr additionalSettingsGroupBox; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 3c50fe2be..12ee1bd0d 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -43,7 +43,7 @@ namespace ignite connectionSettingsGroupBox(), sslSettingsGroupBox(), // has a create... function defined tlsCheckBox(), - authSettingsGroupBox(), + //authSettingsGroupBox(), additionalSettingsGroupBox(), nameLabel(), nameEdit(), @@ -141,8 +141,8 @@ namespace ignite // create left column group settings groupPosYLeft += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); - groupPosYLeft += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); groupPosYLeft += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); + //groupPosYLeft += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); // create right column group settings groupPosYRight += INTERVAL + CreateSshSettingsGroup(posXRight, groupPosYRight, groupSizeY); groupPosYRight += INTERVAL + CreateAdditionalSettingsGroup(posXRight, groupPosYRight, groupSizeY); @@ -189,6 +189,49 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; + val = config.GetHostname().c_str(); + hostnameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Hostname :", ChildId::HOST_NAME_LABEL); + hostnameEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::HOST_NAME_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + std::string tmp = common::LexicalCast(config.GetTcpPort()); + val = tmp.c_str(); + portLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Port:", ChildId::PORT_LABEL); + portEdit = CreateEdit( + editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::PORT_EDIT, ES_NUMBER); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetDatabase().c_str(); + databaseLabel = + CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Database :", ChildId::DATABASE_LABEL); + databaseEdit = CreateEdit(editPosX, rowPos, editSizeX, + ROW_HEIGHT, val, ChildId::DATABASE_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetUser().c_str(); + userLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "User :", ChildId::USER_LABEL); + userEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::USER_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetPassword().c_str(); + passwordLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Password:", ChildId::PASSWORD_LABEL); + passwordEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::USER_EDIT, ES_PASSWORD); + + rowPos += INTERVAL + ROW_HEIGHT; + + /* // original code for hostname std::string addr = config.GetHostname(); val = addr.c_str(); @@ -197,6 +240,7 @@ namespace ignite addressEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::ADDRESS_EDIT); rowPos += INTERVAL + ROW_HEIGHT; + */ val = config.GetDatabase().c_str(); schemaLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, @@ -237,6 +281,8 @@ namespace ignite return rowPos - posY; } + // comment out authSettingsGroup because they are no longer needed + /* int DsnConfigurationWindow::CreateAuthSettingsGroup(int posX, int posY, int sizeX) { enum { LABEL_WIDTH = 120 }; @@ -295,6 +341,7 @@ namespace ignite return rowPos - posY; } + */ int DsnConfigurationWindow::CreateSshSettingsGroup(int posX, int posY, int sizeX) { @@ -804,7 +851,7 @@ namespace ignite void DsnConfigurationWindow::RetrieveParameters(config::Configuration& cfg) const { RetrieveConnectionParameters(cfg); - RetrieveAuthParameters(cfg); + //RetrieveAuthParameters(cfg); RetrieveSshParameters(cfg); RetrieveSslParameters(cfg); RetrieveAdditionalParameters(cfg); @@ -817,6 +864,12 @@ namespace ignite std::string schemaStr; std::string versionStr; + std::string hostnameStr; + std::string portStr; + std::string databaseStr; + std::string userStr; + std::string passwordStr; + nameEdit->GetText(dsnStr); addressEdit->GetText(addressStr); schemaEdit->GetText(schemaStr); @@ -826,12 +879,25 @@ namespace ignite common::StripSurroundingWhitespaces(dsnStr); // Stripping of whitespaces off the schema skipped intentionally + hostnameEdit->GetText(hostnameStr); + portEdit->GetText(portStr); + databaseEdit->GetText(databaseStr); + userEdit->GetText(userStr); + passwordEdit->GetText(passwordStr); + + int16_t port = common::LexicalCast< int16_t >(portStr); + + if (port <= 0) + port = config.GetTcpPort(); + LOG_MSG("Retrieving arguments:"); LOG_MSG("DSN: " << dsnStr); LOG_MSG("Address: " << addressStr); LOG_MSG("Schema: " << schemaStr); LOG_MSG("Protocol version: " << versionStr); + // username and password intentionally not logged for security reasons + if (dsnStr.empty()) throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "DSN name can not be empty."); @@ -856,8 +922,16 @@ namespace ignite //cfg.SetAddresses(addresses); cfg.SetDatabase(schemaStr); //cfg.SetProtocolVersion(version); + + cfg.SetTcpPort(port); + cfg.SetHostname(hostnameStr); + cfg.SetDatabase(databaseStr); + cfg.SetUser(userStr); + cfg.SetPassword(passwordStr); } + // comment out because no longer needed + /* void DsnConfigurationWindow::RetrieveAuthParameters(config::Configuration& cfg) const { std::string hostnameStr; @@ -884,6 +958,7 @@ namespace ignite cfg.SetUser(userStr); cfg.SetPassword(passwordStr); } + */ void DsnConfigurationWindow::RetrieveSshParameters(config::Configuration& cfg) const { From a4d2e0d817fea0b9c910a986ecccb6a737aa7390 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 12:46:05 -0800 Subject: [PATCH 065/100] [AD-522] bugfix-comment out address field related code in RetrieveConnectionParameters --- .../os/win/src/system/ui/dsn_configuration_window.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 12ee1bd0d..73e90c250 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -860,7 +860,7 @@ namespace ignite void DsnConfigurationWindow::RetrieveConnectionParameters(config::Configuration& cfg) const { std::string dsnStr; - std::string addressStr; + //std::string addressStr; std::string schemaStr; std::string versionStr; @@ -871,11 +871,11 @@ namespace ignite std::string passwordStr; nameEdit->GetText(dsnStr); - addressEdit->GetText(addressStr); + //addressEdit->GetText(addressStr); schemaEdit->GetText(schemaStr); protocolVersionComboBox->GetText(versionStr); - common::StripSurroundingWhitespaces(addressStr); + //common::StripSurroundingWhitespaces(addressStr); common::StripSurroundingWhitespaces(dsnStr); // Stripping of whitespaces off the schema skipped intentionally @@ -892,7 +892,7 @@ namespace ignite LOG_MSG("Retrieving arguments:"); LOG_MSG("DSN: " << dsnStr); - LOG_MSG("Address: " << addressStr); + //LOG_MSG("Address: " << addressStr); LOG_MSG("Schema: " << schemaStr); LOG_MSG("Protocol version: " << versionStr); @@ -905,7 +905,7 @@ namespace ignite std::vector addresses; - config::ParseAddress(addressStr, addresses, &diag); + //config::ParseAddress(addressStr, addresses, &diag); if (diag.GetStatusRecordsNumber() > 0) { From 260e6629fd727cac54224c8d535b4abc1e2195c3 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 12:53:29 -0800 Subject: [PATCH 066/100] [AD-522] rename sslSettings to tlsSettings and add comment for connection settings group --- .../ignite/odbc/system/ui/dsn_configuration_window.h | 8 ++++---- .../win/src/system/ui/dsn_configuration_window.cpp | 12 ++++++------ src/odbc/src/config/configuration.cpp | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 41114e706..9b7329a36 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -188,7 +188,7 @@ namespace ignite * * @param cfg Configuration. */ - void RetrieveSslParameters(config::Configuration& cfg) const; + void RetrieveTlsParameters(config::Configuration& cfg) const; /** * Retrieves current values from the additional UI group and @@ -236,7 +236,7 @@ namespace ignite * @param sizeX Width. * @return Size by Y. */ - int CreateSslSettingsGroup(int posX, int posY, int sizeX); + int CreateTlsSettingsGroup(int posX, int posY, int sizeX); /** * Create additional settings group box. @@ -260,8 +260,8 @@ namespace ignite /** SSH settings group box. */ std::auto_ptr sshSettingsGroupBox; - /** SSL settings group box. */ - std::auto_ptr sslSettingsGroupBox; + /** TLS settings group box. */ + std::auto_ptr tlsSettingsGroupBox; ///** Authentication settings group box. */ //std::auto_ptr authSettingsGroupBox; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 73e90c250..182effad8 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -41,7 +41,7 @@ namespace ignite //width(360), //height(800), connectionSettingsGroupBox(), - sslSettingsGroupBox(), // has a create... function defined + tlsSettingsGroupBox(), // has a create... function defined tlsCheckBox(), //authSettingsGroupBox(), additionalSettingsGroupBox(), @@ -141,8 +141,8 @@ namespace ignite // create left column group settings groupPosYLeft += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); - groupPosYLeft += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); //groupPosYLeft += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); + groupPosYLeft += INTERVAL + CreateTlsSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); // create right column group settings groupPosYRight += INTERVAL + CreateSshSettingsGroup(posXRight, groupPosYRight, groupSizeY); groupPosYRight += INTERVAL + CreateAdditionalSettingsGroup(posXRight, groupPosYRight, groupSizeY); @@ -467,7 +467,7 @@ namespace ignite } */ - int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) + int DsnConfigurationWindow::CreateTlsSettingsGroup(int posX, int posY, int sizeX) { // TODO: rename function name from Ssl to TLS after UI works enum { LABEL_WIDTH = 100 }; @@ -502,7 +502,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, + tlsSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "TLS/SSL Settings", ChildId::SSL_SETTINGS_GROUP_BOX); tlsAllowInvalidHostnamesCheckBox->SetEnabled(tlsCheckBox->IsChecked()); @@ -853,7 +853,7 @@ namespace ignite RetrieveConnectionParameters(cfg); //RetrieveAuthParameters(cfg); RetrieveSshParameters(cfg); - RetrieveSslParameters(cfg); + RetrieveTlsParameters(cfg); RetrieveAdditionalParameters(cfg); } @@ -996,7 +996,7 @@ namespace ignite } - void DsnConfigurationWindow::RetrieveSslParameters(config::Configuration& cfg) const + void DsnConfigurationWindow::RetrieveTlsParameters(config::Configuration& cfg) const { bool tls = tlsCheckBox->IsChecked(); diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 43289d4ab..bc85adb80 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -30,7 +30,7 @@ namespace ignite { namespace config { - + // Connection Settings const std::string Configuration::DefaultValue::dsn = "DocumentDB DSN"; const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB ODBC Driver"; const std::string Configuration::DefaultValue::database = ""; From 0063e20dfbae4b2ee989ea17cbcd8a9c559f7491 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 13:20:41 -0800 Subject: [PATCH 067/100] [AD-522] remove protocol version from config window --- .../odbc/system/ui/dsn_configuration_window.h | 18 +++---- .../system/ui/dsn_configuration_window.cpp | 50 +++++++++---------- 2 files changed, 34 insertions(+), 34 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 9b7329a36..7414e3a71 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -22,7 +22,7 @@ #include "ignite/odbc/system/ui/custom_window.h" // TODO: Removed these from configuration.h since no longer used. Moved here since they are still referenced. Remove when no longer needed. #include "ignite/odbc/nested_tx_mode.h" -#include "ignite/odbc/protocol_version.h" +//#include "ignite/odbc/protocol_version.h" #include "ignite/odbc/ssl_mode.h" namespace ignite @@ -52,8 +52,8 @@ namespace ignite //AUTH_SETTINGS_GROUP_BOX, NAME_EDIT, NAME_LABEL, - ADDRESS_EDIT, - ADDRESS_LABEL, + //ADDRESS_EDIT, + //ADDRESS_LABEL, SCHEMA_EDIT, SCHEMA_LABEL, SSH_ENABLE_CHECK_BOX, @@ -79,8 +79,8 @@ namespace ignite RETRY_READS_CHECK_BOX, DEFAULT_FETCH_SIZE_EDIT, DEFAULT_FETCH_SIZE_LABEL, - PROTOCOL_VERSION_LABEL, - PROTOCOL_VERSION_COMBO_BOX, + //PROTOCOL_VERSION_LABEL, + //PROTOCOL_VERSION_COMBO_BOX, //NESTED_TX_MODE_LABEL, //NESTED_TX_MODE_COMBO_BOX, TLS_CHECK_BOX, @@ -360,11 +360,11 @@ namespace ignite /** Default fetch size label. */ std::auto_ptr defaultFetchSizeLabel; - /** Protocol version edit field. */ - std::auto_ptr protocolVersionLabel; + ///** Protocol version edit field. */ + //std::auto_ptr protocolVersionLabel; - /** Protocol verion ComboBox. */ - std::auto_ptr protocolVersionComboBox; + ///** Protocol verion ComboBox. */ + //std::auto_ptr protocolVersionComboBox; /** Ok button. */ std::auto_ptr okButton; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 182effad8..519d04347 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -74,8 +74,8 @@ namespace ignite retryReadsCheckBox(), defaultFetchSizeLabel(), defaultFetchSizeEdit(), - protocolVersionLabel(), - protocolVersionComboBox(), + //protocolVersionLabel(), + //protocolVersionComboBox(), //driverLabel(), //driverEdit(), databaseLabel(), @@ -249,31 +249,31 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - protocolVersionLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Protocol Version:", ChildId::PROTOCOL_VERSION_LABEL); - protocolVersionComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, - "Protocol Version", ChildId::PROTOCOL_VERSION_COMBO_BOX); + //protocolVersionLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + // "Protocol Version:", ChildId::PROTOCOL_VERSION_LABEL); + //protocolVersionComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, + // "Protocol Version", ChildId::PROTOCOL_VERSION_COMBO_BOX); - int id = 0; + //int id = 0; - const ProtocolVersion::VersionSet& supported = ProtocolVersion::GetSupported(); + //const ProtocolVersion::VersionSet& supported = ProtocolVersion::GetSupported(); - ProtocolVersion version = ProtocolVersion::GetCurrent(); + //ProtocolVersion version = ProtocolVersion::GetCurrent(); - if (!version.IsSupported()) - version = ProtocolVersion::GetCurrent(); + //if (!version.IsSupported()) + // version = ProtocolVersion::GetCurrent(); - for (ProtocolVersion::VersionSet::const_iterator it = supported.begin(); it != supported.end(); ++it) - { - protocolVersionComboBox->AddString(it->ToString()); + //for (ProtocolVersion::VersionSet::const_iterator it = supported.begin(); it != supported.end(); ++it) + //{ + // protocolVersionComboBox->AddString(it->ToString()); - if (*it == version) - protocolVersionComboBox->SetSelection(id); + // if (*it == version) + // protocolVersionComboBox->SetSelection(id); - ++id; - } + // ++id; + //} - rowPos += INTERVAL + ROW_HEIGHT; + //rowPos += INTERVAL + ROW_HEIGHT; connectionSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "Connection Settings", ChildId::CONNECTION_SETTINGS_GROUP_BOX); @@ -862,7 +862,7 @@ namespace ignite std::string dsnStr; //std::string addressStr; std::string schemaStr; - std::string versionStr; + //std::string versionStr; std::string hostnameStr; std::string portStr; @@ -873,7 +873,7 @@ namespace ignite nameEdit->GetText(dsnStr); //addressEdit->GetText(addressStr); schemaEdit->GetText(schemaStr); - protocolVersionComboBox->GetText(versionStr); + //protocolVersionComboBox->GetText(versionStr); //common::StripSurroundingWhitespaces(addressStr); common::StripSurroundingWhitespaces(dsnStr); @@ -894,7 +894,7 @@ namespace ignite LOG_MSG("DSN: " << dsnStr); //LOG_MSG("Address: " << addressStr); LOG_MSG("Schema: " << schemaStr); - LOG_MSG("Protocol version: " << versionStr); + //LOG_MSG("Protocol version: " << versionStr); // username and password intentionally not logged for security reasons @@ -913,10 +913,10 @@ namespace ignite diag.GetStatusRecord(1).GetMessageText().c_str()); } - ProtocolVersion version = ProtocolVersion::FromString(versionStr); + //ProtocolVersion version = ProtocolVersion::FromString(versionStr); - if (!version.IsSupported()) - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Protocol version is not supported."); + /*if (!version.IsSupported()) + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Protocol version is not supported.");*/ cfg.SetDsn(dsnStr); //cfg.SetAddresses(addresses); From bd62805102278c81fd3dd40d9410034638d04a02 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 13:50:42 -0800 Subject: [PATCH 068/100] [AD-522] bug fix sshKnownHostsFile not saved when Ok button is pressed --- src/odbc/src/dsn_config.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index 3126580b3..da7c8cabe 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -204,8 +204,8 @@ namespace ignite SettableValue sshKnownHostsFile = ReadDsnString(dsn, ConnectionStringParser::Key::sshKnownHostsFile); - if (sshKnownHostsFile.IsSet() && !config.IsSshStrictHostKeyCheckingSet()) - config.SetSshStrictHostKeyChecking(sshStrictHostKeyChecking.GetValue()); + if (sshKnownHostsFile.IsSet() && !config.IsSshKnownHostsFileSet()) + config.SetSshKnownHostsFile(sshKnownHostsFile.GetValue()); SettableValue scanMethod = ReadDsnString(dsn, ConnectionStringParser::Key::scanMethod); From bddf4b54b8c41e88eb876ad33ac13146b513e07c Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 13:51:19 -0800 Subject: [PATCH 069/100] [AD-522] remove commented out #include headers --- src/odbc/src/config/connection_string_parser.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index d63a252f6..335de7b6a 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -20,10 +20,8 @@ #include "ignite/common/utils.h" #include "ignite/odbc/utility.h" -//#include "ignite/odbc/ssl_mode.h" #include "ignite/odbc/config/connection_string_parser.h" #include "ignite/odbc/config/config_tools.h" -//#include "ignite/odbc/nested_tx_mode.h" namespace ignite { From 8a3e732c579e20979ab443712c2696d14711d3fc Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 13:57:33 -0800 Subject: [PATCH 070/100] [AD-522] disable SSH Known Hosts File edit when SSH Strict Host Key Check check box is unchecked * move SSH Strict Host Key Checking check box above SSH Known Hosts File edit in the config window --- .../system/ui/dsn_configuration_window.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 519d04347..e49692f3e 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -394,18 +394,19 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT * 2; + // SSH Strict Host Key Check check box needs to have editSizeX as size because the string is long + sshStrictHostKeyCheckingCheckBox = CreateCheckBox( + labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "SSH Strict Host Key Check (disabling option is less secure)", + ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX, config.IsSshStrictHostKeyChecking()); + + rowPos += INTERVAL + ROW_HEIGHT; + val = config.GetSshKnownHostsFile().c_str(); sshKnownHostsFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSH Known Hosts File:", ChildId::SSH_KNOWN_HOSTS_FILE_LABEL); sshKnownHostsFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_KNOWN_HOSTS_FILE_EDIT); - rowPos += INTERVAL + ROW_HEIGHT; - // SSH Strict Host Key Check check box needs to have editSizeX as size because the string is long - sshStrictHostKeyCheckingCheckBox = CreateCheckBox( - labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, "SSH Strict Host Key Check (disabling option is less secure)", - ChildId::SSH_STRICT_HOST_KEY_CHECKING_CHECK_BOX, config.IsSshStrictHostKeyChecking()); - rowPos += INTERVAL + ROW_HEIGHT; sshSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, @@ -416,8 +417,10 @@ namespace ignite sshHostEdit->SetEnabled(sshEnableCheckBox->IsChecked()); sshPrivateKeyFileEdit->SetEnabled( sshEnableCheckBox->IsChecked()); sshPrivateKeyPassphraseEdit->SetEnabled(sshEnableCheckBox->IsChecked()); - sshKnownHostsFileEdit->SetEnabled(sshEnableCheckBox->IsChecked()); sshStrictHostKeyCheckingCheckBox->SetEnabled(sshEnableCheckBox->IsChecked()); + sshKnownHostsFileEdit->SetEnabled( + sshEnableCheckBox->IsChecked() + && sshStrictHostKeyCheckingCheckBox->IsChecked()); return rowPos - posY; } @@ -790,7 +793,8 @@ namespace ignite ->SetEnabled( sshEnableCheckBox->IsChecked()); sshKnownHostsFileEdit->SetEnabled( - sshEnableCheckBox->IsChecked()); + sshEnableCheckBox->IsChecked() + && sshStrictHostKeyCheckingCheckBox->IsChecked()); break; } @@ -799,6 +803,9 @@ namespace ignite { sshStrictHostKeyCheckingCheckBox ->SetChecked(!sshStrictHostKeyCheckingCheckBox->IsChecked()); + sshKnownHostsFileEdit->SetEnabled( + sshEnableCheckBox->IsChecked() + && sshStrictHostKeyCheckingCheckBox->IsChecked()); break; } @@ -983,16 +990,16 @@ namespace ignite LOG_MSG("SSH host: " << sshHostStr); LOG_MSG("SSH private key file: " << sshPrivateKeyFileStr); LOG_MSG("SSH private key passphrase: " << sshPrivateKeyPassphraseStr); - LOG_MSG("SSH known hosts file: " << sshKnownHostsFileStr); LOG_MSG("SSH strict host key checking: " << (sshStrictHostKeyChecking ? "true" : "false")); + LOG_MSG("SSH known hosts file: " << sshKnownHostsFileStr); cfg.SetSshEnable(sshEnable); cfg.SetSshUser(sshUserStr); cfg.SetSshHost(sshHostStr); cfg.SetSshPrivateKeyFile(sshPrivateKeyFileStr); cfg.SetSshPrivateKeyPassphrase(sshPrivateKeyPassphraseStr); - cfg.SetSshKnownHostsFile(sshKnownHostsFileStr); cfg.SetSshStrictHostKeyChecking(sshStrictHostKeyChecking); + cfg.SetSshKnownHostsFile(sshKnownHostsFileStr); } From 57cceddddfa55942b7a093e90a8ec3c483d9a3b6 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 13:57:59 -0800 Subject: [PATCH 071/100] [AD-522] refactor - remove commented out header code --- .../include/ignite/odbc/system/ui/dsn_configuration_window.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 7414e3a71..824d0f769 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -21,9 +21,9 @@ #include "ignite/odbc/config/configuration.h" #include "ignite/odbc/system/ui/custom_window.h" // TODO: Removed these from configuration.h since no longer used. Moved here since they are still referenced. Remove when no longer needed. -#include "ignite/odbc/nested_tx_mode.h" +//#include "ignite/odbc/nested_tx_mode.h" //#include "ignite/odbc/protocol_version.h" -#include "ignite/odbc/ssl_mode.h" +//#include "ignite/odbc/ssl_mode.h" namespace ignite { From efe493a63321684fcdc2d27dec3e29e9e46c290b Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 14:29:14 -0800 Subject: [PATCH 072/100] [AD-522] add comments in configuration.cpp for planning * modify commented out example code in dsn_configuration_window.cpp for clarity --- .../os/win/src/system/ui/dsn_configuration_window.cpp | 4 ++-- src/odbc/src/config/configuration.cpp | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index e49692f3e..7a2d21af8 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -629,8 +629,8 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; // useful draft code for changing read preference into a - // mode (check JDBC page for available options) const char* - // val = sslModeStr.c_str(); + // mode (check JDBC page for available options) + // const char* val = sslModeStr.c_str(); // sslModeLabel = CreateLabel(labelPosX, rowPos, // LABEL_WIDTH, ROW_HEIGHT, diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index bc85adb80..314e67af1 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -32,10 +32,11 @@ namespace ignite { // Connection Settings const std::string Configuration::DefaultValue::dsn = "DocumentDB DSN"; - const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB ODBC Driver"; - const std::string Configuration::DefaultValue::database = ""; - const std::string Configuration::DefaultValue::hostname = ""; - const uint16_t Configuration::DefaultValue::port = 27017; + const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB ODBC Driver"; // -AL- add (= need to add to UI) + // driver does not need to be added in config window since it is chosen at the Data Source Administrator + const std::string Configuration::DefaultValue::database = ""; // -AL- add + const std::string Configuration::DefaultValue::hostname = ""; // -AL- add + const uint16_t Configuration::DefaultValue::port = 27017; // -AL- add const std::string Configuration::DefaultValue::user = ""; const std::string Configuration::DefaultValue::password = ""; From 0d04801e1a69192d7a9cdd63cc3b7b9600454395 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 14:30:22 -0800 Subject: [PATCH 073/100] [AD-522] change from SSL to TLS for consistency * SSL_SETTINGS_GROUP_BOX is changed to TLS_SETTINGS_GROUP_BOX --- .../ignite/odbc/system/ui/dsn_configuration_window.h | 6 +++--- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 824d0f769..094d69270 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -47,7 +47,7 @@ namespace ignite { CONNECTION_SETTINGS_GROUP_BOX = 100, SSH_SETTINGS_GROUP_BOX, - SSL_SETTINGS_GROUP_BOX, + TLS_SETTINGS_GROUP_BOX, ADDITIONAL_SETTINGS_GROUP_BOX, //AUTH_SETTINGS_GROUP_BOX, NAME_EDIT, @@ -183,7 +183,7 @@ namespace ignite void RetrieveSshParameters(config::Configuration& cfg) const; /** - * Retrieves current values from the SSL UI group and + * Retrieves current values from the TLS/SSL UI group and * stores them to the specified configuration. * * @param cfg Configuration. @@ -229,7 +229,7 @@ namespace ignite int CreateSshSettingsGroup(int posX, int posY, int sizeX); /** - * Create SSL settings group box. + * Create TLS/SSL settings group box. * * @param posX X position. * @param posY Y position. diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 7a2d21af8..ca4b91b91 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -506,7 +506,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; tlsSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "TLS/SSL Settings", ChildId::SSL_SETTINGS_GROUP_BOX); + "TLS/SSL Settings", ChildId::TLS_SETTINGS_GROUP_BOX); tlsAllowInvalidHostnamesCheckBox->SetEnabled(tlsCheckBox->IsChecked()); tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); From 2fcfd6d6836bd9ebf4f2a2220751cd5bc70de03f Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 14:38:53 -0800 Subject: [PATCH 074/100] [AD-522] remove commented out code Removed commented out code: * RetrieveAuthParameters * CreateAuthSettingsGroup * CreateAdditionalSettingsGroup function and CreateSslSettingsGroup function for 1 column window * protocol version - related code * authSettingsGroupBox code --- .../odbc/system/ui/dsn_configuration_window.h | 45 --- .../system/ui/dsn_configuration_window.cpp | 293 ------------------ 2 files changed, 338 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 094d69270..dbca6bd5a 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -20,10 +20,6 @@ #include "ignite/odbc/config/configuration.h" #include "ignite/odbc/system/ui/custom_window.h" -// TODO: Removed these from configuration.h since no longer used. Moved here since they are still referenced. Remove when no longer needed. -//#include "ignite/odbc/nested_tx_mode.h" -//#include "ignite/odbc/protocol_version.h" -//#include "ignite/odbc/ssl_mode.h" namespace ignite { @@ -49,11 +45,8 @@ namespace ignite SSH_SETTINGS_GROUP_BOX, TLS_SETTINGS_GROUP_BOX, ADDITIONAL_SETTINGS_GROUP_BOX, - //AUTH_SETTINGS_GROUP_BOX, NAME_EDIT, NAME_LABEL, - //ADDRESS_EDIT, - //ADDRESS_LABEL, SCHEMA_EDIT, SCHEMA_LABEL, SSH_ENABLE_CHECK_BOX, @@ -79,10 +72,6 @@ namespace ignite RETRY_READS_CHECK_BOX, DEFAULT_FETCH_SIZE_EDIT, DEFAULT_FETCH_SIZE_LABEL, - //PROTOCOL_VERSION_LABEL, - //PROTOCOL_VERSION_COMBO_BOX, - //NESTED_TX_MODE_LABEL, - //NESTED_TX_MODE_COMBO_BOX, TLS_CHECK_BOX, TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, TLS_CA_FILE_EDIT, @@ -166,14 +155,6 @@ namespace ignite */ void RetrieveConnectionParameters(config::Configuration& cfg) const; - /** - * Retrieves current values from the Authentication UI group and - * stores them to the specified configuration. - * - * @param cfg Configuration. - */ - //void RetrieveAuthParameters(config::Configuration& cfg) const; - /** * Retrieves current values from the SSH tunnel UI group and * stores them to the specified configuration. @@ -208,16 +189,6 @@ namespace ignite */ int CreateConnectionSettingsGroup(int posX, int posY, int sizeX); - /** - * Create authentication settings group box. - * - * @param posX X position. - * @param posY Y position. - * @param sizeX Width. - * @return Size by Y. - */ - //int CreateAuthSettingsGroup(int posX, int posY, int sizeX); - /** * Create internal SSH tunnel settings group box. * @@ -338,10 +309,6 @@ namespace ignite /** Nested Read Preference ComboBox **/ std::auto_ptr readPreferenceComboBox; - // -AL- remove later - ///** Read preference edit. */ - //std::auto_ptr readPreferenceEdit; - /** Read preference label. */ std::auto_ptr readPreferenceLabel; @@ -360,12 +327,6 @@ namespace ignite /** Default fetch size label. */ std::auto_ptr defaultFetchSizeLabel; - ///** Protocol version edit field. */ - //std::auto_ptr protocolVersionLabel; - - ///** Protocol verion ComboBox. */ - //std::auto_ptr protocolVersionComboBox; - /** Ok button. */ std::auto_ptr okButton; @@ -384,12 +345,6 @@ namespace ignite /** TLS certificate authority file edit. */ std::auto_ptr tlsCaFileEdit; - ///** Driver label. */ - //std::auto_ptr driverLabel; - - ///** Driver edit. */ - //std::auto_ptr driverEdit; - /** Database label. */ std::auto_ptr databaseLabel; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index ca4b91b91..aa2e950cd 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -43,7 +43,6 @@ namespace ignite connectionSettingsGroupBox(), tlsSettingsGroupBox(), // has a create... function defined tlsCheckBox(), - //authSettingsGroupBox(), additionalSettingsGroupBox(), nameLabel(), nameEdit(), @@ -74,10 +73,6 @@ namespace ignite retryReadsCheckBox(), defaultFetchSizeLabel(), defaultFetchSizeEdit(), - //protocolVersionLabel(), - //protocolVersionComboBox(), - //driverLabel(), - //driverEdit(), databaseLabel(), databaseEdit(), hostnameLabel(), @@ -231,17 +226,6 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - /* // original code for hostname - std::string addr = config.GetHostname(); - - val = addr.c_str(); - addressLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Address:", ChildId::ADDRESS_LABEL); - addressEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::ADDRESS_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - */ - val = config.GetDatabase().c_str(); schemaLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "Schema Name:", ChildId::SCHEMA_LABEL); @@ -249,100 +233,12 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - //protocolVersionLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - // "Protocol Version:", ChildId::PROTOCOL_VERSION_LABEL); - //protocolVersionComboBox = CreateComboBox(editPosX, rowPos, editSizeX, ROW_HEIGHT, - // "Protocol Version", ChildId::PROTOCOL_VERSION_COMBO_BOX); - - //int id = 0; - - //const ProtocolVersion::VersionSet& supported = ProtocolVersion::GetSupported(); - - //ProtocolVersion version = ProtocolVersion::GetCurrent(); - - //if (!version.IsSupported()) - // version = ProtocolVersion::GetCurrent(); - - //for (ProtocolVersion::VersionSet::const_iterator it = supported.begin(); it != supported.end(); ++it) - //{ - // protocolVersionComboBox->AddString(it->ToString()); - - // if (*it == version) - // protocolVersionComboBox->SetSelection(id); - - // ++id; - //} - - //rowPos += INTERVAL + ROW_HEIGHT; - connectionSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "Connection Settings", ChildId::CONNECTION_SETTINGS_GROUP_BOX); return rowPos - posY; } - // comment out authSettingsGroup because they are no longer needed - /* - int DsnConfigurationWindow::CreateAuthSettingsGroup(int posX, int posY, int sizeX) - { - enum { LABEL_WIDTH = 120 }; - - int labelPosX = posX + INTERVAL; - - int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL; - int editPosX = labelPosX + LABEL_WIDTH + INTERVAL; - - int rowPos = posY + 2 * INTERVAL; - - const char* val = config.GetHostname().c_str(); - hostnameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Hostname :", ChildId::HOST_NAME_LABEL); - hostnameEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - val, ChildId::HOST_NAME_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - - std::string tmp = common::LexicalCast(config.GetTcpPort()); - val = tmp.c_str(); - portLabel = CreateLabel( - labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Port:", ChildId::PORT_LABEL); - portEdit = CreateEdit( - editPosX, rowPos, editSizeX, ROW_HEIGHT, - val, ChildId::PORT_EDIT, ES_NUMBER); - - rowPos += INTERVAL + ROW_HEIGHT; - - val = config.GetDatabase().c_str(); - databaseLabel = - CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Database :", ChildId::DATABASE_LABEL); - databaseEdit = CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT, val, ChildId::DATABASE_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - - val = config.GetUser().c_str(); - userLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "User :", ChildId::USER_LABEL); - userEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::USER_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - - val = config.GetPassword().c_str(); - passwordLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Password:", ChildId::PASSWORD_LABEL); - passwordEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, - val, ChildId::USER_EDIT, ES_PASSWORD); - - rowPos += INTERVAL + ROW_HEIGHT; - - authSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "Authentication Settings", ChildId::AUTH_SETTINGS_GROUP_BOX); - - return rowPos - posY; - } - */ - int DsnConfigurationWindow::CreateSshSettingsGroup(int posX, int posY, int sizeX) { enum { LABEL_WIDTH = 120 }; // -AL- copied from above function @@ -425,51 +321,6 @@ namespace ignite return rowPos - posY; } - // old SSL settings group code for 1 column config window - /* - int DsnConfigurationWindow::CreateSslSettingsGroup(int posX, int posY, int sizeX) - { // TODO: rename function name from Ssl to TLS after UI works - - enum { LABEL_WIDTH = 120 }; - - int labelPosX = posX + INTERVAL; - - int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL; - int editPosX = labelPosX + LABEL_WIDTH + INTERVAL; - - int rowPos = posY + 2 * INTERVAL; - - int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; - - tlsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "TLS", ChildId::TLS_CHECK_BOX, config.IsTls()); - - tlsAllowInvalidHostnamesCheckBox = CreateCheckBox( - labelPosX + checkBoxSize + INTERVAL, rowPos, - checkBoxSize, ROW_HEIGHT, "TLS Allow Invalid Hostnames", - ChildId::TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, - config.IsTlsAllowInvalidHostnames()); - - rowPos += INTERVAL + ROW_HEIGHT; - - const char* val = config.GetTlsCaFile().c_str(); - tlsCaFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "TLS Certificate Authority:", ChildId::TLS_CA_FILE_LABEL); - tlsCaFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, - ChildId::TLS_CA_FILE_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - - sslSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "TLS/SSL settings", ChildId::SSL_SETTINGS_GROUP_BOX); - - tlsCheckBox->SetEnabled(tlsCheckBox->IsChecked()); - tlsCaFileEdit->SetEnabled(tlsCheckBox->IsChecked()); - - return rowPos - posY; - } - */ - int DsnConfigurationWindow::CreateTlsSettingsGroup(int posX, int posY, int sizeX) { // TODO: rename function name from Ssl to TLS after UI works @@ -514,99 +365,6 @@ namespace ignite return rowPos - posY; } - // old additional settings group code for 1 column window - /* - int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) - { - enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also change it to the same - - int labelPosX = posX + INTERVAL; - - int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL; - int editPosX = labelPosX + LABEL_WIDTH + INTERVAL; - - int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; - - int rowPos = posY + 2 * INTERVAL; - - const char* val = config.GetApplicationName().c_str(); - - appNameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, - ROW_HEIGHT, "Application Name:", ChildId::APP_NAME_LABEL); - appNameEdit = CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT, val, ChildId::APP_NAME_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - - std::string tmp = common::LexicalCast< std::string >(config.GetLoginTimeoutSeconds()); - val = tmp.c_str(); - loginTimeoutSecLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, - ROW_HEIGHT, "Login Timeout (s):", ChildId::LOGIN_TIMEOUT_SEC_LABEL); - - loginTimeoutSecEdit = CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT, val, ChildId::LOGIN_TIMEOUT_SEC_EDIT, ES_NUMBER); - - rowPos += INTERVAL + ROW_HEIGHT; - - // useful draft code for changing read preference into a mode (check JDBC page for available options) - // const char* val = sslModeStr.c_str(); - - // sslModeLabel = CreateLabel(labelPosX, rowPos, - // LABEL_WIDTH, ROW_HEIGHT, - // "SSL Mode:", ChildId::SSL_MODE_LABEL); - // sslModeComboBox = CreateComboBox(editPosX, rowPos, - // editSizeX, ROW_HEIGHT, - // "", ChildId::SSL_MODE_COMBO_BOX); - - // sslModeComboBox->AddString("disable"); - // sslModeComboBox->AddString("require"); - - // sslModeComboBox->SetSelection(sslMode); // set default - // value to require -AL- - - // rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight - // I believe - - val = config.GetReadPreference().c_str(); - - readPreferenceLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Read preference:", ChildId::READ_PREFERENCE_LABEL); - readPreferenceEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, - ChildId::READ_PREFERENCE_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - - val = config.GetReplicaSet().c_str(); - - replicaSetLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Replica Set:", ChildId::REPLICA_SET_LABEL); - replicaSetEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, - ChildId::REPLICA_SET_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - - retryReadsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Retry Reads", ChildId::RETRY_READS_CHECK_BOX, config.IsRetryReads()); - - rowPos += INTERVAL + ROW_HEIGHT; - - tmp = common::LexicalCast(config.GetDefaultFetchSize()); - val = tmp.c_str(); - defaultFetchSizeLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, - ROW_HEIGHT, "Fetch size:", ChildId::DEFAULT_FETCH_SIZE_LABEL); - - defaultFetchSizeEdit = CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT, val, ChildId::DEFAULT_FETCH_SIZE_EDIT, ES_NUMBER); - - rowPos += INTERVAL + ROW_HEIGHT; - - additionalSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, - "Additional settings", ChildId::ADDITIONAL_SETTINGS_GROUP_BOX); - - return rowPos - posY; - } - */ - int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) { enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also @@ -858,7 +616,6 @@ namespace ignite void DsnConfigurationWindow::RetrieveParameters(config::Configuration& cfg) const { RetrieveConnectionParameters(cfg); - //RetrieveAuthParameters(cfg); RetrieveSshParameters(cfg); RetrieveTlsParameters(cfg); RetrieveAdditionalParameters(cfg); @@ -867,10 +624,7 @@ namespace ignite void DsnConfigurationWindow::RetrieveConnectionParameters(config::Configuration& cfg) const { std::string dsnStr; - //std::string addressStr; std::string schemaStr; - //std::string versionStr; - std::string hostnameStr; std::string portStr; std::string databaseStr; @@ -878,11 +632,8 @@ namespace ignite std::string passwordStr; nameEdit->GetText(dsnStr); - //addressEdit->GetText(addressStr); schemaEdit->GetText(schemaStr); - //protocolVersionComboBox->GetText(versionStr); - //common::StripSurroundingWhitespaces(addressStr); common::StripSurroundingWhitespaces(dsnStr); // Stripping of whitespaces off the schema skipped intentionally @@ -899,9 +650,7 @@ namespace ignite LOG_MSG("Retrieving arguments:"); LOG_MSG("DSN: " << dsnStr); - //LOG_MSG("Address: " << addressStr); LOG_MSG("Schema: " << schemaStr); - //LOG_MSG("Protocol version: " << versionStr); // username and password intentionally not logged for security reasons @@ -910,62 +659,20 @@ namespace ignite diagnostic::DiagnosticRecordStorage diag; - std::vector addresses; - - //config::ParseAddress(addressStr, addresses, &diag); - if (diag.GetStatusRecordsNumber() > 0) { throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, diag.GetStatusRecord(1).GetMessageText().c_str()); } - //ProtocolVersion version = ProtocolVersion::FromString(versionStr); - - /*if (!version.IsSupported()) - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Protocol version is not supported.");*/ - cfg.SetDsn(dsnStr); - //cfg.SetAddresses(addresses); cfg.SetDatabase(schemaStr); - //cfg.SetProtocolVersion(version); - - cfg.SetTcpPort(port); - cfg.SetHostname(hostnameStr); - cfg.SetDatabase(databaseStr); - cfg.SetUser(userStr); - cfg.SetPassword(passwordStr); - } - - // comment out because no longer needed - /* - void DsnConfigurationWindow::RetrieveAuthParameters(config::Configuration& cfg) const - { - std::string hostnameStr; - std::string portStr; - std::string databaseStr; - std::string userStr; - std::string passwordStr; - - hostnameEdit->GetText(hostnameStr); - portEdit->GetText(portStr); - databaseEdit->GetText(databaseStr); - userEdit->GetText(userStr); - passwordEdit->GetText(passwordStr); - - int16_t port = - common::LexicalCast(portStr); - - if (port <= 0) - port = config.GetTcpPort(); - cfg.SetTcpPort(port); cfg.SetHostname(hostnameStr); cfg.SetDatabase(databaseStr); cfg.SetUser(userStr); cfg.SetPassword(passwordStr); } - */ void DsnConfigurationWindow::RetrieveSshParameters(config::Configuration& cfg) const { From e30676cdda00f507394da97c273eedc1bc8c230f Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 14:40:08 -0800 Subject: [PATCH 075/100] [AD-522] remove std::auto_ptr authSettingsGroupBox; --- .../include/ignite/odbc/system/ui/dsn_configuration_window.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index dbca6bd5a..d6ceed592 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -234,9 +234,6 @@ namespace ignite /** TLS settings group box. */ std::auto_ptr tlsSettingsGroupBox; - ///** Authentication settings group box. */ - //std::auto_ptr authSettingsGroupBox; - /** Additional settings group box. */ std::auto_ptr additionalSettingsGroupBox; From de64d8707055d3e8f87f5fa2e6b215448ba2aceb Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 14:43:00 -0800 Subject: [PATCH 076/100] [AD-522] remove address field auto pointer initialization --- .../ignite/odbc/system/ui/dsn_configuration_window.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index d6ceed592..15082df8a 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -243,12 +243,6 @@ namespace ignite /** DSN name edit field. */ std::auto_ptr nameEdit; - /** DSN address edit field label. */ - std::auto_ptr addressLabel; - - /** DSN address edit field. */ - std::auto_ptr addressEdit; - /** DSN schema edit field label. */ std::auto_ptr schemaLabel; From f96413deae3de0af108453412b009fceb5d3c6eb Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 14:43:28 -0800 Subject: [PATCH 077/100] [AD-522] remove address field from config window constructor --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index aa2e950cd..f1d5188d7 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -46,8 +46,6 @@ namespace ignite additionalSettingsGroupBox(), nameLabel(), nameEdit(), - addressLabel(), - addressEdit(), schemaLabel(), schemaEdit(), // internal SSH tunnel vars From 4acad7bc7c9c33c640df98df7990fe8a12abc9c9 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 16:21:53 -0800 Subject: [PATCH 078/100] [AD-522] refactor - remove unneeded commented out code in HasText --- src/odbc/os/win/src/system/ui/window.cpp | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/window.cpp b/src/odbc/os/win/src/system/ui/window.cpp index 097dee836..02d62e2d8 100644 --- a/src/odbc/os/win/src/system/ui/window.cpp +++ b/src/odbc/os/win/src/system/ui/window.cpp @@ -159,19 +159,9 @@ namespace ignite SNDMSG(handle, WM_SETTEXT, 0, reinterpret_cast(text.c_str())); } - bool Window::HasText() const { + bool Window::HasText() const + { return IsEnabled() && GetWindowTextLength(handle) > 0; - //if (!IsEnabled()) { - // return false; - //} - - //int len = GetWindowTextLength(handle); - - //if (len <= 0) { - // return false; - //} - - //return true; } bool Window::IsChecked() const From 7652d8674be8a74e18e5595d128b3d8b5d345d0e Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 16:23:50 -0800 Subject: [PATCH 079/100] [AD-522] refactor - remove white spaces and update comment --- .../ignite/odbc/system/ui/dsn_configuration_window.h | 2 +- .../os/win/src/system/ui/dsn_configuration_window.cpp | 8 +------- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 15082df8a..451badde3 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -297,7 +297,7 @@ namespace ignite /** Login Timeout (seconds) label. */ std::auto_ptr loginTimeoutSecLabel; - /** Nested Read Preference ComboBox **/ + /** Read Preference ComboBox **/ std::auto_ptr readPreferenceComboBox; /** Read preference label. */ diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index f1d5188d7..f132c5617 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -320,7 +320,7 @@ namespace ignite } int DsnConfigurationWindow::CreateTlsSettingsGroup(int posX, int posY, int sizeX) - { // TODO: rename function name from Ssl to TLS after UI works + { enum { LABEL_WIDTH = 100 }; @@ -331,7 +331,6 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; - //int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; // original int checkBoxSize = sizeX - 2 * MARGIN; tlsCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, @@ -481,7 +480,6 @@ namespace ignite return rowPos - posY; } - bool DsnConfigurationWindow::OnMessage(UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) @@ -705,12 +703,10 @@ namespace ignite cfg.SetSshPrivateKeyPassphrase(sshPrivateKeyPassphraseStr); cfg.SetSshStrictHostKeyChecking(sshStrictHostKeyChecking); cfg.SetSshKnownHostsFile(sshKnownHostsFileStr); - } void DsnConfigurationWindow::RetrieveTlsParameters(config::Configuration& cfg) const { - bool tls = tlsCheckBox->IsChecked(); bool tlsAllowInvalidHostnames = tlsAllowInvalidHostnamesCheckBox->IsChecked(); std::string tlsCaStr; @@ -729,7 +725,6 @@ namespace ignite void DsnConfigurationWindow::RetrieveAdditionalParameters(config::Configuration& cfg) const { - std::string readPreferenceStr; std::string appNameStr; std::string replicaSetStr; @@ -777,7 +772,6 @@ namespace ignite cfg.SetLoginTimeoutSeconds(loginTimeoutSec); cfg.SetReplicaSet(replicaSetStr); cfg.SetDefaultFetchSize(fetchSize); - } } } From 3e01d10eaf2413acfdb3f7685b49f9dff5c92346 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 16:59:10 -0800 Subject: [PATCH 080/100] [AD-522] debug scan_method.h * SpaceToUnderscore is called in scan_method.cpp to make reads better * added guards to scan_method.h --- src/odbc/include/ignite/odbc/scan_method.h | 8 ++++++-- .../os/win/src/system/ui/dsn_configuration_window.cpp | 1 + src/odbc/src/scan_method.cpp | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/odbc/include/ignite/odbc/scan_method.h b/src/odbc/include/ignite/odbc/scan_method.h index 1feb2f9ca..e5230f1ce 100644 --- a/src/odbc/include/ignite/odbc/scan_method.h +++ b/src/odbc/include/ignite/odbc/scan_method.h @@ -15,6 +15,9 @@ * limitations under the License. */ +#ifndef _IGNITE_ODBC_SCAN_METHOD +#define _IGNITE_ODBC_SCAN_METHOD + #include namespace ignite @@ -24,7 +27,7 @@ namespace ignite /** Scan method enum. */ struct ScanMethod { - enum class Type + enum Type { RANDOM, @@ -56,4 +59,5 @@ namespace ignite }; } -} +} // namespace ignite +#endif //_IGNITE_ODBC_SCAN_METHOD \ No newline at end of file diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index f132c5617..b9719c9f7 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -20,6 +20,7 @@ #include "ignite/odbc/log.h" #include "ignite/odbc/read_preference.h" +#include "ignite/odbc/scan_method.h" #include "ignite/odbc/system/ui/dsn_configuration_window.h" #include "ignite/odbc/config/config_tools.h" diff --git a/src/odbc/src/scan_method.cpp b/src/odbc/src/scan_method.cpp index 06400dd9a..ef253fa5f 100644 --- a/src/odbc/src/scan_method.cpp +++ b/src/odbc/src/scan_method.cpp @@ -29,6 +29,8 @@ namespace ignite common::StripSurroundingWhitespaces(lowerVal); + common::SpaceToUnderscore(lowerVal); + if (lowerVal == "random") return ScanMethod::Type::RANDOM; From fa54ad398de475b91769e6a170221ff980c3218a Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 17:02:47 -0800 Subject: [PATCH 081/100] [AD-522] implement Schema group settings box * fixed bug in dsn_config.cpp to save scanLimit correctly --- .../odbc/system/ui/dsn_configuration_window.h | 46 +++++- .../system/ui/dsn_configuration_window.cpp | 147 ++++++++++++++++-- src/odbc/src/dsn_config.cpp | 2 +- 3 files changed, 180 insertions(+), 15 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 451badde3..787e34a1b 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -44,11 +44,10 @@ namespace ignite CONNECTION_SETTINGS_GROUP_BOX = 100, SSH_SETTINGS_GROUP_BOX, TLS_SETTINGS_GROUP_BOX, + SCHEMA_SETTINGS_GROUP_BOX, ADDITIONAL_SETTINGS_GROUP_BOX, NAME_EDIT, NAME_LABEL, - SCHEMA_EDIT, - SCHEMA_LABEL, SSH_ENABLE_CHECK_BOX, SSH_USER_EDIT, SSH_USER_LABEL, @@ -72,6 +71,13 @@ namespace ignite RETRY_READS_CHECK_BOX, DEFAULT_FETCH_SIZE_EDIT, DEFAULT_FETCH_SIZE_LABEL, + SCAN_METHOD_COMBO_BOX, + SCAN_METHOD_LABEL, + SCAN_LIMIT_EDIT, + SCAN_LIMIT_LABEL, + SCHEMA_EDIT, + SCHEMA_LABEL, + REFRESH_SCHEMA_CHECK_BOX, TLS_CHECK_BOX, TLS_ALLOW_INVALID_HOSTNAMES_CHECK_BOX, TLS_CA_FILE_EDIT, @@ -171,6 +177,14 @@ namespace ignite */ void RetrieveTlsParameters(config::Configuration& cfg) const; + /** + * Retrieves current values from the schema generation UI group and + * stores them to the specified configuration. + * + * @param cfg Configuration. + */ + void RetrieveSchemaParameters(config::Configuration& cfg) const; + /** * Retrieves current values from the additional UI group and * stores them to the specified configuration. @@ -209,6 +223,16 @@ namespace ignite */ int CreateTlsSettingsGroup(int posX, int posY, int sizeX); + /** + * Create schema generation settings group box. + * + * @param posX X position. + * @param posY Y position. + * @param sizeX Width. + * @return Size by Y. + */ + int CreateSchemaSettingsGroup(int posX, int posY, int sizeX); + /** * Create additional settings group box. * @@ -234,6 +258,9 @@ namespace ignite /** TLS settings group box. */ std::auto_ptr tlsSettingsGroupBox; + /** Schema generation and discovery settings group box. */ + std::auto_ptr< Window > schemaSettingsGroupBox; + /** Additional settings group box. */ std::auto_ptr additionalSettingsGroupBox; @@ -243,12 +270,27 @@ namespace ignite /** DSN name edit field. */ std::auto_ptr nameEdit; + /** Scan method ComboBox **/ + std::auto_ptr scanMethodComboBox; + + /** Scan method label. */ + std::auto_ptr scanMethodLabel; + + /** Scan limit field label. */ + std::auto_ptr scanLimitLabel; + + /** Scan limit field. */ + std::auto_ptr scanLimitEdit; + /** DSN schema edit field label. */ std::auto_ptr schemaLabel; /** DSN schema edit field. */ std::auto_ptr schemaEdit; + /** Refresh DSN schema checkBox. */ + std::auto_ptr refreshSchemaCheckBox; + /** SSH enable checkBox. */ std::auto_ptr sshEnableCheckBox; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index b9719c9f7..bfbb1ecbc 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -47,8 +47,13 @@ namespace ignite additionalSettingsGroupBox(), nameLabel(), nameEdit(), + scanMethodLabel(), + scanMethodComboBox(), + scanLimitLabel(), + scanLimitEdit(), schemaLabel(), schemaEdit(), + refreshSchemaCheckBox(), // internal SSH tunnel vars sshEnableCheckBox(), sshUserLabel(), @@ -137,6 +142,7 @@ namespace ignite groupPosYLeft += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); //groupPosYLeft += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); groupPosYLeft += INTERVAL + CreateTlsSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); + groupPosYLeft += INTERVAL + CreateSchemaSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); // create right column group settings groupPosYRight += INTERVAL + CreateSshSettingsGroup(posXRight, groupPosYRight, groupSizeY); groupPosYRight += INTERVAL + CreateAdditionalSettingsGroup(posXRight, groupPosYRight, groupSizeY); @@ -225,13 +231,6 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - val = config.GetDatabase().c_str(); - schemaLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Schema Name:", ChildId::SCHEMA_LABEL); - schemaEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SCHEMA_EDIT); - - rowPos += INTERVAL + ROW_HEIGHT; - connectionSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, "Connection Settings", ChildId::CONNECTION_SETTINGS_GROUP_BOX); @@ -363,6 +362,77 @@ namespace ignite return rowPos - posY; } + int DsnConfigurationWindow::CreateSchemaSettingsGroup(int posX, int posY, int sizeX) + { + + enum { LABEL_WIDTH = 100 }; + + int labelPosX = posX + INTERVAL; + + int editSizeX = sizeX - LABEL_WIDTH - 3 * INTERVAL; + int editPosX = labelPosX + LABEL_WIDTH + INTERVAL; + + int rowPos = posY + 2 * INTERVAL; + + int checkBoxSize = sizeX - 2 * MARGIN; + + ScanMethod::Type scanMethod = config.GetScanMethod(); + + scanMethodLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Scan Method:", ChildId::SCAN_METHOD_LABEL); + scanMethodComboBox = CreateComboBox( + editPosX, rowPos, editSizeX, ROW_HEIGHT, + "", ChildId::SCAN_METHOD_COMBO_BOX); + + scanMethodComboBox->AddString("Random"); + scanMethodComboBox->AddString("ID Forward"); + scanMethodComboBox->AddString("ID Reverse"); + scanMethodComboBox->AddString("All"); + + scanMethodComboBox->SetSelection(scanMethod); // set default + + rowPos += INTERVAL + ROW_HEIGHT; + + std::string tmp = common::LexicalCast(config.GetScanLimit()); + const char* val = tmp.c_str(); + scanLimitLabel = CreateLabel( + labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Scan Limit:", ChildId::SCAN_LIMIT_LABEL); + scanLimitEdit = CreateEdit( + editPosX, rowPos, editSizeX, ROW_HEIGHT, + val, ChildId::SCAN_LIMIT_EDIT, ES_NUMBER); + + rowPos += INTERVAL + ROW_HEIGHT; + + val = config.GetDatabase().c_str(); + schemaLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, + "Schema Name:", ChildId::SCHEMA_LABEL); + schemaEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SCHEMA_EDIT); + + rowPos += INTERVAL + ROW_HEIGHT; + + refreshSchemaCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, + "Refresh Schema", ChildId::REFRESH_SCHEMA_CHECK_BOX, config.IsRefreshSchema()); + + rowPos += INTERVAL + ROW_HEIGHT; + + schemaSettingsGroupBox = CreateGroupBox(posX, posY, sizeX, rowPos - posY, + "Schema Generation Settings", ChildId::SCHEMA_SETTINGS_GROUP_BOX); + + std::string scanMethodStr; + scanMethodComboBox->GetText(scanMethodStr); + if (ScanMethod::FromString(scanMethodStr, + ScanMethod::UNKNOWN) + == ScanMethod::ALL) { + scanLimitEdit->SetEnabled(false); + } else { + scanLimitEdit->SetEnabled(true); + } + + return rowPos - posY; + } + int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) { enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also @@ -582,6 +652,29 @@ namespace ignite break; } + case ChildId::SCAN_METHOD_COMBO_BOX: + { + std::string scanMethodStr; + scanMethodComboBox->GetText(scanMethodStr); + if (ScanMethod::FromString( + scanMethodStr, ScanMethod::UNKNOWN) + == ScanMethod::ALL) + { + scanLimitEdit->SetEnabled(false); + } + else + { + scanLimitEdit->SetEnabled(true); + } + break; + } + + case ChildId::REFRESH_SCHEMA_CHECK_BOX: + { + refreshSchemaCheckBox->SetChecked(!refreshSchemaCheckBox->IsChecked()); + break; + } + case ChildId::RETRY_READS_CHECK_BOX: { retryReadsCheckBox->SetChecked(!retryReadsCheckBox->IsChecked()); @@ -615,13 +708,13 @@ namespace ignite RetrieveConnectionParameters(cfg); RetrieveSshParameters(cfg); RetrieveTlsParameters(cfg); + RetrieveSchemaParameters(cfg); RetrieveAdditionalParameters(cfg); } void DsnConfigurationWindow::RetrieveConnectionParameters(config::Configuration& cfg) const { std::string dsnStr; - std::string schemaStr; std::string hostnameStr; std::string portStr; std::string databaseStr; @@ -629,7 +722,6 @@ namespace ignite std::string passwordStr; nameEdit->GetText(dsnStr); - schemaEdit->GetText(schemaStr); common::StripSurroundingWhitespaces(dsnStr); // Stripping of whitespaces off the schema skipped intentionally @@ -646,8 +738,10 @@ namespace ignite port = config.GetTcpPort(); LOG_MSG("Retrieving arguments:"); - LOG_MSG("DSN: " << dsnStr); - LOG_MSG("Schema: " << schemaStr); + LOG_MSG("DSN: " << dsnStr); + LOG_MSG("Hostname: " << hostnameStr); + LOG_MSG("Port: " << portStr); + LOG_MSG("Database: " << databaseStr); // username and password intentionally not logged for security reasons @@ -663,7 +757,6 @@ namespace ignite } cfg.SetDsn(dsnStr); - cfg.SetDatabase(schemaStr); cfg.SetTcpPort(port); cfg.SetHostname(hostnameStr); cfg.SetDatabase(databaseStr); @@ -721,7 +814,37 @@ namespace ignite cfg.SetTls(tls); cfg.SetTlsAllowInvalidHostnames(tlsAllowInvalidHostnames); cfg.SetTlsCaFile(tlsCaStr); + } + + void DsnConfigurationWindow::RetrieveSchemaParameters(config::Configuration& cfg) const + { + std::string scanMethodStr; + std::string scanLimitStr; + std::string schemaStr; + bool refreshSchema = refreshSchemaCheckBox->IsChecked(); + scanMethodComboBox->GetText(scanMethodStr); + scanLimitEdit->GetText(scanLimitStr); + schemaEdit->GetText(schemaStr); + + int32_t scanLimit = + common::LexicalCast(scanLimitStr); + + if (scanLimit <= 0) + scanLimit = config.GetScanLimit(); + + LOG_MSG("Scan method: " << scanMethodStr); + LOG_MSG("Scan limit " << scanLimit); + LOG_MSG("Schema: " << schemaStr); + LOG_MSG("Refresh schema: " << (refreshSchema ? "true" : "false")); + + ScanMethod::Type scanMethod = + ScanMethod::FromString(scanMethodStr, ScanMethod::UNKNOWN); + + cfg.SetScanMethod(scanMethod); + cfg.SetSchemaName(schemaStr); + cfg.SetScanLimit(scanLimit); + cfg.SetRefreshSchema(refreshSchema); } void DsnConfigurationWindow::RetrieveAdditionalParameters(config::Configuration& cfg) const diff --git a/src/odbc/src/dsn_config.cpp b/src/odbc/src/dsn_config.cpp index da7c8cabe..6d1d4006a 100644 --- a/src/odbc/src/dsn_config.cpp +++ b/src/odbc/src/dsn_config.cpp @@ -219,7 +219,7 @@ namespace ignite if (scanLimit.IsSet() && !config.IsScanLimitSet() && scanLimit.GetValue() > 0) - config.SetDefaultFetchSize(scanLimit.GetValue()); + config.SetScanLimit(scanLimit.GetValue()); SettableValue schemaName = ReadDsnString(dsn, ConnectionStringParser::Key::schemaName); From bc752a3fc76f0ab70f4a70acabe496c350eec6f3 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 25 Jan 2022 17:05:09 -0800 Subject: [PATCH 082/100] [AD-522] update readPreference default value to unknown * removed unneeded commented out code * removed unnecessary code to get string value on readPreference --- .../system/ui/dsn_configuration_window.cpp | 28 ++----------------- 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index bfbb1ecbc..86eed8a7d 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -454,30 +454,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - // useful draft code for changing read preference into a - // mode (check JDBC page for available options) - // const char* val = sslModeStr.c_str(); - - // sslModeLabel = CreateLabel(labelPosX, rowPos, - // LABEL_WIDTH, ROW_HEIGHT, - // "SSL Mode:", ChildId::SSL_MODE_LABEL); - // sslModeComboBox = CreateComboBox(editPosX, rowPos, - // editSizeX, ROW_HEIGHT, - // "", ChildId::SSL_MODE_COMBO_BOX); - - // sslModeComboBox->AddString("disable"); - // sslModeComboBox->AddString("require"); - - // sslModeComboBox->SetSelection(sslMode); // set default - // value to require -AL- - - // rowPos += INTERVAL + ROW_HEIGHT; // used to add row hight - // I believe - ReadPreference::Type readPreference = config.GetReadPreference(); - std::string readPreferenceStr = ReadPreference::ToString(readPreference); - - const char* val = readPreferenceStr.c_str(); readPreferenceLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, @@ -496,8 +473,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - - val = config.GetApplicationName().c_str(); + const char* val = config.GetApplicationName().c_str(); appNameLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "Application Name:", ChildId::APP_NAME_LABEL); @@ -888,7 +864,7 @@ namespace ignite LOG_MSG("Fetch size: " << fetchSize); ReadPreference::Type readPreference = ReadPreference::FromString( - readPreferenceStr, ReadPreference::Type::PRIMARY); + readPreferenceStr, ReadPreference::Type::UNKNOWN); cfg.SetReadPreference(readPreference); cfg.SetRetryReads(retryReads); From c7ed03134c82862ea9a3058d7fd93ec0026bdacd Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 26 Jan 2022 09:39:42 -0800 Subject: [PATCH 083/100] [AD-522] refactor - remove unnecessary comments --- .../win/src/system/ui/dsn_configuration_window.cpp | 9 ++++----- src/odbc/src/config/configuration.cpp | 14 +++++++------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 86eed8a7d..4121d66c3 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -33,7 +33,7 @@ namespace ignite namespace system { namespace ui - { // -AL- the constructor. No-op means no operation I think? + { DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config): CustomWindow(parent, "IgniteConfigureDsn", "Configure Amazon DocumentDB DSN Latest"), //width(360), // original width:360. @@ -42,7 +42,7 @@ namespace ignite //width(360), //height(800), connectionSettingsGroupBox(), - tlsSettingsGroupBox(), // has a create... function defined + tlsSettingsGroupBox(), tlsCheckBox(), additionalSettingsGroupBox(), nameLabel(), @@ -126,7 +126,7 @@ namespace ignite throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, buf.str().c_str()); } } - // the function that actually creates the UI -AL- + void DsnConfigurationWindow::OnCreate() { int groupPosYLeft = MARGIN; @@ -239,7 +239,7 @@ namespace ignite int DsnConfigurationWindow::CreateSshSettingsGroup(int posX, int posY, int sizeX) { - enum { LABEL_WIDTH = 120 }; // -AL- copied from above function + enum { LABEL_WIDTH = 120 }; int labelPosX = posX + INTERVAL; @@ -248,7 +248,6 @@ namespace ignite int rowPos = posY + 2 * INTERVAL; - //int checkBoxSize = (sizeX - 3 * INTERVAL) / 2; // original int checkBoxSize = sizeX - 2 * MARGIN; sshEnableCheckBox = CreateCheckBox( diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 314e67af1..1d025d4e6 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -32,18 +32,18 @@ namespace ignite { // Connection Settings const std::string Configuration::DefaultValue::dsn = "DocumentDB DSN"; - const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB ODBC Driver"; // -AL- add (= need to add to UI) + const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB ODBC Driver"; // driver does not need to be added in config window since it is chosen at the Data Source Administrator - const std::string Configuration::DefaultValue::database = ""; // -AL- add - const std::string Configuration::DefaultValue::hostname = ""; // -AL- add - const uint16_t Configuration::DefaultValue::port = 27017; // -AL- add + const std::string Configuration::DefaultValue::database = ""; + const std::string Configuration::DefaultValue::hostname = ""; + const uint16_t Configuration::DefaultValue::port = 27017; const std::string Configuration::DefaultValue::user = ""; const std::string Configuration::DefaultValue::password = ""; - // SSL/TLS options. Use checkboxes for boolean variables // need to add to UI - const bool Configuration::DefaultValue::tls = true; // changed instead of SSL mode; tls is TLS Encryption + // SSL/TLS options. Use checkboxes for boolean variables + const bool Configuration::DefaultValue::tls = true; const bool Configuration::DefaultValue::tlsAllowInvalidHostnames = false; // needs to be set to true for SSH; TLS Allow Invalid Hostnames - const std::string Configuration::DefaultValue::tlsCaFile = ""; //renamed from SSL CA file + const std::string Configuration::DefaultValue::tlsCaFile = ""; // Schema Generation and Discovery options const ScanMethod::Type Configuration::DefaultValue::scanMethod = ScanMethod::Type::RANDOM; From 0aa20527606ccc11a7a99d6bd6f8d249fa8d1f61 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 26 Jan 2022 09:40:38 -0800 Subject: [PATCH 084/100] [AD-522] adjust window size and additional settings group label size * additional settings group label size is now the same as other settings group in the same column --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 4121d66c3..b3a35c843 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -37,10 +37,10 @@ namespace ignite DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config): CustomWindow(parent, "IgniteConfigureDsn", "Configure Amazon DocumentDB DSN Latest"), //width(360), // original width:360. - height(600), // original height:600 + //height(600), // original height:600 width(730), // double the original width //width(360), - //height(800), + height(515), connectionSettingsGroupBox(), tlsSettingsGroupBox(), tlsCheckBox(), @@ -434,7 +434,8 @@ namespace ignite int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) { - enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also + enum { LABEL_WIDTH = 120 }; // same as SSH settings + //enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also // change it to the same int labelPosX = posX + INTERVAL; From df0cad5490612c695ca28cc8ee44c73dbb1b68bd Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 26 Jan 2022 10:35:07 -0800 Subject: [PATCH 085/100] Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window" This reverts commit 8d609dac52d3e3fc0442f2e8ec8526ec3eb2d6ab, reversing changes made to 0aa20527606ccc11a7a99d6bd6f8d249fa8d1f61. --- .github/workflows/checks.yml | 1 + .github/workflows/mac-build.yml | 26 +- .github/workflows/mac-debug-build.yml | 1 - .github/workflows/win-build.yml | 79 +- README.md | 10 +- build_mac_debug64.sh | 21 - build_mac_release64.sh | 26 +- scripts/build_windows.ps1 | 15 - scripts/register_driver_macos.sh | 27 - .../include/ignite/common/big_integer.h | 2 +- src/common/include/ignite/common/decimal.h | 6 +- src/odbc-test/CMakeLists.txt | 43 +- src/odbc-test/config/ssh_config | 2 - src/odbc-test/include/odbc_test_suite.h | 12 +- src/odbc-test/include/test_utils.h | 47 +- src/odbc-test/src/connection_test.cpp | 86 +- src/odbc-test/src/odbc_test_suite.cpp | 27 +- src/odbc-test/src/test_utils.cpp | 95 +- src/odbc/CMakeLists.txt | 35 +- .../ignite/odbc/app/application_data_buffer.h | 2 +- .../include/ignite/odbc/common/big_integer.h | 526 -------- src/odbc/include/ignite/odbc/common/bits.h | 221 ---- .../include/ignite/odbc/common/concurrent.h | 605 --------- src/odbc/include/ignite/odbc/common/decimal.h | 530 -------- .../ignite/odbc/common/default_allocator.h | 92 -- .../ignite/odbc/common/dynamic_size_array.h | 418 ------- .../include/ignite/odbc/common/expected.h | 303 ----- .../ignite/odbc/common/fixed_size_array.h | 262 ---- .../ignite/odbc/common/platform_utils.h | 126 -- src/odbc/include/ignite/odbc/common/utils.h | 664 ---------- src/odbc/include/ignite/odbc/connection.h | 31 +- src/odbc/include/ignite/odbc/ignite_error.h | 316 ----- src/odbc/include/ignite/odbc/jni/java.h | 641 ---------- src/odbc/include/ignite/odbc/jni/utils.h | 193 --- src/odbc/include/ignite/odbc/log.h | 6 +- .../include/ignite/odbc/meta/column_meta.h | 2 +- .../ignite/odbc/meta/primary_key_meta.h | 2 +- src/odbc/include/ignite/odbc/odbc_error.h | 6 +- src/odbc/include/ignite/odbc/utility.h | 8 +- src/odbc/install/install_amd64.cmd | 3 +- .../linux/include/ignite/odbc/common/common.h | 56 - .../ignite/odbc/common/concurrent_os.h | 701 ----------- .../os/linux/src/common/concurrent_os.cpp | 211 ---- .../os/linux/src/common/platform_utils.cpp | 143 --- .../win/include/ignite/odbc/common/common.h | 46 - .../ignite/odbc/common/concurrent_os.h | 610 --------- src/odbc/os/win/src/common/concurrent_os.cpp | 208 ---- src/odbc/os/win/src/common/platform_utils.cpp | 140 --- src/odbc/os/win/src/system/ui/window.cpp | 8 +- src/odbc/src/app/application_data_buffer.cpp | 2 +- src/odbc/src/common/big_integer.cpp | 866 ------------- src/odbc/src/common/bits.cpp | 236 ---- src/odbc/src/common/concurrent.cpp | 108 -- src/odbc/src/common/decimal.cpp | 278 ----- src/odbc/src/common/utils.cpp | 219 ---- src/odbc/src/connection.cpp | 387 +++--- src/odbc/src/ignite_error.cpp | 227 ---- src/odbc/src/jni/java.cpp | 1102 ----------------- src/odbc/src/jni/os/linux/utils.cpp | 432 ------- src/odbc/src/jni/os/win/utils.cpp | 459 ------- src/odbc/src/log.cpp | 2 +- src/odbc/src/protocol_version.cpp | 2 +- src/odbc/src/ssl_mode.cpp | 2 +- src/odbc/src/utility.cpp | 10 +- 64 files changed, 475 insertions(+), 11498 deletions(-) delete mode 100644 scripts/register_driver_macos.sh delete mode 100644 src/odbc-test/config/ssh_config delete mode 100644 src/odbc/include/ignite/odbc/common/big_integer.h delete mode 100644 src/odbc/include/ignite/odbc/common/bits.h delete mode 100644 src/odbc/include/ignite/odbc/common/concurrent.h delete mode 100644 src/odbc/include/ignite/odbc/common/decimal.h delete mode 100644 src/odbc/include/ignite/odbc/common/default_allocator.h delete mode 100644 src/odbc/include/ignite/odbc/common/dynamic_size_array.h delete mode 100644 src/odbc/include/ignite/odbc/common/expected.h delete mode 100644 src/odbc/include/ignite/odbc/common/fixed_size_array.h delete mode 100644 src/odbc/include/ignite/odbc/common/platform_utils.h delete mode 100644 src/odbc/include/ignite/odbc/common/utils.h delete mode 100644 src/odbc/include/ignite/odbc/ignite_error.h delete mode 100644 src/odbc/include/ignite/odbc/jni/java.h delete mode 100644 src/odbc/include/ignite/odbc/jni/utils.h delete mode 100644 src/odbc/os/linux/include/ignite/odbc/common/common.h delete mode 100644 src/odbc/os/linux/include/ignite/odbc/common/concurrent_os.h delete mode 100644 src/odbc/os/linux/src/common/concurrent_os.cpp delete mode 100644 src/odbc/os/linux/src/common/platform_utils.cpp delete mode 100644 src/odbc/os/win/include/ignite/odbc/common/common.h delete mode 100644 src/odbc/os/win/include/ignite/odbc/common/concurrent_os.h delete mode 100644 src/odbc/os/win/src/common/concurrent_os.cpp delete mode 100644 src/odbc/os/win/src/common/platform_utils.cpp delete mode 100644 src/odbc/src/common/big_integer.cpp delete mode 100644 src/odbc/src/common/bits.cpp delete mode 100644 src/odbc/src/common/concurrent.cpp delete mode 100644 src/odbc/src/common/decimal.cpp delete mode 100644 src/odbc/src/common/utils.cpp delete mode 100644 src/odbc/src/ignite_error.cpp delete mode 100644 src/odbc/src/jni/java.cpp delete mode 100644 src/odbc/src/jni/os/linux/utils.cpp delete mode 100644 src/odbc/src/jni/os/win/utils.cpp diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index ac7484567..d3fec3b10 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -11,3 +11,4 @@ jobs: - uses: ZedThree/clang-tidy-review@v0.7.0 id: review continue-on-error: true + diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml index 29368f323..870a2b257 100644 --- a/.github/workflows/mac-build.yml +++ b/.github/workflows/mac-build.yml @@ -12,19 +12,9 @@ on: env: CI_OUTPUT_PATH: "ci-output" - ODBC_LIB_PATH: "${{github.workspace}}/build/odbc/lib" - ODBC_BIN_PATH: "${{github.workspace}}/build/odbc/bin" - ODBC_BUILD_PATH: "${{github.workspace}}/build/odbc/build" - DOCUMENTDB_HOME: "${{github.workspace}}/build/odbc/bin" - DOC_DB_KEYPAIR: ${{secrets.DOC_DB_KEYPAIR}} - DOC_DB_USER_NAME: ${{secrets.DOC_DB_USER_NAME}} - DOC_DB_PASSWORD: ${{secrets.DOC_DB_PASSWORD}} - DOC_DB_USER: ${{secrets.DOC_DB_USER}} - DOC_DB_HOST: ${{secrets.DOC_DB_HOST}} - DOC_DB_LOCAL_PORT: 27019 - DOC_DB_REMOTE_PORT: 27017 - DOC_DB_PRIV_KEY_FILE: ~/certs/docdb-sshtunnel.pem - JDBC_DRIVER_VERSION: "1.1.0" + ODBC_LIB_PATH: "./build/odbc/lib" + ODBC_BIN_PATH: "./build/odbc/bin" + ODBC_BUILD_PATH: "./build/odbc/build" jobs: build-mac: @@ -47,12 +37,6 @@ jobs: # with: # name: cppcheck-results # path: cppcheck-results.log - - name: Extract key-pair into file - run: | - mkdir ~/certs - echo "${{env.DOC_DB_KEYPAIR}}" > ${{env.DOC_DB_PRIV_KEY_FILE}} - chmod 400 ${{env.DOC_DB_PRIV_KEY_FILE}} - - name: get-dependencies run: | brew install unixodbc @@ -70,10 +54,6 @@ jobs: # sudo cp ./src/Tests/Tests/odbc-mac.ini /Library/ODBC/odbc.ini # sudo cp ./src/Tests/Tests/odbcinst-mac.ini /Library/ODBC/odbcinst.ini # mkdir ${{ github.workspace }}/odbc-logs - - name: register-odbc-driver - run: | - chmod +x scripts/register_driver_macos.sh - ./scripts/register_driver_macos.sh - name: run-tests run: | ./build/odbc/bin/ignite-odbc-tests diff --git a/.github/workflows/mac-debug-build.yml b/.github/workflows/mac-debug-build.yml index 8d41ff8fb..85468cd26 100644 --- a/.github/workflows/mac-debug-build.yml +++ b/.github/workflows/mac-debug-build.yml @@ -8,7 +8,6 @@ env: ODBC_LIB_PATH: "./build/odbc/lib" ODBC_BIN_PATH: "./build/odbc/bin" ODBC_BUILD_PATH: "./build/odbc/build" - DOCUMENTDB_HOME: "./build/odbc/bin" jobs: build-mac: diff --git a/.github/workflows/win-build.yml b/.github/workflows/win-build.yml index b02b4b8f5..ee0506351 100644 --- a/.github/workflows/win-build.yml +++ b/.github/workflows/win-build.yml @@ -16,75 +16,45 @@ env: ODBC_BIN_PATH: "./build/odbc/bin/Release" ODBC_BUILD_PATH: "./build/odbc/cmake" VCPKG_ROOT: "c:/vcpkg" - DOCUMENTDB_HOME: "./build/odbc/bin/Release" - DOC_DB_KEYPAIR: ${{secrets.DOC_DB_KEYPAIR}} - DOC_DB_USER_NAME: ${{secrets.DOC_DB_USER_NAME}} - DOC_DB_PASSWORD: ${{secrets.DOC_DB_PASSWORD}} - DOC_DB_USER: ${{secrets.DOC_DB_USER}} - DOC_DB_HOST: ${{secrets.DOC_DB_HOST}} - RUN_REMOTE_INTEGRATION_TESTS: ${{ github.event.inputs.testWithoutDocumnetDb && 'false' || 'true' }} - DOC_DB_LOCAL_PORT: 27019 - DOC_DB_REMOTE_PORT: 27017 - DOC_DB_PRIV_KEY_FILE: ~/certs/docdb-sshtunnel.pem - JDBC_DRIVER_VERSION: "1.1.0" jobs: build-windows32: runs-on: windows-latest steps: - uses: actions/checkout@v2 - - name: Get Java distribution uses: actions/setup-java@v2 with: distribution: 'temurin' java-version: '17' architecture: x86 - - name: "Update path for Java" run: | echo "${{ env.JAVA_HOME }}\bin\server" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - name: "Update path for WIX Toolset" run: | echo "C:\Program Files (x86)\WiX Toolset v3.11\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - name: Get specific version CMake, v3.20.1 uses: lukka/get-cmake@v3.20.1 - - name: add-msbuild-to-path uses: microsoft/setup-msbuild@v1.0.2 - - - name: Extract key-pair into file - run: | - mkdir -p ~/certs - echo "${{env.DOC_DB_KEYPAIR}}" > ~/certs/docdb-sshtunnel.pem - chmod 400 ~/certs/docdb-sshtunnel.pem - mkdir -p ~/.ssh - copy ./src/odbc-test/config/ssh_config ~/.ssh/config - - #- name: Run SSH tunnel to DocumentDB server - # run: | - # ssh.exe -f -N -i ~/certs/docdb-sshtunnel.pem -L ${{env.DOC_DB_LOCAL_PORT}}:${{secrets.DOC_DB_HOST}}:${{env.DOC_DB_REMOTE_PORT}} ${{secrets.DOC_DB_USER}} - - name: Install dependencies Windows run: vcpkg integrate install; vcpkg install openssl:x86-windows boost-test:x86-windows boost-asio:x86-windows boost-chrono:x86-windows boost-interprocess:x86-windows boost-regex:x86-windows boost-system:x86-windows boost-thread:x86-windows env: VCPKG_ROOT: ${{ env.VCPKG_ROOT }} - - name: configure-and-build-driver run: | .\build_win_release32.ps1 env: OPENSSL_ROOT_DIR: '${{ env.VCPKG_ROOT }}/packages/openssl_x86-windows' - - - name: register-driver - run: | - .\src\odbc\install\install_amd64.cmd ${{env.ODBC_BIN_PATH}}\ignite.odbc.dll ${{env.ODBC_BIN_PATH}}\ignite.odbc.dll - + # - name: import-registry + # run: | + # reg import .\src\Tests\Tests\AWSProfileRegistry_Win32.reg + # reg import .\src\Tests\Tests\IAMRegistry_Win32.reg + # mkdir ${{ github.workspace }}\odbc-logs - name: run-tests run: | - ${{env.ODBC_BIN_PATH}}/ignite-odbc-tests.exe + ${{ env.ODBC_BIN_PATH }}/ignite-odbc-tests.exe # - name: upload-test-report # if: failure() # uses: actions/upload-artifact@v2 @@ -121,58 +91,39 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v2 - - name: Get Java distribution uses: actions/setup-java@v2 with: distribution: 'temurin' java-version: '17' architecture: x64 - - name: "Update path for Java" run: | - echo "${{env.JAVA_HOME}}\bin\server" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - + echo "${{ env.JAVA_HOME }}\bin\server" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - name: "Update path for WIX Toolset" run: | echo "C:\Program Files (x86)\WiX Toolset v3.11\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - name: Get specific version CMake, v3.20.1 uses: lukka/get-cmake@v3.20.1 - - name: add-msbuild-to-path uses: microsoft/setup-msbuild@v1.0.2 - - - name: Extract key-pair into file - run: | - mkdir -p ~/certs - echo "${{env.DOC_DB_KEYPAIR}}" > ~/certs/docdb-sshtunnel.pem - chmod 400 ~/certs/docdb-sshtunnel.pem - mkdir -p ~/.ssh - copy ./src/odbc-test/config/ssh_config ~/.ssh/config - - #- name: Run SSH tunnel to DocumentDB server - # run: | - # ssh.exe -f -N -i ~/certs/docdb-sshtunnel.pem -L ${{env.DOC_DB_LOCAL_PORT}}:${{secrets.DOC_DB_HOST}}:${{env.DOC_DB_REMOTE_PORT}} ${{secrets.DOC_DB_USER}} - - name: Install dependencies Windows run: vcpkg integrate install; vcpkg install openssl:x64-windows boost-test:x64-windows boost-asio:x64-windows boost-chrono:x64-windows boost-interprocess:x64-windows boost-regex:x64-windows boost-system:x64-windows boost-thread:x64-windows env: - VCPKG_ROOT: ${{env.VCPKG_ROOT}} - + VCPKG_ROOT: ${{ env.VCPKG_ROOT }} - name: configure-and-build-driver run: | .\build_win_release64.ps1 env: - OPENSSL_ROOT_DIR: '${{env.VCPKG_ROOT}}/packages/openssl_x64-windows' - - - name: register-driver - run: | - .\src\odbc\install\install_amd64.cmd ${{env.ODBC_BIN_PATH}}\ignite.odbc.dll - + OPENSSL_ROOT_DIR: '${{ env.VCPKG_ROOT }}/packages/openssl_x64-windows' + # - name: import-registry + # run: | + # reg import .\src\Tests\Tests\AWSProfileRegistry.reg + # reg import .\src\Tests\Tests\IAMRegistry.reg + # mkdir ${{ github.workspace }}\odbc-logs - name: run-tests run: | - ${{env.ODBC_BIN_PATH}}/ignite-odbc-tests.exe + ${{ env.ODBC_BIN_PATH }}/ignite-odbc-tests.exe # - name: upload-test-report # if: failure() # uses: actions/upload-artifact@v2 diff --git a/README.md b/README.md index 7db369e0d..cb1308e83 100644 --- a/README.md +++ b/README.md @@ -25,13 +25,7 @@ 1. E.g.: `.\build_win_debug64.ps1` 2. Navigate to the `build\odbc\cmake` folder to use the generated solution file, `Ignite.C++.sln` to work on source code development and testing. -7. Set the environment variable `DOCUMENTDB_HOME`. On a developer's machine, set it to `\build\odbc\bin\Debug`. The - build script run above, downloads it to the `\build\odbc\bin\Debug\libs` folder. -8. Open a **64-bit** command shell or **64-bit** PowerShell window, **as Administrator**, run the - ``` - \src\odbc\src\install\install_amd64.cmd \buildbuild\odbc\cmake\Debug\ignite.odbc.dll - ``` -8. More details in [`src\DEVNOTES.txt`](src/DEVNOTES.txt). +7. More details in `src\DEVNOTES.txt`. ### MacOS @@ -50,7 +44,7 @@ 2. Run one of the build scripts to create an initial compilation. 1. E.g.: `./build_mac_release64.sh` 2. Navigate to the `build/odbc/lib` folder to use the generated files. -3. More details in [`src\DEVNOTES.txt`](src/DEVNOTES.txt). +3. More details in `src\DEVNOTES.txt`. ### Linux diff --git a/build_mac_debug64.sh b/build_mac_debug64.sh index 1118a04b9..98222f20f 100755 --- a/build_mac_debug64.sh +++ b/build_mac_debug64.sh @@ -1,26 +1,5 @@ - -BUILD_DIR=cmake-build64 -BUILD_TYPE=Debug -PROJECT_DIR=$(pwd) -DRIVER_BIN_DIR="$PROJECT_DIR/build/odbc/bin" - mkdir cmake-build64 cd cmake-build64 cmake ../src -DCMAKE_BUILD_TYPE="Debug" -DCODE_COVERAGE="ON" -DBUILD_SHARED_LIBS="OFF" -DWITH_TESTS="ON" -DWITH_CORE="OFF" -DWITH_ODBC="ON" -cd .. - -# Download the DocumentDB JDBC Driver -JDBC_DRIVER_VERSION="${JDBC_DRIVER_VERSION-1.1.0}" -JDBC_DRIVER_FILENAME="documentdb-jdbc-$JDBC_DRIVER_VERSION-all.jar" -JDBC_DRIVER_FULLPATH="$DRIVER_BIN_DIR/libs/$JDBC_DRIVER_FILENAME" -export DOCUMENTDB_HOME="$DRIVER_BIN_DIR" -if [ ! -f "$JDBC_DRIVER_FULLPATH" ]; then - mkdir "$DRIVER_BIN_DIR/libs" - echo "Downloading version $JDBC_DRIVER_VERSION of JDBC driver..." - curl -o "$DRIVER_BIN_DIR/libs/$JDBC_DRIVER_FILENAME" -L https://github.com/aws/amazon-documentdb-jdbc-driver/releases/download/v$JDBC_DRIVER_VERSION/$JDBC_DRIVER_FILENAME - echo "Download complete." -fi - -cd cmake-build64 make ccov-all -j 4 cd .. diff --git a/build_mac_release64.sh b/build_mac_release64.sh index ca42d942e..b2f6bb36f 100755 --- a/build_mac_release64.sh +++ b/build_mac_release64.sh @@ -1,25 +1,5 @@ - -BUILD_DIR=cmake-build64 -BUILD_TYPE=Release -PROJECT_DIR=$(pwd) -DRIVER_BIN_DIR="$PROJECT_DIR/build/odbc/bin" - -set -e -mkdir $BUILD_DIR -cd $BUILD_DIR -cmake ../src -DCMAKE_BUILD_TYPE="$BUILD_TYPE" -DCODE_COVERAGE="OFF" -DBUILD_SHARED_LIBS="OFF" -DWITH_TESTS="ON" -DWITH_CORE="OFF" -DWITH_ODBC="ON" +mkdir cmake-build64 +cd cmake-build64 +cmake ../src -DCMAKE_BUILD_TYPE="Release" -DCODE_COVERAGE="OFF" -DBUILD_SHARED_LIBS="OFF" -DWITH_TESTS="ON" -DWITH_CORE="OFF" -DWITH_ODBC="ON" make -j 4 - -# Download the DocumentDB JDBC Driver -JDBC_DRIVER_VERSION="${JDBC_DRIVER_VERSION-1.1.0}" -JDBC_DRIVER_FILENAME="documentdb-jdbc-$JDBC_DRIVER_VERSION-all.jar" -JDBC_DRIVER_FULLPATH="$DRIVER_BIN_DIR/libs/$JDBC_DRIVER_FILENAME" -export DOCUMENTDB_HOME="$DRIVER_BIN_DIR" -if [ ! -f "$JDBC_DRIVER_FULLPATH" ]; then - mkdir "$DRIVER_BIN_DIR/libs" - echo "Downloading version $JDBC_DRIVER_VERSION of JDBC driver..." - curl -o "$DRIVER_BIN_DIR/libs/$JDBC_DRIVER_FILENAME" -L https://github.com/aws/amazon-documentdb-jdbc-driver/releases/download/v$JDBC_DRIVER_VERSION/$JDBC_DRIVER_FILENAME - echo "Download complete." -fi - cd .. diff --git a/scripts/build_windows.ps1 b/scripts/build_windows.ps1 index 3118170cf..3e3d72988 100644 --- a/scripts/build_windows.ps1 +++ b/scripts/build_windows.ps1 @@ -28,21 +28,6 @@ Set-Location $CURRENT_DIR $DRIVER_BIN_DIR = "$DRIVER_BUILD_DIR\..\bin\$CONFIGURATION" New-Item -Path $DRIVER_BIN_DIR -ItemType Directory -Force | Out-Null -# Download the JDBC driver -$JDBC_DRIVER_VERSION = if ($JDBC_DRIVER_VERSION -eq $null) { "1.1.0" } else { $JDBC_DRIVER_VERSION } -$JDBC_DRIVER_FILENAME = "documentdb-jdbc-$JDBC_DRIVER_VERSION-all.jar" -$JDBC_DRIVER_FULLPATH = "$DRIVER_BIN_DIR\libs\$JDBC_DRIVER_FILENAME" -if (-not (Test-Path -Path $JDBC_DRIVER_FULLPATH -PathType Leaf)) { - New-Item -Path "$DRIVER_BIN_DIR\libs" -ItemType Directory -Force | Out-Null - Write-Output "Downloading version $JDBC_DRIVER_VERSION of JDBC driver..." - $progresspreference = 'silentlyContinue' - Invoke-WebRequest ` - https://github.com/aws/amazon-documentdb-jdbc-driver/releases/download/v$JDBC_DRIVER_VERSION/$JDBC_DRIVER_FILENAME ` - -o $JDBC_DRIVER_FULLPATH - $progressPreference = 'Continue' - Write-Output "Download complete." -} - if (Test-Path -Path $DRIVER_BUILD_DIR\$CONFIGURATION) { Copy-Item $DRIVER_BUILD_DIR\$CONFIGURATION\* $DRIVER_BIN_DIR } diff --git a/scripts/register_driver_macos.sh b/scripts/register_driver_macos.sh deleted file mode 100644 index a5f4f6005..000000000 --- a/scripts/register_driver_macos.sh +++ /dev/null @@ -1,27 +0,0 @@ - -SOURCE="${BASH_SOURCE[0]}" -while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink - DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" - SOURCE="$(readlink "$SOURCE")" - [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located -done - -SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" - -PROJECT_DIR="$SCRIPT_DIR/.." -ODBC_LIB_PATH="$PROJECT_DIR/build/odbc/lib" -ODBC_LIB_FILENAME="$ODBC_LIB_PATH/libignite-odbc.dylib" - -if [ ! -f "$ODBC_LIB_FILENAME" ] -then - echo "Cannot find ODBC library file: $ODBC_LIB_FILENAME" - exit 1 -fi - -echo "[Apache Ignite]" > "$ODBC_LIB_PATH/ignite-odbc-install.ini" -echo "Description=Apache Ignite" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" -echo "Driver=$ODBC_LIB_FILENAME" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" -echo "Setup=$ODBC_LIB_FILENAME" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" -echo "DriverODBCVer=03.00" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" -echo "FileUsage=0" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" -odbcinst -i -d -f "$ODBC_LIB_PATH/ignite-odbc-install.ini" diff --git a/src/common/include/ignite/common/big_integer.h b/src/common/include/ignite/common/big_integer.h index 66aef6db0..699f59e38 100644 --- a/src/common/include/ignite/common/big_integer.h +++ b/src/common/include/ignite/common/big_integer.h @@ -383,7 +383,7 @@ namespace ignite // Reading number itself. while (is && isdigit(c)) { - part = part * 10 + (static_cast(c) - '0'); + part = part * 10 + (c - '0'); ++partDigits; if (part >= 1000000000000000000U) diff --git a/src/common/include/ignite/common/decimal.h b/src/common/include/ignite/common/decimal.h index 39287264e..d45297a29 100644 --- a/src/common/include/ignite/common/decimal.h +++ b/src/common/include/ignite/common/decimal.h @@ -326,7 +326,7 @@ namespace ignite os << '0'; } - os.write(&magStr[magBegin], static_cast(lastNonZero) - magBegin + 1); + os.write(&magStr[magBegin], lastNonZero - magBegin + 1); } else { @@ -340,7 +340,7 @@ namespace ignite { os << '.'; - os.write(&magStr[static_cast< std::basic_string< char, std::char_traits< char >, std::allocator< char > >::size_type >(magBegin) + dotPos], afterDot); + os.write(&magStr[magBegin + dotPos], afterDot); } } @@ -395,7 +395,7 @@ namespace ignite { if (isdigit(c)) { - part = part * 10 + (static_cast(c) - '0'); + part = part * 10 + (c - '0'); ++partDigits; } else if (c == '.' && scale < 0) diff --git a/src/odbc-test/CMakeLists.txt b/src/odbc-test/CMakeLists.txt index 77294465b..f81e1a103 100644 --- a/src/odbc-test/CMakeLists.txt +++ b/src/odbc-test/CMakeLists.txt @@ -29,27 +29,29 @@ find_package(ODBC REQUIRED) include_directories(SYSTEM ${ODBC_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${JNI_INCLUDE_DIRS}) include_directories(include ../odbc/include ../network/include) -if (WIN32) - include_directories(../odbc/os/win/include) -else () - # TODO: Ensure MacOS is portable. https://bitquill.atlassian.net/browse/AD-525 - include_directories(../odbc/os/linux/include) -endif() set(SOURCES - src/connection_test.cpp src/dummy_test.cpp - src/odbc_test_suite.cpp - src/test_utils.cpp - ../odbc/src/common/concurrent.cpp - ../odbc/src/common/utils.cpp - ../odbc/src/jni/java.cpp + src/configuration_test.cpp + ../odbc/src/config/config_tools.cpp + ../odbc/src/config/configuration.cpp + ../odbc/src/config/connection_info.cpp + ../odbc/src/config/connection_string_parser.cpp + ../odbc/src/scan_method.cpp + ../odbc/src/read_preference.cpp + ../odbc/src/diagnostic/diagnostic_record.cpp + ../odbc/src/diagnostic/diagnostic_record_storage.cpp + ../odbc/src/utility.cpp + ../odbc/src/common_types.cpp + ../odbc/src/app/application_data_buffer.cpp + ../odbc/src/log.cpp # TODO uncomment/rework the tests after get some connectivity and functionalities working. # src/teamcity/teamcity_boost.cpp # src/teamcity/teamcity_messages.cpp # src/parser_test.cpp # src/cursor_test.cpp # src/connection_info_test.cpp +# src/connection_test.cpp # src/application_data_buffer_test.cpp # src/column_test.cpp # src/configuration_test.cpp @@ -58,6 +60,7 @@ set(SOURCES # src/utility_test.cpp # src/queries_test.cpp # src/queries_ssl_test.cpp +# src/test_utils.cpp # src/sql_test_suite_fixture.cpp # src/sql_string_functions_test.cpp # src/sql_numeric_functions_test.cpp @@ -73,6 +76,7 @@ set(SOURCES # src/api_robustness_test.cpp # src/attributes_test.cpp # src/errors_test.cpp +# src/odbc_test_suite.cpp # src/types_test.cpp # src/transaction_test.cpp # src/authentication_test.cpp @@ -103,21 +107,6 @@ set(SOURCES # ../odbc/src/nested_tx_mode.cpp ) -if (WIN32) - list(APPEND SOURCES - ../odbc/os/win/src/common/concurrent_os.cpp - ../odbc/os/win/src/common/platform_utils.cpp - ../odbc/src/jni/os/win/utils.cpp - ) -else() - # TODO: Ensure MacOS is portable. https://bitquill.atlassian.net/browse/AD-525 - list(APPEND SOURCES - ../odbc/os/linux/src/common/concurrent_os.cpp - ../odbc/os/linux/src/common/platform_utils.cpp - ../odbc/src/jni/os/linux/utils.cpp - ) -endif() - add_executable(${TARGET} ${SOURCES}) target_link_libraries(${TARGET} ${Boost_LIBRARIES} ignite ${ODBC_LIBRARY}) diff --git a/src/odbc-test/config/ssh_config b/src/odbc-test/config/ssh_config deleted file mode 100644 index 6318ba0a5..000000000 --- a/src/odbc-test/config/ssh_config +++ /dev/null @@ -1,2 +0,0 @@ -Host * - StrictHostKeyChecking no diff --git a/src/odbc-test/include/odbc_test_suite.h b/src/odbc-test/include/odbc_test_suite.h index 6bd00a63a..1bdd3b077 100644 --- a/src/odbc-test/include/odbc_test_suite.h +++ b/src/odbc-test/include/odbc_test_suite.h @@ -75,9 +75,7 @@ namespace ignite * @param connectStr Connection string. * @return SQL State. */ - std::string ExpectConnectionReject( - const std::string& connectStr, - const std::string& expectedError = "08001: Failed to establish connection with the host."); + std::string ExpectConnectionReject(const std::string& connectStr); /** * Disconnect. @@ -89,6 +87,14 @@ namespace ignite */ void CleanUp(); + /** + * Start additional with the specified name and config. + * + * @param cfg Config path. + * @param name Instance name. + */ + static Ignite StartTestNode(const char* cfg, const char* name); + /** * Constructor. */ diff --git a/src/odbc-test/include/test_utils.h b/src/odbc-test/include/test_utils.h index dc7b01a80..f83b23b0c 100644 --- a/src/odbc-test/include/test_utils.h +++ b/src/odbc-test/include/test_utils.h @@ -27,7 +27,7 @@ #include -#include "ignite/odbc/common/utils.h" +#include "ignite/ignition.h" #define ODBC_THROW_ON_ERROR(ret, type, handle) \ if (!SQL_SUCCEEDED(ret)) \ @@ -160,6 +160,51 @@ namespace ignite_test */ std::string GetTestConfigDir(); + /** + * Initialize configuration for a node. + * + * Inits Ignite node configuration from specified config file. + * Config file is searched in path specified by IGNITE_NATIVE_TEST_CPP_CONFIG_PATH + * environmental variable. + * + * @param cfg Ignite config. + * @param cfgFile Ignite node config file name without path. + */ + void InitConfig(ignite::IgniteConfiguration& cfg, const char* cfgFile); + + /** + * Start Ignite node. + * + * Starts new Ignite node from specified config file. + * Config file is searched in path specified by IGNITE_NATIVE_TEST_CPP_CONFIG_PATH + * environmental variable. + * + * @param cfgFile Ignite node config file name without path. + * @return New node. + */ + ignite::Ignite StartNode(const char* cfgFile); + + /** + * Start Ignite node. + * + * Starts new Ignite node with the specified name and from specified config file. + * Config file is searched in path specified by IGNITE_NATIVE_TEST_CPP_CONFIG_PATH + * environmental variable. + * + * @param cfgFile Ignite node config file name without path. + * @param name Node name. + * @return New node. + */ + ignite::Ignite StartNode(const char* cfgFile, const char* name); + + /** + * Start node with the config for the current platform. + * + * @param cfg Basic config path. Changed to platform config if needed. + * @param name Instance name. + */ + ignite::Ignite StartPlatformNode(const char* cfg, const char* name); + /** * Remove all the LFS artifacts. */ diff --git a/src/odbc-test/src/connection_test.cpp b/src/odbc-test/src/connection_test.cpp index 28714a040..6d4ed9a8e 100644 --- a/src/odbc-test/src/connection_test.cpp +++ b/src/odbc-test/src/connection_test.cpp @@ -15,6 +15,7 @@ * limitations under the License. */ +#include "test_server.h" #ifdef _WIN32 # include #endif @@ -26,10 +27,14 @@ #include +#include "ignite/ignite.h" +#include "ignite/ignition.h" + #include "test_utils.h" #include "odbc_test_suite.h" using namespace ignite; +using namespace ignite::common; using namespace ignite_test; using namespace boost::unit_test; @@ -48,6 +53,14 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite // No-op. } + /** + * Start a node. + */ + void StartNode() + { + StartTestNode("queries-test.xml", "NodeMain"); + } + /** * Execute the query and return an error code. */ @@ -83,25 +96,6 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite return code; } - static void SetConnectionString(std::string& connectionString, - const std::string& username = std::string()) { - // NOTE: Assuming we are using internal SSH tunnel - std::string user = common::GetEnv("DOC_DB_USER_NAME", "documentdb"); - std::string password = common::GetEnv("DOC_DB_PASSWORD", ""); - std::string host = common::GetEnv("DOC_DB_HOST", ""); - std::string port = "27017"; - if (!username.empty()) { - user = username; - } - - connectionString = - "DRIVER={Apache Ignite};" - "ADDRESS=" + host + ":" + port + ";" - "SCHEMA=test;" - "USER=" + user + ";" - "PASSWORD=" + password + ";"; - } - /** * Destructor. */ @@ -111,61 +105,45 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite } }; - BOOST_FIXTURE_TEST_SUITE(ConnectionTestSuite, ConnectionTestSuiteFixture) BOOST_AUTO_TEST_CASE(TestConnectionRestore) { - std::string connectionString; - SetConnectionString(connectionString); + StartNode(); - Connect(connectionString); - Disconnect(); + Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache"); - // TODO: [AD-507] Re-enable when querying is supported. - // https://bitquill.atlassian.net/browse/AD-507 + // Check that query was successfully executed. + BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), ""); - //// Check that query was successfully executed. - //BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), ""); + // Stop node. + Ignition::StopAll(true); - //// Query execution should throw ODBC error. - //BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08S01"); + // Query execution should throw ODBC error. + BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08S01"); - //// Reusing a closed connection should not crash an application. - //BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08001"); + // Reusing a closed connection should not crash an application. + BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08001"); - //// Check that connection was restored. - //BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), ""); + StartNode(); + // Check that connection was restored. + BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), ""); } BOOST_AUTO_TEST_CASE(TestConnectionMemoryLeak) { - std::string connectionString; - SetConnectionString(connectionString); - - Connect(connectionString); - - // TODO: [AD-507] Re-enable when querying is supported. - // https://bitquill.atlassian.net/browse/AD-507 - // ExecQuery("Select * from Test"); + TestServer testServer(11100); - Disconnect(); -} + testServer.PushHandshakeResponse(true); + testServer.Start(); -BOOST_AUTO_TEST_CASE(TestConnectionInvalidUser) { - std::string connectionString; - SetConnectionString(connectionString, "invaliduser"); + Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11100;SCHEMA=cache"); - ExpectConnectionReject(connectionString, "08001: Failed to establish connection with the host.\n" - "Invalid username or password or user is not authorized on database 'test'. " - "Please check your settings. Authorization failed for user 'invaliduser' on database 'admin' with mechanism"); - - // TODO: [AD-507] Re-enable when querying is supported. - // https://bitquill.atlassian.net/browse/AD-507 - // ExecQuery("Select * from Test"); + ExecQuery("Select * from Test"); Disconnect(); + Disconnect(); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/odbc-test/src/odbc_test_suite.cpp b/src/odbc-test/src/odbc_test_suite.cpp index 1b2ece743..bef4639e1 100644 --- a/src/odbc-test/src/odbc_test_suite.cpp +++ b/src/odbc-test/src/odbc_test_suite.cpp @@ -24,9 +24,10 @@ #include +#include "ignite/ignition.h" + #include "test_utils.h" #include "odbc_test_suite.h" -#include using namespace ignite_test; using namespace boost::unit_test; @@ -102,9 +103,7 @@ namespace ignite BOOST_REQUIRE(stmt != NULL); } - std::string OdbcTestSuite::ExpectConnectionReject( - const std::string& connectStr, - const std::string& expectedError) + std::string OdbcTestSuite::ExpectConnectionReject(const std::string& connectStr) { Prepare(); @@ -119,9 +118,6 @@ namespace ignite outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE); BOOST_REQUIRE_EQUAL(ret, SQL_ERROR); - BOOST_REQUIRE_EQUAL(expectedError, - GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc) - .substr(0, expectedError.size())); return GetOdbcErrorState(SQL_HANDLE_DBC, dbc); } @@ -158,6 +154,19 @@ namespace ignite } } + Ignite OdbcTestSuite::StartTestNode(const char* cfg, const char* name) + { + std::string config(cfg); + +#ifdef IGNITE_TESTS_32 + // Cutting off the ".xml" part. + config.resize(config.size() - 4); + config += "-32.xml"; +#endif //IGNITE_TESTS_32 + + return StartNode(config.c_str(), name); + } + OdbcTestSuite::OdbcTestSuite(): env(NULL), dbc(NULL), @@ -169,6 +178,8 @@ namespace ignite OdbcTestSuite::~OdbcTestSuite() { CleanUp(); + + Ignition::StopAll(true); } int8_t OdbcTestSuite::GetTestI8Field(int64_t idx) @@ -336,7 +347,7 @@ namespace ignite { BOOST_TEST_CONTEXT("Test index: " << idx) { - odbc::common::FixedSizeArray expected(static_cast(valLen)); + common::FixedSizeArray expected(static_cast(valLen)); GetTestI8ArrayField(idx, expected.GetData(), expected.GetSize()); for (size_t j = 0; j < valLen; ++j) diff --git a/src/odbc-test/src/test_utils.cpp b/src/odbc-test/src/test_utils.cpp index aa4e654b5..bdd32d8af 100644 --- a/src/odbc-test/src/test_utils.cpp +++ b/src/odbc-test/src/test_utils.cpp @@ -19,13 +19,10 @@ #include -#include -#include "ignite/odbc/jni/utils.h" - +#include #include "test_utils.h" - namespace ignite_test { OdbcClientError GetOdbcError(SQLSMALLINT handleType, SQLHANDLE handle) @@ -78,14 +75,14 @@ namespace ignite_test std::string GetTestConfigDir() { - using namespace ignite::odbc; + using namespace ignite; std::string cfgPath = common::GetEnv("IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH"); if (!cfgPath.empty()) return cfgPath; - std::string home = jni::ResolveDocumentDbHome(); + std::string home = jni::ResolveIgniteHome(); if (home.empty()) return home; @@ -102,20 +99,100 @@ namespace ignite_test return path.str(); } + void InitConfig(ignite::IgniteConfiguration& cfg, const char* cfgFile) + { + using namespace ignite; + + assert(cfgFile != 0); + + cfg.jvmOpts.push_back("-Xdebug"); + cfg.jvmOpts.push_back("-Xnoagent"); + cfg.jvmOpts.push_back("-Djava.compiler=NONE"); + cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"); + cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError"); + cfg.jvmOpts.push_back("-Duser.timezone=GMT"); + cfg.jvmOpts.push_back("-DIGNITE_QUIET=false"); + cfg.jvmOpts.push_back("-DIGNITE_CONSOLE_APPENDER=false"); + cfg.jvmOpts.push_back("-DIGNITE_UPDATE_NOTIFIER=false"); + cfg.jvmOpts.push_back("-DIGNITE_LOG_CLASSPATH_CONTENT_ON_STARTUP=false"); + cfg.jvmOpts.push_back("-Duser.language=en"); + // Un-comment to debug SSL + //cfg.jvmOpts.push_back("-Djavax.net.debug=ssl"); + + cfg.igniteHome = jni::ResolveIgniteHome(); + cfg.jvmClassPath = jni::CreateIgniteHomeClasspath(cfg.igniteHome, true); + +#ifdef IGNITE_TESTS_32 + cfg.jvmInitMem = 256; + cfg.jvmMaxMem = 768; +#else + cfg.jvmInitMem = 1024; + cfg.jvmMaxMem = 4096; +#endif + + std::string cfgDir = GetTestConfigDir(); + + if (cfgDir.empty()) + throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Failed to resolve test config directory"); + + std::stringstream path; + + path << cfgDir << common::Fs << cfgFile; + + cfg.springCfgPath = path.str(); + } + + ignite::Ignite StartNode(const char* cfgFile) + { + using namespace ignite; + + IgniteConfiguration cfg; + + InitConfig(cfg, cfgFile); + + return Ignition::Start(cfg); + } + + ignite::Ignite StartNode(const char* cfgFile, const char* name) + { + using namespace ignite; + + assert(name != 0); + + IgniteConfiguration cfg; + + InitConfig(cfg, cfgFile); + + return Ignition::Start(cfg, name); + } + + ignite::Ignite StartPlatformNode(const char* cfg, const char* name) + { + std::string config(cfg); + +#ifdef IGNITE_TESTS_32 + // Cutting off the ".xml" part. + config.resize(config.size() - 4); + config += "-32.xml"; +#endif //IGNITE_TESTS_32 + + return StartNode(config.c_str(), name); + } + std::string AppendPath(const std::string& base, const std::string& toAdd) { std::stringstream stream; - stream << base << ignite::odbc::common::Fs << toAdd; + stream << base << ignite::common::Fs << toAdd; return stream.str(); } void ClearLfs() { - std::string home = ignite::odbc::jni::ResolveDocumentDbHome(); + std::string home = ignite::jni::ResolveIgniteHome(); std::string workDir = AppendPath(home, "work"); - ignite::odbc::common::DeletePath(workDir); + ignite::common::DeletePath(workDir); } } diff --git a/src/odbc/CMakeLists.txt b/src/odbc/CMakeLists.txt index 0c6c45caa..e2021f3e7 100644 --- a/src/odbc/CMakeLists.txt +++ b/src/odbc/CMakeLists.txt @@ -20,23 +20,14 @@ project(ignite-odbc) set(TARGET ${PROJECT_NAME}) find_package(ODBC REQUIRED) -find_package(Java REQUIRED) -find_package(JNI REQUIRED) -include(UseJava) -include_directories(SYSTEM ${ODBC_INCLUDE_DIRS} ${JNI_INCLUDE_DIRS}) +include_directories(SYSTEM ${ODBC_INCLUDE_DIRS}) include_directories(include) set(SOURCES src/app/application_data_buffer.cpp src/app/parameter.cpp src/app/parameter_set.cpp src/common_types.cpp - src/common/big_integer.cpp - src/common/bits.cpp - src/common/concurrent.cpp - src/common/decimal.cpp - src/ignite_error.cpp - src/common/utils.cpp src/config/config_tools.cpp src/config/configuration.cpp src/config/connection_info.cpp @@ -46,7 +37,6 @@ set(SOURCES src/app/application_data_buffer.cpp src/diagnostic/diagnosable_adapter.cpp src/diagnostic/diagnostic_record.cpp src/diagnostic/diagnostic_record_storage.cpp - src/jni/java.cpp src/environment.cpp src/meta/column_meta.cpp src/meta/table_meta.cpp @@ -83,37 +73,20 @@ set(SOURCES src/app/application_data_buffer.cpp src/scan_method.cpp) if (WIN32) - set(OS_INCLUDE os/win/include) + include_directories(os/win/include) - list(APPEND SOURCES - os/win/src/system_dsn.cpp + list(APPEND SOURCES os/win/src/system_dsn.cpp os/win/src/system/ui/custom_window.cpp os/win/src/system/ui/dsn_configuration_window.cpp os/win/src/system/ui/window.cpp - os/win/src/common/concurrent_os.cpp - os/win/src/common/platform_utils.cpp - src/jni/os/win/utils.cpp - module.def - ) -else() - set(OS_INCLUDE os/linux/include) - - list(APPEND SOURCES - os/linux/src/common/concurrent_os.cpp - os/linux/src/common/platform_utils.cpp - src/jni/os/linux/utils.cpp - ) + module.def) endif () -include_directories(${OS_INCLUDE}) - - add_library(${TARGET} SHARED ${SOURCES}) set_target_properties(${TARGET} PROPERTIES VERSION ${CMAKE_PROJECT_VERSION}) target_link_libraries(${TARGET} ${ODBC_LIBRARIES}) -target_link_libraries(${TARGET} ${JNI_LIBRARIES}) if (WIN32) target_link_libraries(${TARGET} ignite-common-objlib ignite-binary-objlib ignite-network-objlib odbccp32 shlwapi) diff --git a/src/odbc/include/ignite/odbc/app/application_data_buffer.h b/src/odbc/include/ignite/odbc/app/application_data_buffer.h index af0231b46..50d324488 100644 --- a/src/odbc/include/ignite/odbc/app/application_data_buffer.h +++ b/src/odbc/include/ignite/odbc/app/application_data_buffer.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "ignite/odbc/common_types.h" #include "ignite/odbc/type_traits.h" diff --git a/src/odbc/include/ignite/odbc/common/big_integer.h b/src/odbc/include/ignite/odbc/common/big_integer.h deleted file mode 100644 index 4e06543a3..000000000 --- a/src/odbc/include/ignite/odbc/common/big_integer.h +++ /dev/null @@ -1,526 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IGNITE_ODBC_COMMON_BIG_INTEGER -#define _IGNITE_ODBC_COMMON_BIG_INTEGER - -#include - -#include -#include - -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Big integer number implementation. - */ - class IGNITE_IMPORT_EXPORT BigInteger - { - friend class Decimal; - public: - // Magnitude array type. - typedef DynamicSizeArray MagArray; - - /** - * Default constructor. Constructs zero-value big integer. - */ - BigInteger(); - - /** - * Constructs big integer with the specified integer value. - * - * @param val Value. - */ - explicit BigInteger(int64_t val); - - /** - * String constructor. - * - * @param val String to assign. - * @param len String length. - */ - BigInteger(const char* val, int32_t len); - - /** - * String constructor. - * - * @param val String to assign. - */ - explicit BigInteger(const std::string& val) : - sign(1), - mag() - { - AssignString(val); - } - - /** - * Copy constructor. - * - * @param other Other value. - */ - BigInteger(const BigInteger& other); - - /** - * Constructs big integer from the byte array. - * - * @param val Bytes of the integer. Byte order is big-endian. - * @param len Array length. - * @param sign Signum. Can be -1 (negative) or 1 (positive or zero). - * @param bigEndian If true then magnitude is in big-endian. Otherwise - * the byte order of the magnitude considered to be little-endian. - */ - BigInteger(const int8_t* val, int32_t len, int32_t sign, bool bigEndian = true); - - /** - * Constructs big integer with the specified magnitude. - * @warning Magnitude is moved. This mean mag left empty after the call. - * - * @param mag Magnitude. Moved. - * @param sign Sign. Can be 1 or -1. - */ - BigInteger(MagArray& mag, int8_t sign); - - /** - * Assigment operator. - * - * @param other Other value. - * @return *this. - */ - BigInteger& operator=(const BigInteger& other); - - /** - * Assign specified value to this BigInteger. - * - * @param val Value to assign. - */ - void Assign(const BigInteger& val); - - /** - * Assign specified value to this BigInteger. - * - * @param val Value to assign. - */ - void AssignInt64(int64_t val); - - /** - * Assign specified value to this Decimal. - * - * @param val String to assign. - */ - void AssignString(const std::string& val) - { - AssignString(val.data(), static_cast(val.size())); - } - - /** - * Assign specified value to this Decimal. - * - * @param val String to assign. - * @param len String length. - */ - void AssignString(const char* val, int32_t len); - - /** - * Assign specified value to this BigInteger. - * - * @param val Value to assign. - */ - void AssignUint64(uint64_t val); - - /** - * Get number sign. Returns -1 if negative and 1 otherwise. - * - * @return Sign of the number. - */ - int8_t GetSign() const; - - /** - * Swap function for the BigInteger type. - * - * @param other Other instance. - */ - void Swap(BigInteger& other); - - /** - * Get magnitude array. - * - * @return magnitude array. - */ - const MagArray& GetMagnitude() const; - - /** - * Get this number length in bits as if it was positive. - * - * @return Number length in bits. - */ - uint32_t GetBitLength() const; - - /** - * Get precision of the BigInteger. - * - * @return Number of the decimal digits in the decimal representation - * of the value. - */ - int32_t GetPrecision() const; - - /** - * Fills specified buffer with data of this BigInteger converted to - * bytes in big-endian byte order. Sign is not considered when this - * operation is performed. - * - * @param buffer Buffer to fill. - */ - void MagnitudeToBytes(common::FixedSizeArray& buffer) const; - - /** - * Mutates this BigInteger so its value becomes exp power of this. - * - * @param exp Exponent. - */ - void Pow(int32_t exp); - - /** - * Muitiply this to another big integer. - * - * @param other Another instance. Can be *this. - * @param res Result placed there. Can be *this. - */ - void Multiply(const BigInteger& other, BigInteger& res) const; - - /** - * Divide this to another big integer. - * - * @param divisor Divisor. Can be *this. - * @param res Result placed there. Can be *this. - */ - void Divide(const BigInteger& divisor, BigInteger& res) const; - - /** - * Divide this to another big integer. - * - * @param divisor Divisor. Can be *this. - * @param res Result placed there. Can be *this. - * @param rem Remainder placed there. Can be *this. - */ - void Divide(const BigInteger& divisor, BigInteger& res, BigInteger& rem) const; - - /** - * Add unsigned integer number to this BigInteger. - * - * @param x Number to add. - */ - void Add(uint64_t x); - - /** - * Compare this instance to another. - * - * @param other Another instance. - * @param ignoreSign If set to true than only magnitudes are compared. - * @return Comparasion result - 0 if equal, 1 if this is greater, -1 if - * this is less. - */ - int32_t Compare(const BigInteger& other, bool ignoreSign = false) const; - - /** - * Convert to int64_t. - * - * @return int64_t value. - */ - int64_t ToInt64() const; - - /** - * Check whether this value is negative. - * - * @return True if this value is negative and false otherwise. - */ - bool IsNegative() const - { - return sign < 0; - } - - /** - * Check whether this value is zero. - * - * @return True if this value is negative and false otherwise. - */ - bool IsZero() const - { - return mag.GetSize() == 0; - } - - /** - * Check whether this value is positive. - * - * @return True if this value is positive and false otherwise. - */ - bool IsPositive() const - { - return sign > 0 && !IsZero(); - } - - /** - * Rverses sign of this value. - */ - void Negate() - { - if (!IsZero()) - sign = -sign; - } - - /** - * Output operator. - * - * @param os Output stream. - * @param val Value to output. - * @return Reference to the first param. - */ - friend std::ostream& operator<<(std::ostream& os, const BigInteger& val) - { - if (val.IsZero()) - return os << '0'; - - if (val.sign < 0) - os << '-'; - - const int32_t maxResultDigits = 19; - BigInteger maxUintTenPower; - BigInteger res; - BigInteger left; - - maxUintTenPower.AssignUint64(10000000000000000000U); - - std::vector vals; - - val.Divide(maxUintTenPower, left, res); - - if (res.sign < 0) - res.sign = -res.sign; - - if (left.sign < 0) - left.sign = -left.sign; - - vals.push_back(static_cast(res.ToInt64())); - - while (!left.IsZero()) - { - left.Divide(maxUintTenPower, left, res); - - vals.push_back(static_cast(res.ToInt64())); - } - - os << vals.back(); - - for (int32_t i = static_cast(vals.size()) - 2; i >= 0; --i) - { - os.fill('0'); - os.width(maxResultDigits); - - os << vals[i]; - } - - return os; - } - - /** - * Input operator. - * - * @param is Input stream. - * @param val Value to input. - * @return Reference to the first param. - */ - friend std::istream& operator>>(std::istream& is, BigInteger& val) - { - std::istream::sentry sentry(is); - - // Return zero if input failed. - val.AssignInt64(0); - - if (!is) - return is; - - // Current value parts. - uint64_t part = 0; - int32_t partDigits = 0; - int32_t sign = 1; - - BigInteger pow; - BigInteger bigPart; - - // Current char. - int c = is.peek(); - - if (!is) - return is; - - // Checking sign. - if (c == '-' || c == '+') - { - if (c == '-') - sign = -1; - - is.ignore(); - c = is.peek(); - } - - // Reading number itself. - while (is && isdigit(c)) - { - part = part * 10 + (static_cast(c) - '0'); - ++partDigits; - - if (part >= 1000000000000000000U) - { - BigInteger::GetPowerOfTen(partDigits, pow); - val.Multiply(pow, val); - - val.Add(part); - - part = 0; - partDigits = 0; - } - - is.ignore(); - c = is.peek(); - } - - // Adding last part of the number. - if (partDigits) - { - BigInteger::GetPowerOfTen(partDigits, pow); - - val.Multiply(pow, val); - - val.Add(part); - } - - if (sign < 0) - val.Negate(); - - return is; - } - - /** - * Get BigInteger which value is the ten of the specified power. - * - * @param pow Tenth power. - * @param res Result is placed here. - */ - static void GetPowerOfTen(int32_t pow, BigInteger& res); - - private: - /** - * Add magnitude array to current. - * - * @param addend Addend. - * @param len Length of the addend. - */ - void Add(const uint32_t* addend, int32_t len); - - /** - * Get n-th integer of the magnitude. - * - * @param n Index. - * @return Value of the n-th int of the magnitude. - */ - uint32_t GetMagInt(int32_t n) const; - - /** - * Divide this to another big integer. - * - * @param divisor Divisor. Can be *this. - * @param res Result placed there. Can be *this. - * @param rem Remainder placed there if requested. Can be *this. - * Can be null if the remainder is not needed. - */ - void Divide(const BigInteger& divisor, BigInteger& res, BigInteger* rem) const; - - /** - * Normalizes current value removing trailing zeroes from the magnitude. - */ - void Normalize(); - - /** The sign of this BigInteger: -1 for negative and 1 for non-negative. */ - int8_t sign; - - /** The magnitude of this BigInteger. Byte order is little-endian. */ - MagArray mag; - }; - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if equal. - */ - IGNITE_IMPORT_EXPORT bool operator==(const BigInteger& val1, const BigInteger& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if not equal. - */ - IGNITE_IMPORT_EXPORT bool operator!=(const BigInteger& val1, const BigInteger& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if less. - */ - IGNITE_IMPORT_EXPORT bool operator<(const BigInteger& val1, const BigInteger& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if less or equal. - */ - IGNITE_IMPORT_EXPORT bool operator<=(const BigInteger& val1, const BigInteger& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if gretter. - */ - IGNITE_IMPORT_EXPORT bool operator>(const BigInteger& val1, const BigInteger& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if gretter or equal. - */ - IGNITE_IMPORT_EXPORT bool operator>=(const BigInteger& val1, const BigInteger& val2); - } - } -} - -#endif //_IGNITE_ODBC_COMMON_BIG_INTEGER diff --git a/src/odbc/include/ignite/odbc/common/bits.h b/src/odbc/include/ignite/odbc/common/bits.h deleted file mode 100644 index d53a78e37..000000000 --- a/src/odbc/include/ignite/odbc/common/bits.h +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _IGNITE_ODBC_COMMON_BITS -#define _IGNITE_ODBC_COMMON_BITS - -#include - -#include -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace bits - { - /** - * Maximum number of digits in uint64_t number. - */ - const int32_t UINT64_MAX_PRECISION = 20; - - /** - * Get number of trailing zero bits in the two's complement binary - * representation of the specified 32-bit int value. - * - * @param i The value whose bits are to be counted. - * @return The number of trailing zero bits in the two's complement - * binary representation of the specified 32-bit int value. - */ - IGNITE_IMPORT_EXPORT int32_t NumberOfTrailingZerosI32(int32_t i); - - /** - * Get number of leading zero bits in the two's complement binary - * representation of the specified 32-bit int value. - * - * @param i The value whose bits are to be counted. - * @return The number of leading zero bits in the two's complement - * binary representation of the specified 32-bit int value. - */ - IGNITE_IMPORT_EXPORT int32_t NumberOfLeadingZerosI32(int32_t i); - - /** - * Get number of leading zero bits in the two's complement binary - * representation of the specified 32-bit int value. - * - * @param i The value whose bits are to be counted. - * @return The number of leading zero bits in the two's complement - * binary representation of the specified 32-bit int value. - */ - IGNITE_IMPORT_EXPORT int32_t NumberOfLeadingZerosU32(uint32_t i); - - /** - * Get number of leading zero bits in the two's complement binary - * representation of the specified 64-bit int value. - * - * @param i The value whose bits are to be counted. - * @return The number of leading zero bits in the two's complement - * binary representation of the specified 64-bit int value. - */ - IGNITE_IMPORT_EXPORT int32_t NumberOfLeadingZerosI64(int64_t i); - - /** - * Get number of leading zero bits in the two's complement binary - * representation of the specified 64-bit int value. - * - * @param i The value whose bits are to be counted. - * @return The number of leading zero bits in the two's complement - * binary representation of the specified 64-bit int value. - */ - IGNITE_IMPORT_EXPORT int32_t NumberOfLeadingZerosU64(uint64_t i); - - /** - * Get the number of one-bits in the two's complement binary - * representation of the specified 32-bit int value. - * - * @param i The value whose bits are to be counted. - * @return The number of one-bits in the two's complement binary - * representation of the specified 32-bit int value. - */ - IGNITE_IMPORT_EXPORT int32_t BitCountI32(int32_t i); - - /** - * Get bit length for the specified signed 32-bit int value. - * - * @param i The value to get bit length for. - * @return The number of significant bits in the two's complement binary - * representation of the specified 32-bit int value. - */ - IGNITE_IMPORT_EXPORT int32_t BitLengthI32(int32_t i); - - /** - * Get bit length for the specified unsigned 32-bit int value. - * - * @param i The value to get bit length for. - * @return The number of significant bits in the two's complement binary - * representation of the specified 32-bit int value. - */ - IGNITE_IMPORT_EXPORT int32_t BitLengthU32(uint32_t i); - - /** - * Calcutale capasity for required size. - * Rounds up to the nearest power of two. - * - * @param size Needed capasity. - * @return Recomended capasity to allocate. - */ - IGNITE_IMPORT_EXPORT int32_t GetCapasityForSize(int32_t size); - - /** - * Get the number of decimal digits of the integer value. - * - * @param x The value. - * @return The number of decimal digits of the integer value. - */ - IGNITE_IMPORT_EXPORT int32_t DigitLength(uint64_t x); - - /** - * Get n-th power of ten. - * - * @param n Power. Should be in range [0, UINT64_MAX_PRECISION] - * @return 10 pow n, if n is in range [0, UINT64_MAX_PRECISION]. - * Otherwise, behaviour is undefined. - */ - IGNITE_IMPORT_EXPORT uint64_t TenPowerU64(int32_t n); - - /** - * Get the signum function of the specified 64-bit integer value. - * The return value is -1 if the specified value is negative; 0 if the - * specified value is zero; and 1 if the specified value is positive. - * - * @param i the value whose signum is to be computed - * @return The signum function of the specified value. - */ - inline int32_t Signum64(int64_t i) - { - return (static_cast(-i) >> 63) | (i >> 63); - } - - /** - * Makes single 64-bit integer number out of two 32-bit numbers. - * - * @param higher Higher bits part. - * @param lower Lower bits part. - * @return New 64-bit integer. - */ - inline uint64_t MakeU64(uint32_t higher, uint32_t lower) - { - return (static_cast(higher) << 32) | lower; - } - - /** - * Makes single 64-bit integer number out of two 32-bit numbers. - * - * @param higher Higher bits part. - * @param lower Lower bits part. - * @return New 64-bit integer. - */ - inline int64_t MakeI64(uint32_t higher, uint32_t lower) - { - return static_cast(MakeU64(higher, lower)); - } - - /** - * Makes single 32-bit integer number out of two 32-bit numbers, - * shifted by specified number of bits. First number x is shifted - * to the left. - * x y - * [........][........] - * ^[........] - * n res - * - * @param x First part. - * @param y Second part. - * @param n Number of bits to shift. - * @return New 32-bit integer. - */ - inline uint32_t MakeU32(uint32_t x, uint32_t y, int32_t n) - { - return (x << n) | (y >> (32 - n)); - } - - /** - * Makes single 32-bit integer number out of two 32-bit numbers, - * shifted by specified number of bits. First number x is shifted - * to the left. - * x y - * [........][........] - * ^[........] - * n res - * - * @param x First part. - * @param y Second part. - * @param n Number of bits to shift. - * @return New 32-bit integer. - */ - inline int32_t MakeI32(uint32_t x, uint32_t y, int32_t n) - { - return static_cast(MakeU32(x, y, n)); - } - } - } - } -} - -#endif //_IGNITE_ODBC_COMMON_BITS diff --git a/src/odbc/include/ignite/odbc/common/concurrent.h b/src/odbc/include/ignite/odbc/common/concurrent.h deleted file mode 100644 index c0615f22a..000000000 --- a/src/odbc/include/ignite/odbc/common/concurrent.h +++ /dev/null @@ -1,605 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IGNITE_ODBC_COMMON_CONCURRENT -#define _IGNITE_ODBC_COMMON_CONCURRENT - -#include -#include - -#include "ignite/odbc/common/concurrent_os.h" - -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace concurrent - { - /** - * Type tag for static pointer cast. - */ - struct StaticTag {}; - - /** - * Default deleter implementation. - * - * @param obj Object to be deleted. - */ - template - IGNITE_IMPORT_EXPORT void SharedPointerDefaultDeleter(T* obj) - { - delete obj; - } - - /** - * Empty deleter implementation. - * - * @param obj Object to be deleted. - */ - template - IGNITE_IMPORT_EXPORT void SharedPointerEmptyDeleter(T*) - { - // No-op. - } - - /** - * Holder of shared pointer data. - */ - class IGNITE_IMPORT_EXPORT SharedPointerImpl - { - public: - typedef void(*DeleterType)(void*); - /** - * Constructor. - * - * @param ptr Raw pointer. - */ - SharedPointerImpl(void* ptr, DeleterType deleter); - - /** - * Get raw pointer. - * - * @return Raw pointer. - */ - void* Pointer(); - - /** - * Get raw pointer. - * - * @return Raw pointer. - */ - const void* Pointer() const; - - /** - * Get raw pointer. - * - * @return Raw pointer. - */ - DeleterType Deleter(); - - /** - * Increment usage counter. - */ - void Increment(); - - /** - * Decrement usage counter. - * - * @return True if counter reached zero. - */ - bool Decrement(); - private: - /** Raw pointer. */ - void* ptr; - - /** Deleter. */ - DeleterType deleter; - - /** Reference count. */ - int32_t refCnt; - - IGNITE_NO_COPY_ASSIGNMENT(SharedPointerImpl); - }; - - /* Forward declaration. */ - template - class IGNITE_IMPORT_EXPORT EnableSharedFromThis; - - /* Forward declaration. */ - template - inline void ImplEnableShared(EnableSharedFromThis* some, SharedPointerImpl* impl); - - // Do nothing if the instance is not derived from EnableSharedFromThis. - inline void ImplEnableShared(const volatile void*, const volatile void*) - { - // No-op. - } - - /** - * Shared pointer. - */ - template - class IGNITE_IMPORT_EXPORT SharedPointer - { - public: - friend class EnableSharedFromThis; - - template - friend class SharedPointer; - - /** - * Constructor. - */ - SharedPointer() : - ptr(0), - impl(0) - { - // No-op. - } - - /** - * Constructor. - * - * @param ptr Raw pointer. - * @param deleter Delete function. - */ - SharedPointer(T* ptr, void(*deleter)(T*) = &SharedPointerDefaultDeleter) : - ptr(ptr), - impl(0) - { - if (ptr) - { - impl = new SharedPointerImpl(ptr, reinterpret_cast(deleter)); - ImplEnableShared(ptr, impl); - } - } - - /** - * Constructor. - * - * @param ptr Raw pointer. - * @param deleter Delete function. - */ - template - SharedPointer(T2* ptr, void(*deleter)(T2*) = &SharedPointerDefaultDeleter) : - ptr(ptr), - impl(0) - { - if (ptr) - { - impl = new SharedPointerImpl(ptr, reinterpret_cast(deleter)); - ImplEnableShared(ptr, impl); - } - } - - /** - * Copy constructor. - * - * @param other Instance to copy. - */ - SharedPointer(const SharedPointer& other) : - ptr(other.ptr), - impl(other.impl) - { - if (impl) - impl->Increment(); - } - - /** - * Copy constructor. - * - * @param other Instance to copy. - */ - template - SharedPointer(const SharedPointer& other) : - ptr(other.ptr), - impl(other.impl) - { - if (impl) - impl->Increment(); - } - - /** - * Static-cast constructor. - * - * @param other Instance to copy. - */ - template - SharedPointer(const SharedPointer& other, StaticTag) : - ptr(static_cast(other.ptr)), - impl(other.impl) - { - if (impl) - impl->Increment(); - } - - /** - * Assignment operator. - * - * @param other Other instance. - */ - SharedPointer& operator=(const SharedPointer& other) - { - if (this != &other) - { - SharedPointer tmp(other); - - Swap(tmp); - } - - return *this; - } - - /** - * Assignment operator. - * - * @param other Other instance. - */ - template - SharedPointer& operator=(const SharedPointer& other) - { - SharedPointer tmp(other); - - Swap(tmp); - - return *this; - } - - /** - * Destructor. - */ - ~SharedPointer() - { - if (impl && impl->Decrement()) - { - void* ptr0 = impl->Pointer(); - - void(*deleter)(void*) = impl->Deleter(); - - deleter(ptr0); - - delete impl; - - ptr = 0; - } - } - - /** - * Get raw pointer. - * - * @return Raw pointer. - */ - T* Get() - { - return ptr; - } - - /** - * Get raw pointer. - * - * @return Raw pointer. - */ - const T* Get() const - { - return ptr; - } - - /** - * Check whether underlying raw pointer is valid. - * - * Invalid instance can be returned if some of the previous - * operations have resulted in a failure. For example invalid - * instance can be returned by not-throwing version of method - * in case of error. Invalid instances also often can be - * created using default constructor. - * - * @return True if valid. - */ - bool IsValid() const - { - return impl != 0; - } - - /** - * Swap pointer content with another instance. - * - * @param other Other instance. - */ - void Swap(SharedPointer& other) - { - if (this != &other) - { - T* ptrTmp = ptr; - SharedPointerImpl* implTmp = impl; - - ptr = other.ptr; - impl = other.impl; - - other.ptr = ptrTmp; - other.impl = implTmp; - } - } - - private: - /* Pointer. */ - T* ptr; - - /** Implementation. */ - SharedPointerImpl* impl; - }; - - /** - * Enables static-cast semantics for SharedPointer. - * - * @param val Value to cast. - */ - template - SharedPointer StaticPointerCast(const SharedPointer& val) - { - return SharedPointer(val, StaticTag()); - } - - /** - * The class provides functionality that allows objects of derived - * classes to create instances of shared_ptr pointing to themselves - * and sharing ownership with existing shared_ptr objects. - */ - template - class IGNITE_IMPORT_EXPORT EnableSharedFromThis - { - public: - /** - * Default constructor. - */ - EnableSharedFromThis() : self(0) - { - // No-op. - } - - /** - * Copy constructor. - */ - EnableSharedFromThis(const EnableSharedFromThis&) : self(0) - { - // No-op. - } - - /** - * Assignment operator. - */ - EnableSharedFromThis& operator=(const EnableSharedFromThis&) - { - return *this; - } - - /** - * Destructor. - */ - virtual ~EnableSharedFromThis() - { - // No-op. - } - - /** - * Create shared pointer for this instance. - * - * Can only be called on already shared object. - * @return New shared pointer instance. - */ - SharedPointer SharedFromThis() - { - assert(self != 0); - - SharedPointer ptr; - - ptr.impl = self; - - self->Increment(); - - return ptr; - } - - private: - template - friend void ImplEnableShared(EnableSharedFromThis*, SharedPointerImpl*); - - /** Shared pointer base. */ - SharedPointerImpl* self; - }; - - // Implementation for instances derived from EnableSharedFromThis. - template - inline void ImplEnableShared(EnableSharedFromThis* some, SharedPointerImpl* impl) - { - if (some) - some->self = impl; - } - - /** - * Lock guard. - */ - template - class LockGuard - { - public: - /** - * Constructor. - * - * @param lock Lockable object. - */ - LockGuard(T& lock) : - lock(&lock) - { - lock.Enter(); - } - - /** - * Destructor. - */ - ~LockGuard() - { - if (lock) - lock->Leave(); - } - - /** - * Releases control over lock without unlocking it. - */ - void Forget() - { - lock = 0; - } - - /** - * Releases control over lock and unlocks it as if it would - * go out of scope. - */ - void Reset() - { - if (lock) - { - lock->Leave(); - - Forget(); - } - } - - private: - T* lock; - }; - - typedef LockGuard CsLockGuard; - - /** - * Shared lock guard. - * Locks guard in shared mode. - */ - template - class SharedLockGuard - { - public: - /** - * Constructor. - * - * @param lock Lockable object. - */ - SharedLockGuard(T& lock) : - lock(&lock) - { - lock.LockShared(); - } - - /** - * Destructor. - */ - ~SharedLockGuard() - { - if (lock) - lock->ReleaseShared(); - } - - /** - * Releases control over lock without unlocking it. - */ - void Forget() - { - lock = 0; - } - - /** - * Releases control over lock and unlocks it as if it would - * go out of scope. - */ - void Reset() - { - if (lock) - { - lock->ReleaseShared(); - - Forget(); - } - } - - private: - T* lock; - }; - - typedef SharedLockGuard RwSharedLockGuard; - - /** - * Exclusive lock guard. - * Locks guard in exclusive mode. - */ - template - class ExclusiveLockGuard - { - public: - /** - * Constructor. - * - * @param lock Lockable object. - */ - ExclusiveLockGuard(T& lock) : - lock(&lock) - { - lock.LockExclusive(); - } - - /** - * Destructor. - */ - ~ExclusiveLockGuard() - { - if (lock) - lock->ReleaseExclusive(); - } - - /** - * Releases control over lock without unlocking it. - */ - void Forget() - { - lock = 0; - } - - /** - * Releases control over lock and unlocks it as if it would - * go out of scope. - */ - void Reset() - { - if (lock) - { - lock->ReleaseExclusive(); - - Forget(); - } - } - - private: - T* lock; - }; - - typedef ExclusiveLockGuard RwExclusiveLockGuard; - } // namespace concurrent - } // namespace common - } // namespace odbc -} // namespace ignite - -#endif //_IGNITE_ODBC_COMMON_CONCURRENT diff --git a/src/odbc/include/ignite/odbc/common/decimal.h b/src/odbc/include/ignite/odbc/common/decimal.h deleted file mode 100644 index 9728fc845..000000000 --- a/src/odbc/include/ignite/odbc/common/decimal.h +++ /dev/null @@ -1,530 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IGNITE_ODBC_COMMON_DECIMAL -#define _IGNITE_ODBC_COMMON_DECIMAL - -#include -#include - -#include -#include - -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Big decimal number implementation. - */ - class IGNITE_IMPORT_EXPORT Decimal - { - public: - /** - * Default constructor. - */ - Decimal(); - - /** - * Constructor. - * - * @param mag Bytes of the magnitude. Should be positive, sign is - * passed using separate argument. - * @param len Magnitude length in bytes. - * @param scale Scale. - * @param sign Sign of the decimal. Should be -1 for negative numbers - * and 1 otherwise. - * @param bigEndian If true then magnitude is in big-endian. Otherwise - * the byte order of the magnitude considered to be little-endian. - */ - Decimal(const int8_t* mag, int32_t len, int32_t scale, int32_t sign, bool bigEndian = true); - - /** - * Copy constructor. - * - * @param other Other instance. - */ - Decimal(const Decimal& other); - - /** - * Integer constructor. - * - * @param val Integer value. - */ - explicit Decimal(int64_t val); - - /** - * Integer constructor with scale. - * - * @param val Integer value. - * @param scale Scale. - */ - Decimal(int64_t val, int32_t scale); - - /** - * BigInteger constructor with scale. - * - * @param val BigInteger value. - * @param scale Scale. - */ - Decimal(const common::BigInteger& val, int32_t scale); - - /** - * String constructor. - * - * @param val String to assign. - * @param len String length. - */ - Decimal(const char* val, int32_t len); - - /** - * String constructor. - * - * @param val String to assign. - */ - explicit Decimal(const std::string& val) : - scale(0), - magnitude(0) - { - AssignString(val); - } - - /** - * Destructor. - */ - ~Decimal(); - - /** - * Copy operator. - * - * @param other Other instance. - * @return This. - */ - Decimal& operator=(const Decimal& other); - - /** - * Convert to double. - */ - operator double() const; - - /** - * Convert to int64_t. - */ - operator int64_t() const; - - /** - * Convert to double. - * - * @return Double value. - */ - double ToDouble() const; - - /** - * Convert to int64_t. - * - * @return int64_t value. - */ - int64_t ToInt64() const; - - /** - * Get scale. - * - * @return Scale. - */ - int32_t GetScale() const; - - /** - * Set scale. - * - * @param scale Scale to set. - * @param res Result is placed here. Can be *this. - */ - void SetScale(int32_t scale, Decimal& res) const; - - /** - * Get precision of the Decimal. - * - * @return Number of the decimal digits in the decimal representation - * of the value. - */ - int32_t GetPrecision() const; - - /** - * Get unscaled value. - * - * @return Unscaled value. - */ - const common::BigInteger& GetUnscaledValue() const; - - /** - * Swap function for the Decimal type. - * - * @param other Other instance. - */ - void Swap(Decimal& second); - - /** - * Get length of the magnitude. - * - * @return Length of the magnitude. - */ - int32_t GetMagnitudeLength() const; - - /** - * Assign specified value to this Decimal. - * - * @param val String to assign. - */ - void AssignString(const std::string& val) - { - AssignString(val.data(), static_cast(val.size())); - } - - /** - * Assign specified value to this Decimal. - * - * @param val String to assign. - * @param len String length. - */ - void AssignString(const char* val, int32_t len); - - /** - * Assign specified value to this Decimal. - * - * @param val Value to assign. - */ - void AssignInt64(int64_t val); - - /** - * Assign specified value to this Decimal. - * - * @param val Value to assign. - */ - void AssignDouble(double val); - - /** - * Assign specified value to this Decimal. - * - * @param val Value to assign. - */ - void AssignUint64(uint64_t val); - - /** - * Compare this instance to another. - * - * @param other Another instance. - * @return Comparasion result - 0 if equal, 1 if this is greater, -1 if - * this is less. - */ - int32_t Compare(const Decimal& other) const; - - /** - * Check whether this value is negative. - * - * @return True if this value is negative and false otherwise. - */ - bool IsNegative() const; - - /** - * Check whether this value is zero. - * - * @return True if this value is negative and false otherwise. - */ - bool IsZero() const; - - /** - * Check whether this value is positive. - * - * @return True if this value is positive and false otherwise. - */ - bool IsPositive() const; - - /** - * Output operator. - * - * @param os Output stream. - * @param val Value to output. - * @return Reference to the first param. - */ - friend std::ostream& operator<<(std::ostream& os, const Decimal& val) - { - const common::BigInteger& unscaled = val.GetUnscaledValue(); - - // Zero magnitude case. Scale does not matter. - if (unscaled.GetMagnitude().IsEmpty()) - return os << '0'; - - // Scale is zero or negative. No decimal point here. - if (val.scale <= 0) - { - os << unscaled; - - // Adding zeroes if needed. - for (int32_t i = 0; i < -val.scale; ++i) - os << '0'; - - return os; - } - - // Getting magnitude as a string. - std::stringstream converter; - - converter << unscaled; - - std::string magStr = converter.str(); - - int32_t magLen = static_cast(magStr.size()); - - int32_t magBegin = 0; - - // If value is negative passing minus sign. - if (magStr[magBegin] == '-') - { - os << magStr[magBegin]; - - ++magBegin; - --magLen; - } - - // Finding last non-zero char. There is no sense in trailing zeroes - // beyond the decimal point. - int32_t lastNonZero = static_cast(magStr.size()) - 1; - - while (lastNonZero >= magBegin && magStr[lastNonZero] == '0') - --lastNonZero; - - // This is expected as we already covered zero number case. - assert(lastNonZero >= magBegin); - - int32_t dotPos = magLen - val.scale; - - if (dotPos <= 0) - { - // Means we need to add leading zeroes. - os << '0' << '.'; - - while (dotPos < 0) - { - ++dotPos; - - os << '0'; - } - - os.write(&magStr[magBegin], static_cast(lastNonZero) - magBegin + 1); - } - else - { - // Decimal point is in the middle of the number. - // Just output everything before the decimal point. - os.write(&magStr[magBegin], dotPos); - - int32_t afterDot = lastNonZero - dotPos - magBegin + 1; - - if (afterDot > 0) - { - os << '.'; - - os.write(&magStr[magBegin + dotPos], afterDot); - } - } - - return os; - } - - /** - * Input operator. - * - * @param is Input stream. - * @param val Value to input. - * @return Reference to the first param. - */ - friend std::istream& operator>>(std::istream& is, Decimal& val) - { - std::istream::sentry sentry(is); - - // Return zero if input failed. - val.AssignInt64(0); - - if (!is) - return is; - - // Current char. - int c = is.peek(); - - // Current value parts. - uint64_t part = 0; - int32_t partDigits = 0; - int32_t scale = -1; - int32_t sign = 1; - - common::BigInteger& mag = val.magnitude; - common::BigInteger pow; - common::BigInteger bigPart; - - if (!is) - return is; - - // Checking sign. - if (c == '-' || c == '+') - { - if (c == '-') - sign = -1; - - is.ignore(); - c = is.peek(); - } - - // Reading number itself. - while (is) - { - if (isdigit(c)) - { - part = part * 10 + (c - '0'); - ++partDigits; - } - else if (c == '.' && scale < 0) - { - // We have found decimal point. Starting counting scale. - scale = 0; - } - else - break; - - is.ignore(); - c = is.peek(); - - if (part >= 1000000000000000000U) - { - common::BigInteger::GetPowerOfTen(partDigits, pow); - mag.Multiply(pow, mag); - - mag.Add(part); - - part = 0; - partDigits = 0; - } - - // Counting scale if the decimal point have been encountered. - if (scale >= 0) - ++scale; - } - - // Adding last part of the number. - if (partDigits) - { - common::BigInteger::GetPowerOfTen(partDigits, pow); - - mag.Multiply(pow, mag); - - mag.Add(part); - } - - // Adjusting scale. - if (scale < 0) - scale = 0; - else - --scale; - - // Reading exponent. - if (c == 'e' || c == 'E') - { - is.ignore(); - - int32_t exp = 0; - is >> exp; - - scale -= exp; - } - - val.scale = scale; - - if (sign < 0) - mag.Negate(); - - return is; - } - - private: - /** Scale. */ - int32_t scale; - - /** Magnitude. */ - common::BigInteger magnitude; - }; - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if equal. - */ - IGNITE_IMPORT_EXPORT bool operator==(const Decimal& val1, const Decimal& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if not equal. - */ - IGNITE_IMPORT_EXPORT bool operator!=(const Decimal& val1, const Decimal& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if less. - */ - IGNITE_IMPORT_EXPORT bool operator<(const Decimal& val1, const Decimal& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if less or equal. - */ - IGNITE_IMPORT_EXPORT bool operator<=(const Decimal& val1, const Decimal& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if gretter. - */ - IGNITE_IMPORT_EXPORT bool operator>(const Decimal& val1, const Decimal& val2); - - /** - * Comparison operator. - * - * @param val1 First value. - * @param val2 Second value. - * @return True if gretter or equal. - */ - IGNITE_IMPORT_EXPORT bool operator>=(const Decimal& val1, const Decimal& val2); - } - } -} - -#endif //_IGNITE_ODBC_COMMON_DECIMAL diff --git a/src/odbc/include/ignite/odbc/common/default_allocator.h b/src/odbc/include/ignite/odbc/common/default_allocator.h deleted file mode 100644 index ddf7bdda7..000000000 --- a/src/odbc/include/ignite/odbc/common/default_allocator.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _IGNITE_ODBC_COMMON_DEFAULT_ALLOCATOR -#define _IGNITE_ODBC_COMMON_DEFAULT_ALLOCATOR - -#include -#include - -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Allocator. Manages objects construction and destruction as well - * as a memory allocation. - */ - template - class IGNITE_IMPORT_EXPORT DefaultAllocator - { - public: - typedef T ValueType; - typedef T* PointerType; - typedef T& ReferenceType; - typedef const T* ConstPointerType; - typedef const T& ConstReferenceType; - typedef int32_t SizeType; - typedef int32_t DifferenceType; - - template struct Rebind - { - typedef DefaultAllocator other; - }; - - /** - * Default constructor. - */ - DefaultAllocator() - { - // No-op. - } - - /** - * Destructor. - */ - ~DefaultAllocator() - { - // No-op. - } - - PointerType Allocate(SizeType len, void* = 0) - { - return static_cast(::operator new(len * sizeof(ValueType))); - } - - void Deallocate(PointerType ptr, SizeType) - { - ::operator delete(ptr); - } - - void Construct(PointerType p, ConstReferenceType val) - { - new (p) ValueType(val); - } - - void Destruct(PointerType p) - { - p->~ValueType(); - } - }; - } - } -} - -#endif // _IGNITE_ODBC_COMMON_DEFAULT_ALLOCATOR diff --git a/src/odbc/include/ignite/odbc/common/dynamic_size_array.h b/src/odbc/include/ignite/odbc/common/dynamic_size_array.h deleted file mode 100644 index 109ccc51c..000000000 --- a/src/odbc/include/ignite/odbc/common/dynamic_size_array.h +++ /dev/null @@ -1,418 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _IGNITE_ODBC_COMMON_DYNAMIC_SIZE_ARRAY -#define _IGNITE_ODBC_COMMON_DYNAMIC_SIZE_ARRAY - -#include -#include -#include - -#include - -#include -#include -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Dynamic size array is safe container abstraction with a dynamic size. - * This is the analogue of the standard vector. It is needed to be used - * in exported classes as we can't export standard library classes. - */ - template > - class IGNITE_IMPORT_EXPORT DynamicSizeArray - { - public: - typedef T ValueType; - typedef A AllocatorType; - typedef typename AllocatorType::SizeType SizeType; - typedef typename AllocatorType::PointerType PointerType; - typedef typename AllocatorType::ConstPointerType ConstPointerType; - typedef typename AllocatorType::ReferenceType ReferenceType; - typedef typename AllocatorType::ConstReferenceType ConstReferenceType; - - /** - * Default constructor. - * - * Constructs zero-size and zero-capasity array. - */ - DynamicSizeArray(const AllocatorType& allocator = AllocatorType()) : - alloc(allocator), - size(0), - capasity(0), - data(0) - { - // No-op. - } - - /** - * Constructor. - * Constructs empty array with the specified capacity. - * - * @param len Array length. - * @param alloc Allocator. - */ - DynamicSizeArray(SizeType len, const AllocatorType& allocator = AllocatorType()) : - alloc(allocator), - size(0), - capasity(bits::GetCapasityForSize(len)), - data(alloc.Allocate(capasity)) - { - // No-op. - } - - /** - * Raw array constructor. - * - * @param arr Raw array. - * @param len Array length in elements. - */ - DynamicSizeArray(ConstPointerType arr, SizeType len, - const AllocatorType& allocator = AllocatorType()) : - alloc(allocator), - size(0), - capasity(0), - data(0) - { - Assign(arr, len); - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - DynamicSizeArray(const DynamicSizeArray& other) : - alloc(), - size(0), - capasity(0), - data(0) - { - Assign(other); - } - - /** - * Destructor. - */ - ~DynamicSizeArray() - { - for (PointerType it = data; it != data + size; ++it) - alloc.Destruct(it); - - alloc.Deallocate(data, capasity); - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return Reference to this instance. - */ - DynamicSizeArray& operator=(const DynamicSizeArray& other) - { - Assign(other); - - return *this; - } - - /** - * Assign new value to the array. - * - * @param other Another array instance. - */ - void Assign(const DynamicSizeArray& other) - { - if (this != &other) - { - alloc = other.alloc; - - Assign(other.GetData(), other.GetSize()); - } - } - - /** - * Assign new value to the array. - * - * @param src Raw array. - * @param len Array length in elements. - */ - void Assign(ConstPointerType src, SizeType len) - { - for (PointerType it = data; it != data + size; ++it) - alloc.Destruct(it); - - if (capasity < len) - { - alloc.Deallocate(data, capasity); - - capasity = bits::GetCapasityForSize(len); - data = alloc.Allocate(capasity); - } - - size = len; - - for (SizeType i = 0; i < size; ++i) - alloc.Construct(data + i, src[i]); - } - - /** - * Append several values to the array. - * - * @param src Raw array. - * @param len Array length in elements. - */ - void Append(ConstPointerType src, SizeType len) - { - Reserve(size + len); - - for (SizeType i = 0; i < len; ++i) - alloc.Construct(data + size + i, src[i]); - - size += len; - } - - /** - * Swap contents of the array with another instance. - * - * @param other Instance to swap with. - */ - void Swap(DynamicSizeArray& other) - { - if (this != &other) - { - std::swap(alloc, other.alloc); - std::swap(size, other.size); - std::swap(capasity, other.capasity); - std::swap(data, other.data); - } - } - - /** - * Get data pointer. - * - * @return Data pointer. - */ - PointerType GetData() - { - return data; - } - - /** - * Get data pointer. - * - * @return Data pointer. - */ - ConstPointerType GetData() const - { - return data; - } - - /** - * Get array size. - * - * @return Array size. - */ - SizeType GetSize() const - { - return size; - } - - /** - * Get capasity. - * - * @return Array capasity. - */ - SizeType GetCapasity() const - { - return capasity; - } - - /** - * Element access operator. - * - * @param idx Element index. - * @return Element reference. - */ - ReferenceType operator[](SizeType idx) - { - assert(idx < size); - - return data[idx]; - } - - /** - * Element access operator. - * - * @param idx Element index. - * @return Element reference. - */ - ConstReferenceType operator[](SizeType idx) const - { - assert(idx < size); - - return data[idx]; - } - - /** - * Check if the array is empty. - * - * @return True if the array is empty. - */ - bool IsEmpty() const - { - return size == 0; - } - - /** - * Clears the array. - */ - void Clear() - { - for (PointerType it = data; it != data + size; ++it) - alloc.Destruct(it); - - size = 0; - } - - /** - * Reserves not less than specified elements number so array is not - * going to grow on append. - * - * @param newCapacity Desired capasity. - */ - void Reserve(SizeType newCapacity) - { - if (capasity < newCapacity) - { - DynamicSizeArray tmp(newCapacity); - - tmp.Assign(*this); - - Swap(tmp); - } - } - - /** - * Resizes array. Destructs elements if the specified size is less - * than the array's size. Default-constructs elements if the - * specified size is more than the array's size. - * - * @param newSize Desired size. - */ - void Resize(SizeType newSize) - { - if (capasity < newSize) - Reserve(newSize); - - if (newSize > size) - { - for (PointerType it = data + size; it < data + newSize; ++it) - alloc.Construct(it, ValueType()); - } - else - { - for (PointerType it = data + newSize; it < data + size; ++it) - alloc.Destruct(it); - } - - size = newSize; - } - - /** - * Get last element. - * - * @return Last element reference. - */ - const ValueType& Back() const - { - assert(size > 0); - - return data[size - 1]; - } - - /** - * Get last element. - * - * @return Last element reference. - */ - ValueType& Back() - { - assert(size > 0); - - return data[size - 1]; - } - - /** - * Get first element. - * - * @return First element reference. - */ - const ValueType& Front() const - { - assert(size > 0); - - return data[0]; - } - - /** - * Get first element. - * - * @return First element reference. - */ - ValueType& Front() - { - assert(size > 0); - - return data[0]; - } - - /** - * Pushes new value to the back of the array, effectively increasing - * array size by one. - * - * @param val Value to push. - */ - void PushBack(ConstReferenceType val) - { - Resize(size + 1); - - Back() = val; - } - - private: - /** Allocator */ - AllocatorType alloc; - - /** Array size. */ - SizeType size; - - /** Array capasity. */ - SizeType capasity; - - /** Data. */ - PointerType data; - }; - } - } -} - -#endif // _IGNITE_ODBC_COMMON_DYNAMIC_SIZE_ARRAY diff --git a/src/odbc/include/ignite/odbc/common/expected.h b/src/odbc/include/ignite/odbc/common/expected.h deleted file mode 100644 index 800fda179..000000000 --- a/src/odbc/include/ignite/odbc/common/expected.h +++ /dev/null @@ -1,303 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IGNITE_ODBC_COMMON_EXPECTED -#define _IGNITE_ODBC_COMMON_EXPECTED - -#include - -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Helper class to construct Expected class with error value. - */ - template - struct Unexpected - { - /** Value type. */ - typedef E ValueType; - - /** - * Constructor. - * - * @param e Error value reference. - */ - Unexpected(const ValueType& e) : err(e) - { - // No-op; - } - - /** Error. */ - const ValueType& err; - }; - - /** - * Operation result wrapper. - * - * Represents a type, which can accept one of two value types - expected - * result or error. - * - * @tparam R Result type. - * @tparam E Error type. - * @tparam AR Allocator type used for the Result type. - * @tparam AE Allocator type used for the Error type. - */ - template< - typename R, - typename E, - typename AR = std::allocator, - typename AE = std::allocator > - class Expected - { - public: - /** Result type. */ - typedef R ResultType; - - /** Error type. */ - typedef E ErrorType; - - /** Allocator type used for the ResultType. */ - typedef AR ResultAllocatorType; - - /** Allocator type used for the ErrorType. */ - typedef AE ErrorAllocatorType; - - /** - * Constructor. - * - * Creates new instance, containing expected value. - * @param res Result. - */ - Expected(const ResultType& res) : - ok(true) - { - ResultAllocatorType ral; - - ral.construct(AsResult(), res); - } - - /** - * Constructor. - * - * Creates new instance, containing error. - * @param err Result. - */ - explicit Expected(Unexpected err) : - ok(false) - { - ErrorAllocatorType ral; - - ral.construct(AsError(), err.err); - } - - /** - * Copy constructor. - * - * @param other Other. - */ - Expected(const Expected& other) : - ok(other.ok) - { - if (ok) - { - ResultAllocatorType ral; - - ral.construct(AsResult(), *other.AsResult()); - } - else - { - ErrorAllocatorType ral; - - ral.construct(AsError(), *other.AsError()); - } - } - - /** - * Destructor. - */ - ~Expected() - { - if (ok) - { - ResultAllocatorType ral; - - ral.destroy(AsResult()); - } - else - { - ErrorAllocatorType ral; - - ral.destroy(AsError()); - } - } - - /** - * Check if the value is OK. - * - * @return @c false if the value is an error and @c true otherwise. - */ - bool IsOk() const - { - return ok; - } - - /** - * Get result. Constant accesser. - * - * @return Result if it was set before. - * @throw ErrorType if there is no result. - */ - const ResultType& GetResult() const - { - if (!ok) - throw *AsError(); - - return *AsResult(); - } - - /** - * Get result. - * - * @return Result if it was set before. - * @throw ErrorType if there is no result. - */ - ResultType& GetResult() - { - if (!ok) - throw *AsError(); - - return *AsResult(); - } - - /** - * Get result. Constant accesser. - * - * @return Result if it was set before. - * @throw ErrorType if there is no result. - */ - const ResultType& operator*() const - { - return GetResult(); - } - - /** - * Get result. - * - * @return Result if it was set before. - * @throw ErrorType if there is no result. - */ - ResultType& operator*() - { - return GetResult(); - } - - /** - * Get result. Constant accesser. - * - * @return Result if it was set before. - * @throw ErrorType if there is no result. - */ - const ResultType& operator->() const - { - return GetResult(); - } - - /** - * Get result. - * - * @return Result if it was set before. - * @throw ErrorType if there is no result. - */ - ResultType& operator->() - { - return GetResult(); - } - - /** - * Get error. - * - * @return Error if it was set before. If there is no error, default - * constructed error is returned (which is expected to be "No error"). - */ - const ErrorType& GetError() const - { - static ErrorType noError; - - if (ok) - return noError; - - return *AsError(); - } - - private: - /** - * Get storage as an result. - * - * @return Storage pointer as an result pointer. - */ - ResultType* AsResult() - { - return reinterpret_cast(&storage); - } - - /** - * Get storage as an result. - * - * @return Storage pointer as an result pointer. - */ - const ResultType* AsResult() const - { - return reinterpret_cast(&storage); - } - - /** - * Get storage as an error. - * - * @return Storage pointer as an error pointer. - */ - ErrorType* AsError() - { - return reinterpret_cast(&storage); - } - - /** - * Get storage as an error. - * - * @return Storage pointer as an error pointer. - */ - const ErrorType* AsError() const - { - return reinterpret_cast(&storage); - } - - /** Storage. */ - int8_t storage[sizeof(typename Bigger::type)]; - - /** Result flag. Set to @c false if the value is an error. */ - bool ok; - }; - } - } -} - -#endif // _IGNITE_ODBC_COMMON_EXPECTED \ No newline at end of file diff --git a/src/odbc/include/ignite/odbc/common/fixed_size_array.h b/src/odbc/include/ignite/odbc/common/fixed_size_array.h deleted file mode 100644 index a18a60a84..000000000 --- a/src/odbc/include/ignite/odbc/common/fixed_size_array.h +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _IGNITE_ODBC_COMMON_FIXED_SIZE_ARRAY -#define _IGNITE_ODBC_COMMON_FIXED_SIZE_ARRAY - -#include -#include -#include - -#include -#include - -#include - -namespace ignite -{ - namespace odbc { - namespace common { - /** - * Fixed size array is safe array abstraction with a fixed size. - * The size can be set during runtime though once array is created - * its size can not be changed without resetting arrays content. - */ - template < typename T > - class IGNITE_IMPORT_EXPORT FixedSizeArray { - public: - typedef int32_t SizeType; - - /** - * Default constructor. - * - * Constructs zero-size array. - */ - FixedSizeArray() : size(0), data(0) { - // No-op. - } - - /** - * Constructor. - * Constructs default-initialized array of the specified length. - * Array zeroed if T is a POD type. - * - * @param len Array length. - */ - FixedSizeArray(SizeType len) - : size(len), - // Brackets are here for a purpose - this way allocated - // array is zeroed if T is POD type. - data(new T[size]()) { - // No-op. - } - - /** - * Copy constructor. - * - * @param other Other instance. - */ - FixedSizeArray(const FixedSizeArray< T >& other) - : size(other.size), data(new T[size]) { - Assign(other); - } - - /** - * Raw array constructor. - * - * @param arr Raw array. - * @param len Array length in elements. - */ - FixedSizeArray(const T* arr, SizeType len) : size(len), data(new T[size]) { - Assign(arr, len); - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return Reference to this instance. - */ - FixedSizeArray< T >& operator=(const FixedSizeArray< T >& other) { - Assign(other); - - return *this; - } - - /** - * Assign new value to the array. - * - * @param other Another array instance. - */ - void Assign(const FixedSizeArray< T >& other) { - if (this != &other) - Assign(other.GetData(), other.GetSize()); - } - - /** - * Assign new value to the array. - * - * @param src Raw array. - * @param len Array length in elements. - */ - void Assign(const T* src, SizeType len) { - // In case we would not need to clean anything - // its okay to call delete[] on 0. - T* toClean = 0; - - if (len != size) { - // Do not clean just yet in case the part of the - // array is being assigned to the array. - toClean = data; - - size = len; - data = new T[size]; - } - - for (SizeType i = 0; i < len; ++i) - data[i] = src[i]; - - delete[] toClean; - } - - /** - * Swap contents of the array with another instance. - * - * @param other Instance to swap with. - */ - void Swap(FixedSizeArray< T >& other) { - if (this != &other) { - std::swap(size, other.size); - std::swap(data, other.data); - } - } - - /** - * Destructor. - */ - ~FixedSizeArray() { - // Not a bug. Delete works just fine on null pointers. - delete[] data; - } - - /** - * Get data pointer. - * - * @return Data pointer. - */ - T* GetData() { - return data; - } - - /** - * Get data pointer. - * - * @return Data pointer. - */ - const T* GetData() const { - return data; - } - - /** - * Get array size. - * - * @return Array size. - */ - SizeType GetSize() const { - return size; - } - - /** - * Copy part of the array and place in another array. - * Contents of the provided array gets swapped with the copy of the - * specified array part. - * - * @param pos Start position. - * @param n Number of elements to copy. - * @param result Instance of an array where result should be placed. - */ - void CopyPart(SizeType pos, SizeType n, FixedSizeArray< T >& result) const { - assert(pos < size); - assert(pos + n <= size); - - result.Assign(data + pos, n); - } - - /** - * Element access operator. - * - * @param idx Element index. - * @return Element reference. - */ - T& operator[](SizeType idx) { - assert(idx < size); - - return data[idx]; - } - - /** - * Element access operator. - * - * @param idx Element index. - * @return Element reference. - */ - const T& operator[](SizeType idx) const { - assert(idx < size); - - return data[idx]; - } - - /** - * Check if the array is empty. - * - * @return True if the array is empty. - */ - bool IsEmpty() const { - return size == 0; - } - - /** - * Resets the state of the array setting it to the specified size - * and erasing its content. - * - * @param newSize New array size. - */ - void Reset(SizeType newSize = 0) { - if (size != newSize) { - delete[] data; - - if (newSize) - data = new T[newSize](); - else - data = 0; - - size = newSize; - } else - std::fill(data, data + size, T()); - } - - private: - /** Array size. */ - SizeType size; - - /** Target array. */ - T* data; - }; - } // namespace common - } // namespace odbc -} - -#endif // _IGNITE_ODBC_COMMON_FIXED_SIZE_ARRAY diff --git a/src/odbc/include/ignite/odbc/common/platform_utils.h b/src/odbc/include/ignite/odbc/common/platform_utils.h deleted file mode 100644 index 5e430de2c..000000000 --- a/src/odbc/include/ignite/odbc/common/platform_utils.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _IGNITE_ODBC_COMMON_PLATFORM_UTILS -#define _IGNITE_ODBC_COMMON_PLATFORM_UTILS - -#include -#include "ignite/odbc/common/common.h" - -namespace ignite -{ - namespace odbc - { - namespace common - { - typedef std::basic_ostream > StdCharOutStream; - - /** - * Convert struct tm to time_t (UTC). - * - * @param time Standard C type struct tm value. - * @return Standard C type time_t value. - */ - IGNITE_IMPORT_EXPORT time_t IgniteTimeGm(const tm& time); - - /** - * Convert struct tm to time_t (Local time). - * - * @param time Standard C type struct tm value. - * @return Standard C type time_t value. - */ - IGNITE_IMPORT_EXPORT time_t IgniteTimeLocal(const tm& time); - - /** - * Convert time_t to struct tm (UTC). - * - * @param in Standard C type time_t value. - * @param out Standard C type struct tm value. - * @return True on success. - */ - IGNITE_IMPORT_EXPORT bool IgniteGmTime(time_t in, tm& out); - - /** - * Convert time_t to struct tm (Local time). - * - * @param in Standard C type time_t value. - * @param out Standard C type struct tm value. - * @return True on success. - */ - IGNITE_IMPORT_EXPORT bool IgniteLocalTime(time_t in, tm& out); - - /** - * Read system environment variable taking thread-safety in count. - * - * @param name Environment variable name. - * @return Environment variable value if found and empty string otherwise. - */ - IGNITE_IMPORT_EXPORT std::string GetEnv(const std::string& name); - - /** - * Read system environment variable taking thread-safety in count. - * - * @param name Environment variable name. - * @param dflt Default value to return on fail. - * @return Environment variable value if found and @c dflt otherwise. - */ - IGNITE_IMPORT_EXPORT std::string GetEnv(const std::string& name, const std::string& dflt); - - /** - * Ensure that file on the given path exists in the system. - * - * @param path Path. - * @return True if file exists, false otherwise. - */ - IGNITE_IMPORT_EXPORT bool FileExists(const std::string& path); - - /** - * Check if the provided path is the valid directory. - * @return @c true if the provided path is the valid directory. - */ - IGNITE_IMPORT_EXPORT bool IsValidDirectory(const std::string& path); - - /** - * Deletes provided filesystem element if exists. - * @return @c true if the provided path exists. - */ - IGNITE_IMPORT_EXPORT bool DeletePath(const std::string& path); - - /** - * Write file separator to a stream. - * @param ostr Stream. - * @return The same stream for chaining. - */ - IGNITE_IMPORT_EXPORT StdCharOutStream& Fs(StdCharOutStream& ostr); - - /** - * Write dynamic library expansion to a stream. - * @param ostr Stream. - * @return The same stream for chaining. - */ - IGNITE_IMPORT_EXPORT StdCharOutStream& Dle(StdCharOutStream& ostr); - - /** - * Get random seed. - * - * @return Random seed. - */ - IGNITE_IMPORT_EXPORT unsigned GetRandSeed(); - } - } -} - -#endif //_IGNITE_ODBC_COMMON_PLATFORM_UTILS diff --git a/src/odbc/include/ignite/odbc/common/utils.h b/src/odbc/include/ignite/odbc/common/utils.h deleted file mode 100644 index accb2fa84..000000000 --- a/src/odbc/include/ignite/odbc/common/utils.h +++ /dev/null @@ -1,664 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _IGNITE_ODBC_COMMON_UTILS -#define _IGNITE_ODBC_COMMON_UTILS - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include "ignite/time.h" - -#ifdef IGNITE_FRIEND -# define IGNITE_FRIEND_EXPORT IGNITE_EXPORT -#else -# define IGNITE_FRIEND_EXPORT -#endif - -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Replace all alphabetic symbols of the string with their lowercase - * versions. - * @param str String to be transformed. - */ - inline void IntoLower(std::string& str) - { - std::transform(str.begin(), str.end(), str.begin(), ::tolower); - } - - /** - * Get lowercase version of the string. - * - * @param str Input string. - * @return Lowercased version of the string. - */ - inline std::string ToLower(const std::string& str) - { - std::string res(str); - IntoLower(res); - return res; - } - - /** - * Strips leading and trailing whitespaces from string. - * - * @param str String to be transformed. - */ - IGNITE_IMPORT_EXPORT void StripSurroundingWhitespaces(std::string& str); - - /** - * Skip leading spaces. - * - * @param begin Iterator to the beginning of the character sequence. - * @param end Iterator to the end of the character sequence. - * @return Iterator to first non-blanc character. - */ - template - Iterator SkipLeadingSpaces(Iterator begin, Iterator end) - { - Iterator res = begin; - - while (isspace(*res) && res != end) - ++res; - - return res; - } - - /** - * Skip trailing spaces. - * - * @param begin Iterator to the beginning of the character sequence. - * @param end Iterator to the end of the character sequence. - * @return Iterator to last non-blanc character. - */ - template - Iterator SkipTrailingSpaces(Iterator begin, Iterator end) - { - Iterator res = end - 1; - - while (isspace(*res) && res != begin - 1) - --res; - - return res + 1; - } - - /** - * Remove leading and trailing spaces. - * - * @param begin Iterator to the beginning of the character sequence. - * @param end Iterator to the end of the character sequence. - * @return String without leading and trailing spaces. - */ - template - std::string StripSurroundingWhitespaces(Iterator begin, Iterator end) - { - std::string res; - - if (begin >= end) - return res; - - Iterator skipped_leading = SkipLeadingSpaces(begin, end); - Iterator skipped_trailing = SkipTrailingSpaces(skipped_leading, end); - - res.reserve(skipped_trailing - skipped_leading); - - std::copy(skipped_leading, skipped_trailing, std::back_inserter(res)); - - return res; - } - - /** - * Get string representation of long in decimal form. - * - * @param val Long value to be converted to string. - * @return String contataining decimal representation of the value. - */ - inline std::string LongToString(long val) - { - std::stringstream tmp; - tmp << val; - return tmp.str(); - } - - /** - * Parse string to try and get int value. - * - * @param str String to be parsed. - * @return String contataining decimal representation of the value. - */ - inline int ParseInt(const std::string& str) - { - return atoi(str.c_str()); - } - - /** - * Copy characters. - * - * @param val Value. - * @return Result. - */ - IGNITE_IMPORT_EXPORT char* CopyChars(const char* val); - - /** - * Release characters. - * - * @param val Value. - */ - IGNITE_IMPORT_EXPORT void ReleaseChars(char* val); - - /** - * Casts value of one type to another type, using stringstream. - * - * @param val Input value. - * @param res Resulted value. - */ - template - void LexicalCast(const T2& val, T1& res) - { - std::stringstream converter; - - converter << val; - converter >> res; - } - - /** - * Casts value of one type to another type, using stringstream. - * - * @param val Input value. - * @return Resulted value. - */ - template - T1 LexicalCast(const T2& val) - { - T1 res; - - LexicalCast(val, res); - - return res; - } - - /** - * Check if all characters are digits. - * - * @param val Value to check. - */ - IGNITE_IMPORT_EXPORT bool AllDigits(const std::string& val); - - /** - * Converts 32-bit integer to big endian format - * - * @param value Input value - * @return Resulting value - */ - IGNITE_IMPORT_EXPORT uint32_t ToBigEndian(uint32_t value); - - /** - * Convert Date type to standard C type time_t. - * - * @param date Date type value. - * @return Corresponding value of time_t. - */ - inline time_t DateToCTime(const Date& date) - { - return static_cast(date.GetSeconds()); - } - - /** - * Convert Timestamp type to standard C type time_t. - * - * @param ts Timestamp type value. - * @return Corresponding value of time_t. - */ - inline time_t TimestampToCTime(const Timestamp& ts) - { - return static_cast(ts.GetSeconds()); - } - - /** - * Convert Time type to standard C type time_t. - * - * @param time Time type value. - * @return Corresponding value of time_t. - */ - inline time_t TimeToCTime(const Time& time) - { - return static_cast(time.GetSeconds()); - } - - /** - * Convert Date type to standard C type time_t. - * - * @param date Date type value. - * @param ctime Corresponding value of struct tm. - * @return True on success. - */ - inline bool DateToCTm(const Date& date, tm& ctime) - { - time_t tmt = DateToCTime(date); - - return common::IgniteGmTime(tmt, ctime); - } - - /** - * Convert Timestamp type to standard C type struct tm. - * - * @param ts Timestamp type value. - * @param ctime Corresponding value of struct tm. - * @return True on success. - */ - inline bool TimestampToCTm(const Timestamp& ts, tm& ctime) - { - time_t tmt = TimestampToCTime(ts); - - return common::IgniteGmTime(tmt, ctime); - } - - /** - * Convert Time type to standard C type struct tm. - * - * @param time Time type value. - * @param ctime Corresponding value of struct tm. - * @return True on success. - */ - inline bool TimeToCTm(const Time& time, tm& ctime) - { - time_t tmt = TimeToCTime(time); - - return common::IgniteGmTime(tmt, ctime); - } - - /** - * Convert standard C type time_t to Date. - * - * @param ctime Standard C type time_t. - * @return Corresponding value of Date. - */ - inline Date CTimeToDate(time_t ctime) - { - return Date(ctime * 1000); - } - - /** - * Convert standard C type time_t to Time. - * - * @param ctime Standard C type time_t. - * @return Corresponding value of Time. - */ - inline Time CTimeToTime(time_t ctime) - { - return Time(ctime * 1000); - } - - /** - * Convert standard C type time_t to Timestamp type. - * - * @param ctime Standard C type time_t. - * @param ns Nanoseconds second fraction. - * @return Corresponding value of Timestamp. - */ - inline Timestamp CTimeToTimestamp(time_t ctime, int32_t ns) - { - return Timestamp(ctime, ns); - } - - /** - * Convert standard C type struct tm to Date type. - * - * @param ctime Standard C type struct tm. - * @return Corresponding value of Date. - */ - inline Date CTmToDate(const tm& ctime) - { - time_t time = common::IgniteTimeGm(ctime); - - return CTimeToDate(time); - } - - /** - * Convert standard C type struct tm to Time type. - * - * @param ctime Standard C type struct tm. - * @return Corresponding value of Time. - */ - inline Time CTmToTime(const tm& ctime) - { - time_t time = common::IgniteTimeGm(ctime); - - return CTimeToTime(time); - } - - /** - * Convert standard C type struct tm to Timestamp type. - * - * @param ctime Standard C type struct tm. - * @param ns Nanoseconds second fraction. - * @return Corresponding value of Timestamp. - */ - inline Timestamp CTmToTimestamp(const tm& ctime, int32_t ns) - { - time_t time = common::IgniteTimeGm(ctime); - - return CTimeToTimestamp(time, ns); - } - - /** - * Make Date in human understandable way. - * - * Created Date uses GMT timezone. - * - * @param year Year. - * @param month Month. - * @param day Day. - * @param hour Hour. - * @param min Min. - * @param sec Sec. - * @return Date. - */ - IGNITE_FRIEND_EXPORT Date MakeDateGmt(int year = 1900, int month = 1, - int day = 1, int hour = 0, int min = 0, int sec = 0); - - /** - * Make Date in human understandable way. - * - * Created Date uses local timezone. - * - * @param year Year. - * @param month Month. - * @param day Day. - * @param hour Hour. - * @param min Min. - * @param sec Sec. - * @return Date. - */ - IGNITE_FRIEND_EXPORT Date MakeDateLocal(int year = 1900, int month = 1, - int day = 1, int hour = 0, int min = 0, int sec = 0); - - /** - * Make Time in human understandable way. - * - * Created Time uses GMT timezone. - * - * @param hour Hour. - * @param min Minute. - * @param sec Second. - * @return Time. - */ - IGNITE_FRIEND_EXPORT Time MakeTimeGmt(int hour = 0, int min = 0, int sec = 0); - - /** - * Make Time in human understandable way. - * - * Created Time uses Local timezone. - * - * @param hour Hour. - * @param min Minute. - * @param sec Second. - * @return Time. - */ - IGNITE_FRIEND_EXPORT Time MakeTimeLocal(int hour = 0, int min = 0, int sec = 0); - - /** - * Make Timestamp in human understandable way. - * - * Created Timestamp uses GMT timezone. - * - * @param year Year. - * @param month Month. - * @param day Day. - * @param hour Hour. - * @param min Minute. - * @param sec Second. - * @param ns Nanosecond. - * @return Timestamp. - */ - IGNITE_FRIEND_EXPORT Timestamp MakeTimestampGmt(int year = 1900, int month = 1, - int day = 1, int hour = 0, int min = 0, int sec = 0, long ns = 0); - - /** - * Make Date in human understandable way. - * - * Created Timestamp uses Local timezone. - * - * @param year Year. - * @param month Month. - * @param day Day. - * @param hour Hour. - * @param min Minute. - * @param sec Second. - * @param ns Nanosecond. - * @return Timestamp. - */ - IGNITE_FRIEND_EXPORT Timestamp MakeTimestampLocal(int year = 1900, int month = 1, - int day = 1, int hour = 0, int min = 0, int sec = 0, long ns = 0); - - /** - * Meta-programming class. - * Defines T1 as ::type if the condition is true, otherwise - * defines T2 as ::type. - */ - template - struct Conditional - { - typedef T1 type; - }; - - /** - * Specialization for the false case. - */ - template - struct Conditional - { - typedef T2 type; - }; - - /** - * Returns the bigger type. - */ - template - struct Bigger - { - typedef typename Conditional<(sizeof(T1) > sizeof(T2)), T1, T2>::type type; - }; - - /** - * Utility class to bind class instance with member function. - */ - template - class BoundInstance - { - public: - typedef R FunctionReturnType; - typedef T ClassType; - typedef FunctionReturnType(ClassType::* MemberFunctionType)(); - - /** - * Constructor. - * - * @param instance Class instance. - * @param mfunc Member function. - */ - BoundInstance(ClassType* instance, MemberFunctionType mfunc) : - instance(instance), - mfunc(mfunc) - { - // No-op. - } - - /** - * Invoke operator. - * - * @return Result of the invokation of the member function on the bound instance. - */ - FunctionReturnType operator()() - { - return (instance->*mfunc)(); - } - - private: - /** Instance reference. */ - ClassType* instance; - - /** Member function pointer. */ - MemberFunctionType mfunc; - }; - - /** - * Utility function for binding. - */ - template - BoundInstance Bind(T* instance, R(T::* mfunc)()) - { - return BoundInstance(instance, mfunc); - } - - /** - * Method guard class template. - * - * Upon destruction calls provided method on provided class instance. - * - * @tparam T Value type. - */ - template - class MethodGuard - { - public: - /** Value type. */ - typedef T ValueType; - - /** Mehtod type. */ - typedef void (ValueType::*MethodType)(); - - /** - * Constructor. - * - * @param val Instance, to call method on. - * @param method Method to call. - */ - MethodGuard(ValueType* val, MethodType method) : - val(val), - method(method) - { - // No-op. - } - - /** - * Destructor. - */ - ~MethodGuard() - { - if (val && method) - (val->*method)(); - } - - /** - * Release control over object. - */ - void Release() - { - val = 0; - method = 0; - } - - private: - /** Instance, to call method on. */ - ValueType* val; - - /** Method to call. */ - MethodType method; - }; - - /** - * Deinit guard class template. - * - * Upon destruction calls provided deinit function on provided instance. - * - * @tparam T Value type. - */ - template - class DeinitGuard - { - public: - /** Value type. */ - typedef T ValueType; - - /** Deinit function type. */ - typedef void (*FuncType)(ValueType*); - - /** - * Constructor. - * - * @param val Instance, to call method on. - * @param method Method to call. - */ - DeinitGuard(ValueType* val, FuncType method) : - val(val), - func(method) - { - // No-op. - } - - /** - * Destructor. - */ - ~DeinitGuard() - { - if (val && func) - (func)(val); - } - - /** - * Release control over object. - */ - void Release() - { - val = 0; - func = 0; - } - - private: - /** Instance, to call method on. */ - ValueType* val; - - /** Method to call. */ - FuncType func; - }; - - /** - * Get dynamic library full name. - * @param name Name without extension. - * @return Full name. - */ - IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const char* name); - } - } -} - -#endif //_IGNITE_ODBC_COMMON_UTILS diff --git a/src/odbc/include/ignite/odbc/connection.h b/src/odbc/include/ignite/odbc/connection.h index 0a917a50d..3fefc8e33 100644 --- a/src/odbc/include/ignite/odbc/connection.h +++ b/src/odbc/include/ignite/odbc/connection.h @@ -30,7 +30,7 @@ #include "ignite/odbc/diagnostic/diagnosable_adapter.h" #include "ignite/odbc/streaming/streaming_context.h" #include "ignite/odbc/odbc_error.h" -#include "ignite/odbc/jni/java.h" +#include "ignite/odbc/end_point.h" namespace ignite { @@ -228,6 +228,8 @@ namespace ignite if (!success) return false; + parser.Decode(rsp, tempBuffer); + return true; } @@ -487,23 +489,7 @@ namespace ignite * @throw IgniteError on failure. * @return @c true on success and @c false otherwise. */ - bool TryRestoreConnection(IgniteError& err); - - /** - * Formats the JDBC connection string from configuration values. - * @return the JDBC connection string. - */ - std::string FormatJdbcConnectionString() const; - - /** - * Creates JVM options - */ - void SetJvmOptions(const std::string& cp); - - /** - * De-initializes the JVM options - */ - void Deinit(); + bool TryRestoreConnection(); /** * Collect all addresses from config. @@ -529,6 +515,9 @@ namespace ignite /** Parent. */ Environment* env; + /** Client Socket. */ + std::auto_ptr socket; + /** Connection timeout in seconds. */ int32_t timeout; @@ -547,12 +536,6 @@ namespace ignite /** Connection info. */ config::ConnectionInfo info; - /** Java connection object */ - jobject connection; - - /** JVM options */ - std::vector< char* > opts; - /** Streaming context. */ streaming::StreamingContext streamingContext; }; diff --git a/src/odbc/include/ignite/odbc/ignite_error.h b/src/odbc/include/ignite/odbc/ignite_error.h deleted file mode 100644 index 5034a6e9c..000000000 --- a/src/odbc/include/ignite/odbc/ignite_error.h +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Declares ignite::IgniteError class. - */ - -#ifndef _IGNITE_ODBC_IGNITE_ERROR -#define _IGNITE_ODBC_IGNITE_ERROR - -#include - -#include -#include - -#include - -#define IGNITE_ERROR_1(code, part1) { \ - std::stringstream stream; \ - stream << (part1); \ - throw ignite::IgniteError(code, stream.str().c_str()); \ -} - -#define IGNITE_ERROR_2(code, part1, part2) { \ - std::stringstream stream; \ - stream << (part1) << (part2); \ - throw ignite::IgniteError(code, stream.str().c_str()); \ -} - -#define IGNITE_ERROR_3(code, part1, part2, part3) { \ - std::stringstream stream; \ - stream << (part1) << (part2) << (part3); \ - throw ignite::IgniteError(code, stream.str().c_str()); \ -} - -#define IGNITE_ERROR_FORMATTED_1(code, msg, key1, val1) { \ - std::stringstream stream; \ - stream << msg << " [" << key1 << "=" << (val1) << "]"; \ - throw ignite::IgniteError(code, stream.str().c_str()); \ -} - -#define IGNITE_ERROR_FORMATTED_2(code, msg, key1, val1, key2, val2) { \ - std::stringstream stream; \ - stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" << (val2) << "]"; \ - throw ignite::IgniteError(code, stream.str().c_str()); \ -} - -#define IGNITE_ERROR_FORMATTED_3(code, msg, key1, val1, key2, val2, key3, val3) { \ - std::stringstream stream; \ - stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" << (val2) << ", " << key3 << "=" << (val3) << "]"; \ - throw ignite::IgniteError(code, stream.str().c_str()); \ -} - -#define IGNITE_ERROR_FORMATTED_4(code, msg, key1, val1, key2, val2, key3, val3, key4, val4) { \ - std::stringstream stream; \ - stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" << (val2) << ", " << key3 << "=" << (val3) << ", " << key4 << "=" << (val4) << "]"; \ - throw ignite::IgniteError(code, stream.str().c_str()); \ -} - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4275) -#endif //_MSC_VER - -namespace ignite -{ - namespace odbc - { - namespace java - { - /* JNI error constants. */ - const int IGNITE_JNI_ERR_SUCCESS = 0; - const int IGNITE_JNI_ERR_GENERIC = 1; - const int IGNITE_JNI_ERR_JVM_INIT = 2; - const int IGNITE_JNI_ERR_JVM_ATTACH = 3; - } - - /** - * %Ignite error information. - */ - class IGNITE_IMPORT_EXPORT IgniteError : public std::exception - { - public: - /** Success. */ - static const int IGNITE_SUCCESS = 0; - - /** Failed to initialize JVM. */ - static const int IGNITE_ERR_JVM_INIT = 1; - - /** Failed to attach to JVM. */ - static const int IGNITE_ERR_JVM_ATTACH = 2; - - /** JVM library is not found. */ - static const int IGNITE_ERR_JVM_LIB_NOT_FOUND = 3; - - /** Failed to load JVM library. */ - static const int IGNITE_ERR_JVM_LIB_LOAD_FAILED = 4; - - /** JVM classpath is not provided. */ - static const int IGNITE_ERR_JVM_NO_CLASSPATH = 5; - - /** JVM error: no class definition found. */ - static const int IGNITE_ERR_JVM_NO_CLASS_DEF_FOUND = 6; - - /** JVM error: no such method. */ - static const int IGNITE_ERR_JVM_NO_SUCH_METHOD = 7; - - /** Memory operation error. */ - static const int IGNITE_ERR_MEMORY = 1001; - - /** Binary error. */ - static const int IGNITE_ERR_BINARY = 1002; - - /** Standard library exception. */ - static const int IGNITE_ERR_STD = 1003; - - /** Generic %Ignite error. */ - static const int IGNITE_ERR_GENERIC = 2000; - - /** Illegal argument passed. */ - static const int IGNITE_ERR_ILLEGAL_ARGUMENT = 2001; - - /** Illegal state. */ - static const int IGNITE_ERR_ILLEGAL_STATE = 2002; - - /** Unsupported operation. */ - static const int IGNITE_ERR_UNSUPPORTED_OPERATION = 2003; - - /** Thread has been interrup. */ - static const int IGNITE_ERR_INTERRUPTED = 2004; - - /** Cluster group is empty. */ - static const int IGNITE_ERR_CLUSTER_GROUP_EMPTY = 2005; - - /** Cluster topology problem. */ - static const int IGNITE_ERR_CLUSTER_TOPOLOGY = 2006; - - /** Compute execution rejected. */ - static const int IGNITE_ERR_COMPUTE_EXECUTION_REJECTED = 2007; - - /** Compute job failover. */ - static const int IGNITE_ERR_COMPUTE_JOB_FAILOVER = 2008; - - /** Compute task cancelled. */ - static const int IGNITE_ERR_COMPUTE_TASK_CANCELLED = 2009; - - /** Compute task timeout. */ - static const int IGNITE_ERR_COMPUTE_TASK_TIMEOUT = 2010; - - /** Compute user undeclared exception. */ - static const int IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION = 2011; - - /** Generic cache error. */ - static const int IGNITE_ERR_CACHE = 2012; - - /** Generic cache loader error. */ - static const int IGNITE_ERR_CACHE_LOADER = 2013; - - /** Generic cache writer error. */ - static const int IGNITE_ERR_CACHE_WRITER = 2014; - - /** Generic cache entry processor error. */ - static const int IGNITE_ERR_ENTRY_PROCESSOR = 2015; - - /** Cache atomic update timeout. */ - static const int IGNITE_ERR_CACHE_ATOMIC_UPDATE_TIMEOUT = 2016; - - /** Cache partial update. */ - static const int IGNITE_ERR_CACHE_PARTIAL_UPDATE = 2017; - - /** Transaction optimisitc exception. */ - static const int IGNITE_ERR_TX_OPTIMISTIC = 2018; - - /** Transaction timeout. */ - static const int IGNITE_ERR_TX_TIMEOUT = 2019; - - /** Transaction rollback. */ - static const int IGNITE_ERR_TX_ROLLBACK = 2020; - - /** Transaction heuristic exception. */ - static const int IGNITE_ERR_TX_HEURISTIC = 2021; - - /** Authentication error. */ - static const int IGNITE_ERR_AUTHENTICATION = 2022; - - /** Security error. */ - static const int IGNITE_ERR_SECURITY = 2023; - - /** Future state error. */ - static const int IGNITE_ERR_FUTURE_STATE = 2024; - - /** Networking error. */ - static const int IGNITE_ERR_NETWORK_FAILURE = 2025; - - /** SSL/TLS error. */ - static const int IGNITE_ERR_SECURE_CONNECTION_FAILURE = 2026; - - /** Transaction already started by current thread. */ - static const int IGNITE_ERR_TX_THIS_THREAD = 2027; - - /** Generic transaction error. */ - static const int IGNITE_ERR_TX = 2028; - - - /** Unknown error. */ - static const int IGNITE_ERR_UNKNOWN = -1; - - /** - * Throw an error if code is not IGNITE_SUCCESS. - * - * @param err Error. - */ - static void ThrowIfNeeded(const IgniteError& err); - - /** - * Default constructor. - * Creates empty error. Code is IGNITE_SUCCESS and message is NULL. - */ - IgniteError(); - - /** - * Create error with specific code. Message is set to NULL. - * - * @param code Error code. - */ - IgniteError(const int32_t code); - - /** - * Create error with specific code and message. - * - * @param code Error code. - * @param msg Message. - */ - IgniteError(const int32_t code, const char* msg); - - /** - * Copy constructor. - * - * @param other Other instance. - */ - IgniteError(const IgniteError& other); - - /** - * Assignment operator. - * - * @param other Other instance. - * @return *this. - */ - IgniteError& operator=(const IgniteError& other); - - /** - * Destructor. - */ - ~IgniteError() IGNITE_NO_THROW; - - /** - * Get error code. - * - * @return Error code. - */ - int32_t GetCode() const; - - /** - * Get error message. - * - * @return Error message. Can be NULL. - */ - const char* GetText() const IGNITE_NO_THROW; - - /** - * Implementation of the standard std::exception::what() method. - * Synonym for GetText() method. - * - * @return Error message string. - */ - virtual const char* what() const IGNITE_NO_THROW; - - /** - * Initializes IgniteError instance from the JNI error. - * - * @param jniCode Error code. - * @param jniCls Error class. - * @param jniMsg Error message. - * @param err Error. Can not be NULL. - */ - static void SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError& err); - private: - /** Error code. */ - int32_t code; - - /** Error message. */ - char* msg; - }; - } -} - -#ifdef _MSC_VER -# pragma warning(pop) -#endif //_MSC_VER - -#endif //_IGNITE_ODBC_IGNITE_ERROR diff --git a/src/odbc/include/ignite/odbc/jni/java.h b/src/odbc/include/ignite/odbc/jni/java.h deleted file mode 100644 index 3925aaf0a..000000000 --- a/src/odbc/include/ignite/odbc/jni/java.h +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IGNITE_ODBC_JNI_JAVA -#define _IGNITE_ODBC_JNI_JAVA - -#include - -#include - -#include - -namespace ignite { - namespace odbc { - namespace jni { - namespace java { - - /* Handlers for callbacks from Java. */ - typedef int64_t(JNICALL* CacheStoreCreateHandler)(void* target, int64_t memPtr); - typedef int(JNICALL* CacheStoreInvokeHandler)(void* target, int64_t objPtr, - int64_t memPtr); - typedef void(JNICALL* CacheStoreDestroyHandler)(void* target, int64_t objPtr); - typedef int64_t(JNICALL* CacheStoreSessionCreateHandler)(void* target, - int64_t storePtr); - - typedef int64_t(JNICALL* CacheEntryFilterCreateHandler)(void* target, - int64_t memPtr); - typedef int(JNICALL* CacheEntryFilterApplyHandler)(void* target, int64_t ptr, - int64_t memPtr); - typedef void(JNICALL* CacheEntryFilterDestroyHandler)(void* target, - int64_t ptr); - - typedef void(JNICALL* CacheInvokeHandler)(void* target, int64_t inMemPtr, - int64_t outMemPtr); - - typedef void(JNICALL* ComputeTaskMapHandler)(void* target, int64_t taskPtr, - int64_t inMemPtr, - int64_t outMemPtr); - typedef int(JNICALL* ComputeTaskJobResultHandler)(void* target, int64_t taskPtr, - int64_t jobPtr, - int64_t memPtr); - typedef void(JNICALL* ComputeTaskReduceHandler)(void* target, int64_t taskPtr); - typedef void(JNICALL* ComputeTaskCompleteHandler)(void* target, int64_t taskPtr, - int64_t memPtr); - typedef int(JNICALL* ComputeJobSerializeHandler)(void* target, int64_t jobPtr, - int64_t memPtr); - typedef int64_t(JNICALL* ComputeJobCreateHandler)(void* target, int64_t memPtr); - typedef void(JNICALL* ComputeJobExecuteHandler)(void* target, int64_t jobPtr, - int cancel, int64_t memPtr); - typedef void(JNICALL* ComputeJobCancelHandler)(void* target, int64_t jobPtr); - typedef void(JNICALL* ComputeJobDestroyHandler)(void* target, int64_t jobPtr); - - typedef void(JNICALL* ContinuousQueryListenerApplyHandler)(void* target, - int64_t lsnrPtr, - int64_t memPtr); - typedef int64_t(JNICALL* ContinuousQueryFilterCreateHandler)(void* target, - int64_t memPtr); - typedef int(JNICALL* ContinuousQueryFilterApplyHandler)(void* target, - int64_t filterPtr, - int64_t memPtr); - typedef void(JNICALL* ContinuousQueryFilterReleaseHandler)(void* target, - int64_t filterPtr); - - typedef void(JNICALL* DataStreamerTopologyUpdateHandler)(void* target, - int64_t ldrPtr, - int64_t topVer, - int topSize); - typedef void(JNICALL* DataStreamerStreamReceiverInvokeHandler)( - void* target, int64_t ptr, void* cache, int64_t memPtr, - unsigned char keepPortable); - - typedef void(JNICALL* FutureByteResultHandler)(void* target, int64_t futAddr, - int res); - typedef void(JNICALL* FutureBoolResultHandler)(void* target, int64_t futAddr, - int res); - typedef void(JNICALL* FutureShortResultHandler)(void* target, int64_t futAddr, - int res); - typedef void(JNICALL* FutureCharResultHandler)(void* target, int64_t futAddr, - int res); - typedef void(JNICALL* FutureIntResultHandler)(void* target, int64_t futAddr, - int res); - typedef void(JNICALL* FutureFloatResultHandler)(void* target, int64_t futAddr, - float res); - typedef void(JNICALL* FutureLongResultHandler)(void* target, int64_t futAddr, - int64_t res); - typedef void(JNICALL* FutureDoubleResultHandler)(void* target, int64_t futAddr, - double res); - typedef void(JNICALL* FutureObjectResultHandler)(void* target, int64_t futAddr, - int64_t memPtr); - typedef void(JNICALL* FutureNullResultHandler)(void* target, int64_t futAddr); - typedef void(JNICALL* FutureErrorHandler)(void* target, int64_t futAddr, - int64_t memPtr); - - typedef void(JNICALL* LifecycleEventHandler)(void* target, int64_t ptr, - int evt); - - typedef void(JNICALL* MemoryReallocateHandler)(void* target, int64_t memPtr, - int cap); - - typedef int64_t(JNICALL* MessagingFilterCreateHandler)(void* target, - int64_t memPtr); - typedef int(JNICALL* MessagingFilterApplyHandler)(void* target, int64_t ptr, - int64_t memPtr); - typedef void(JNICALL* MessagingFilterDestroyHandler)(void* target, int64_t ptr); - - typedef int64_t(JNICALL* EventFilterCreateHandler)(void* target, - int64_t memPtr); - typedef int(JNICALL* EventFilterApplyHandler)(void* target, int64_t ptr, - int64_t memPtr); - typedef void(JNICALL* EventFilterDestroyHandler)(void* target, int64_t ptr); - - typedef int64_t(JNICALL* ServiceInitHandler)(void* target, int64_t memPtr); - typedef void(JNICALL* ServiceExecuteHandler)(void* target, int64_t svcPtr, - int64_t memPtr); - typedef void(JNICALL* ServiceCancelHandler)(void* target, int64_t svcPtr, - int64_t memPtr); - typedef void(JNICALL* ServiceInvokeMethodHandler)(void* target, int64_t svcPtr, - int64_t inMemPtr, - int64_t outMemPtr); - typedef int(JNICALL* ClusterNodeFilterApplyHandler)(void* target, - int64_t memPtr); - - typedef int64_t(JNICALL* NodeInfoHandler)(void* target, int64_t memPtr); - - typedef void(JNICALL* OnStartHandler)(void* target, void* proc, int64_t memPtr); - typedef void(JNICALL* OnStopHandler)(void* target); - typedef void(JNICALL* ErrorHandler)(void* target, int errCode, - const char* errClsChars, int errClsCharsLen, - const char* errMsgChars, int errMsgCharsLen, - const char* stackTraceChars, - int stackTraceCharsLen, void* errData, - int errDataLen); - - typedef int64_t(JNICALL* ExtensionCallbackInLongOutLongHandler)(void* target, - int typ, - int64_t arg1); - typedef int64_t(JNICALL* ExtensionCallbackInLongLongOutLongHandler)( - void* target, int typ, int64_t arg1, int64_t arg2); - - typedef void(JNICALL* OnClientDisconnectedHandler)(void* target); - typedef void(JNICALL* OnClientReconnectedHandler)( - void* target, unsigned char clusterRestarted); - - typedef int64_t(JNICALL* AffinityFunctionInitHandler)(void* target, - int64_t memPtr, - void* baseFunc); - typedef int(JNICALL* AffinityFunctionPartitionHandler)(void* target, - int64_t ptr, - int64_t memPtr); - typedef void(JNICALL* AffinityFunctionAssignPartitionsHandler)( - void* target, int64_t ptr, int64_t inMemPtr, int64_t outMemPtr); - typedef void(JNICALL* AffinityFunctionRemoveNodeHandler)(void* target, - int64_t ptr, - int64_t memPtr); - typedef void(JNICALL* AffinityFunctionDestroyHandler)(void* target, - int64_t ptr); - - typedef void(JNICALL* ConsoleWriteHandler)(const char* chars, int charsLen, - unsigned char isErr); - - typedef void(JNICALL* LoggerLogHandler)( - void* target, int level, const char* messageChars, int messageCharsLen, - const char* categoryChars, int categoryCharsLen, const char* errorInfoChars, - int errorInfoCharsLen, int64_t memPtr); - typedef bool(JNICALL* LoggerIsLevelEnabledHandler)(void* target, int level); - - typedef int64_t(JNICALL* InLongOutLongHandler)(void* target, int type, - int64_t val); - typedef int64_t(JNICALL* InLongLongLongObjectOutLongHandler)( - void* target, int type, int64_t val1, int64_t val2, int64_t val3, - void* arg); - - /** - * Is Java 9 or later is used. - * - * @return true if the Java 9 or later is in use. - */ - bool IGNITE_IMPORT_EXPORT IsJava9OrLater(); - - /** - * JNI handlers holder. - */ - struct JniHandlers { - void* target; - - ErrorHandler error; - - LoggerLogHandler loggerLog; - LoggerIsLevelEnabledHandler loggerIsLevelEnabled; - - InLongOutLongHandler inLongOutLong; - InLongLongLongObjectOutLongHandler inLongLongLongObjectOutLong; - }; - - /** - * JNI Java members. - */ - struct JniJavaMembers { - jclass c_Class; - jmethodID m_Class_getName; - - jclass c_Throwable; - jmethodID m_Throwable_getMessage; - jmethodID m_Throwable_printStackTrace; - - jclass c_PlatformUtils; - jmethodID m_PlatformUtils_getFullStackTrace; - - /** - * Constructor. - */ - void Initialize(JNIEnv* env); - - /** - * Destroy members releasing all allocated classes. - */ - void Destroy(JNIEnv* env); - - /** - * Write error information. - */ - bool WriteErrorInfo(JNIEnv* env, char** errClsName, int* errClsNameLen, - char** errMsg, int* errMsgLen, char** stackTrace, - int* stackTraceLen); - }; - - /** - * JNI members. - */ - struct JniMembers { - jclass c_DocumentDbConnectionProperties; - jmethodID m_DocumentDbConnectionPropertiesGetPropertiesFromConnectionString; - - jclass c_DocumentDbConnection; - jmethodID m_DocumentDbConnectionInit; - jmethodID m_DocumentDbClose; - - jclass c_DriverManager; - jmethodID m_DriverManagerGetConnection; - - jclass c_JavaSqlConnection; - jmethodID m_JavaSqlConnectionClose; - - jclass c_IgniteException; - - jclass c_PlatformIgnition; - jmethodID m_PlatformIgnition_start; - jmethodID m_PlatformIgnition_instance; - jmethodID m_PlatformIgnition_environmentPointer; - jmethodID m_PlatformIgnition_stop; - jmethodID m_PlatformIgnition_stopAll; - - jclass c_PlatformTarget; - jmethodID m_PlatformTarget_inLongOutLong; - jmethodID m_PlatformTarget_inStreamOutLong; - jmethodID m_PlatformTarget_inStreamOutObject; - jmethodID m_PlatformTarget_outStream; - jmethodID m_PlatformTarget_outObject; - jmethodID m_PlatformTarget_inStreamAsync; - jmethodID m_PlatformTarget_inStreamOutObjectAsync; - jmethodID m_PlatformTarget_inStreamOutStream; - jmethodID m_PlatformTarget_inObjectStreamOutObjectStream; - - jclass c_PlatformUtils; - jmethodID m_PlatformUtils_reallocate; - jmethodID m_PlatformUtils_errData; - - /** - * Constructor. - */ - void Initialize(JNIEnv* env); - - /** - * Destroy members releasing all allocated classes. - */ - void Destroy(JNIEnv* env); - }; - - /** - * JNI JVM wrapper. - */ - class IGNITE_IMPORT_EXPORT JniJvm { - public: - /** - * Default constructor for uninitialized JVM. - */ - JniJvm(); - - /** - * Constructor. - * - * @param jvm JVM. - * @param javaMembers Java members. - * @param members Members. - */ - JniJvm(JavaVM* jvm, JniJavaMembers javaMembers, JniMembers members); - - /** - * Get JVM. - * - * @param JVM. - */ - JavaVM* GetJvm(); - - /** - * Get Java members. - * - * @param Java members. - */ - JniJavaMembers& GetJavaMembers(); - - /** - * Get members. - * - * @param Members. - */ - JniMembers& GetMembers(); - - private: - /** JVM. */ - JavaVM* jvm; - - /** Java members. */ - JniJavaMembers javaMembers; - - /** Members. */ - JniMembers members; - }; - - /** - * JNI error information. - */ - struct IGNITE_IMPORT_EXPORT JniErrorInfo { - int code; - char* errCls = nullptr; - char* errMsg = nullptr; - - /** - * Default constructor. Creates empty error info. - */ - JniErrorInfo(); - - /** - * Constructor. - * - * @param code Code. - * @param errCls Error class. - * @param errMsg Error message. - */ - JniErrorInfo(int code, const char* errCls, const char* errMsg); - - /** - * Copy constructor. - * - * @param other Other instance. - */ - JniErrorInfo(const JniErrorInfo& other); - - /** - * Assignment operator overload. - * - * @param other Other instance. - * @return This instance. - */ - JniErrorInfo& operator=(const JniErrorInfo& other); - - /** - * Destructor. - */ - ~JniErrorInfo(); - }; - - /** - * Unmanaged context. - */ - class IGNITE_IMPORT_EXPORT JniContext { - public: - static JniContext* Create(char** opts, int optsLen, JniHandlers hnds); - static JniContext* Create(char** opts, int optsLen, JniHandlers hnds, - JniErrorInfo* errInfo); - static int Reallocate(int64_t memPtr, int cap); - static void Detach(); - static void Release(jobject obj); - static void SetConsoleHandler(ConsoleWriteHandler consoleHandler); - static int RemoveConsoleHandler(ConsoleWriteHandler consoleHandler); - - jobject DocumentDbConnect(const char* connectionString, - JniErrorInfo* errInfo); - - void DocumentDbDisconnect(const jobject connection, JniErrorInfo* errInfo); - - int64_t TargetInLongOutLong(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); - int64_t TargetInStreamOutLong(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); - void TargetInStreamOutStream(jobject obj, int opType, int64_t inMemPtr, - int64_t outMemPtr, - JniErrorInfo* errInfo = NULL); - jobject TargetInStreamOutObject(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); - jobject TargetInObjectStreamOutObjectStream(jobject obj, int opType, - void* arg, int64_t inMemPtr, - int64_t outMemPtr, - JniErrorInfo* errInfo = NULL); - void TargetOutStream(jobject obj, int opType, int64_t memPtr, - JniErrorInfo* errInfo = NULL); - jobject TargetOutObject(jobject obj, int opType, - JniErrorInfo* errInfo = NULL); - void TargetInStreamAsync(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); - jobject TargetInStreamOutObjectAsync(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); - - jobject CacheOutOpQueryCursor(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); - jobject CacheOutOpContinuousQuery(jobject obj, int type, int64_t memPtr, - JniErrorInfo* errInfo = NULL); - - jobject Acquire(jobject obj); - - void DestroyJvm(); - void ThrowToJava(char* errMsg); - - private: - JniJvm* jvm; - JniHandlers hnds; - - JniContext(JniJvm* jvm, JniHandlers hnds); - - JNIEnv* Attach(); - void ExceptionCheck(JNIEnv* env); - void ExceptionCheck(JNIEnv* env, JniErrorInfo* errInfo); - jobject LocalToGlobal(JNIEnv* env, jobject obj); - }; - - JNIEXPORT jlong JNICALL JniCacheStoreCreate(JNIEnv* env, jclass cls, - jlong envPtr, jlong memPtr); - JNIEXPORT jint JNICALL JniCacheStoreInvoke(JNIEnv* env, jclass cls, - jlong envPtr, jlong objPtr, - jlong memPtr); - JNIEXPORT void JNICALL JniCacheStoreDestroy(JNIEnv* env, jclass cls, - jlong envPtr, jlong objPtr); - JNIEXPORT jlong JNICALL JniCacheStoreSessionCreate(JNIEnv* env, jclass cls, - jlong envPtr, - jlong storePtr); - - JNIEXPORT jlong JNICALL JniCacheEntryFilterCreate(JNIEnv* env, jclass cls, - jlong envPtr, jlong memPtr); - JNIEXPORT jint JNICALL JniCacheEntryFilterApply(JNIEnv* env, jclass cls, - jlong envPtr, jlong objPtr, - jlong memPtr); - JNIEXPORT void JNICALL JniCacheEntryFilterDestroy(JNIEnv* env, jclass cls, - jlong envPtr, jlong objPtr); - - JNIEXPORT void JNICALL JniCacheInvoke(JNIEnv* env, jclass cls, jlong envPtr, - jlong inMemPtr, jlong outMemPtr); - - JNIEXPORT void JNICALL JniComputeTaskMap(JNIEnv* env, jclass cls, jlong envPtr, - jlong taskPtr, jlong inMemPtr, - jlong outMemPtr); - JNIEXPORT jint JNICALL JniComputeTaskJobResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong taskPtr, - jlong jobPtr, jlong memPtr); - JNIEXPORT void JNICALL JniComputeTaskReduce(JNIEnv* env, jclass cls, - jlong envPtr, jlong taskPtr); - JNIEXPORT void JNICALL JniComputeTaskComplete(JNIEnv* env, jclass cls, - jlong envPtr, jlong taskPtr, - jlong memPtr); - JNIEXPORT jint JNICALL JniComputeJobSerialize(JNIEnv* env, jclass cls, - jlong envPtr, jlong jobPtr, - jlong memPtr); - JNIEXPORT jlong JNICALL JniComputeJobCreate(JNIEnv* env, jclass cls, - jlong envPtr, jlong memPtr); - JNIEXPORT void JNICALL JniComputeJobExecute(JNIEnv* env, jclass cls, - jlong envPtr, jlong jobPtr, - jint cancel, jlong memPtr); - JNIEXPORT void JNICALL JniComputeJobCancel(JNIEnv* env, jclass cls, - jlong envPtr, jlong jobPtr); - JNIEXPORT void JNICALL JniComputeJobDestroy(JNIEnv* env, jclass cls, - jlong envPtr, jlong jobPtr); - - JNIEXPORT void JNICALL JniContinuousQueryListenerApply(JNIEnv* env, jclass cls, - jlong envPtr, - jlong cbPtr, - jlong memPtr); - JNIEXPORT jlong JNICALL JniContinuousQueryFilterCreate(JNIEnv* env, jclass cls, - jlong envPtr, - jlong memPtr); - JNIEXPORT jint JNICALL JniContinuousQueryFilterApply(JNIEnv* env, jclass cls, - jlong envPtr, - jlong filterPtr, - jlong memPtr); - JNIEXPORT void JNICALL JniContinuousQueryFilterRelease(JNIEnv* env, jclass cls, - jlong envPtr, - jlong filterPtr); - - JNIEXPORT void JNICALL JniDataStreamerTopologyUpdate(JNIEnv* env, jclass cls, - jlong envPtr, jlong ldrPtr, - jlong topVer, - jint topSize); - JNIEXPORT void JNICALL JniDataStreamerStreamReceiverInvoke( - JNIEnv* env, jclass cls, jlong envPtr, jlong ptr, jobject cache, - jlong memPtr, jboolean keepPortable); - - JNIEXPORT void JNICALL JniFutureByteResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr, - jint res); - JNIEXPORT void JNICALL JniFutureBoolResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr, - jint res); - JNIEXPORT void JNICALL JniFutureShortResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr, - jint res); - JNIEXPORT void JNICALL JniFutureCharResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr, - jint res); - JNIEXPORT void JNICALL JniFutureIntResult(JNIEnv* env, jclass cls, jlong envPtr, - jlong futPtr, jint res); - JNIEXPORT void JNICALL JniFutureFloatResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr, - jfloat res); - JNIEXPORT void JNICALL JniFutureLongResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr, - jlong res); - JNIEXPORT void JNICALL JniFutureDoubleResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr, - jdouble res); - JNIEXPORT void JNICALL JniFutureObjectResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr, - jlong memPtr); - JNIEXPORT void JNICALL JniFutureNullResult(JNIEnv* env, jclass cls, - jlong envPtr, jlong futPtr); - JNIEXPORT void JNICALL JniFutureError(JNIEnv* env, jclass cls, jlong envPtr, - jlong futPtr, jlong memPtr); - - JNIEXPORT void JNICALL JniLifecycleEvent(JNIEnv* env, jclass cls, jlong envPtr, - jlong ptr, jint evt); - - JNIEXPORT void JNICALL JniMemoryReallocate(JNIEnv* env, jclass cls, - jlong envPtr, jlong memPtr, - jint cap); - - JNIEXPORT jlong JNICALL JniMessagingFilterCreate(JNIEnv* env, jclass cls, - jlong envPtr, jlong memPtr); - JNIEXPORT jint JNICALL JniMessagingFilterApply(JNIEnv* env, jclass cls, - jlong envPtr, jlong ptr, - jlong memPtr); - JNIEXPORT void JNICALL JniMessagingFilterDestroy(JNIEnv* env, jclass cls, - jlong envPtr, jlong ptr); - - JNIEXPORT jlong JNICALL JniEventFilterCreate(JNIEnv* env, jclass cls, - jlong envPtr, jlong memPtr); - JNIEXPORT jint JNICALL JniEventFilterApply(JNIEnv* env, jclass cls, - jlong envPtr, jlong ptr, - jlong memPtr); - JNIEXPORT void JNICALL JniEventFilterDestroy(JNIEnv* env, jclass cls, - jlong envPtr, jlong ptr); - - JNIEXPORT jlong JNICALL JniServiceInit(JNIEnv* env, jclass cls, jlong envPtr, - jlong memPtr); - JNIEXPORT void JNICALL JniServiceExecute(JNIEnv* env, jclass cls, jlong envPtr, - jlong svcPtr, jlong memPtr); - JNIEXPORT void JNICALL JniServiceCancel(JNIEnv* env, jclass cls, jlong envPtr, - jlong svcPtr, jlong memPtr); - JNIEXPORT void JNICALL JniServiceInvokeMethod(JNIEnv* env, jclass cls, - jlong envPtr, jlong svcPtr, - jlong inMemPtr, jlong outMemPtr); - JNIEXPORT jint JNICALL JniClusterNodeFilterApply(JNIEnv* env, jclass cls, - jlong envPtr, jlong memPtr); - - JNIEXPORT jlong JNICALL JniNodeInfo(JNIEnv* env, jclass cls, jlong envPtr, - jlong memPtr); - - JNIEXPORT void JNICALL JniOnStart(JNIEnv* env, jclass cls, jlong envPtr, - jobject proc, jlong memPtr); - JNIEXPORT void JNICALL JniOnStop(JNIEnv* env, jclass cls, jlong envPtr); - - JNIEXPORT jlong JNICALL JniExtensionCallbackInLongOutLong(JNIEnv* env, - jclass cls, - jlong envPtr, - jint typ, jlong arg1); - JNIEXPORT jlong JNICALL JniExtensionCallbackInLongLongOutLong( - JNIEnv* env, jclass cls, jlong envPtr, jint typ, jlong arg1, jlong arg2); - - JNIEXPORT void JNICALL JniOnClientDisconnected(JNIEnv* env, jclass cls, - jlong envPtr); - JNIEXPORT void JNICALL JniOnClientReconnected(JNIEnv* env, jclass cls, - jlong envPtr, - jboolean clusterRestarted); - - JNIEXPORT jlong JNICALL JniAffinityFunctionInit(JNIEnv* env, jclass cls, - jlong envPtr, jlong memPtr, - jobject baseFunc); - JNIEXPORT jint JNICALL JniAffinityFunctionPartition(JNIEnv* env, jclass cls, - jlong envPtr, jlong ptr, - jlong memPtr); - JNIEXPORT void JNICALL - JniAffinityFunctionAssignPartitions(JNIEnv* env, jclass cls, jlong envPtr, - jlong ptr, jlong inMemPtr, jlong outMemPtr); - JNIEXPORT void JNICALL JniAffinityFunctionRemoveNode(JNIEnv* env, jclass cls, - jlong envPtr, jlong ptr, - jlong memPtr); - JNIEXPORT void JNICALL JniAffinityFunctionDestroy(JNIEnv* env, jclass cls, - jlong envPtr, jlong ptr); - - JNIEXPORT void JNICALL JniConsoleWrite(JNIEnv* env, jclass cls, jstring str, - jboolean isErr); - - JNIEXPORT void JNICALL JniLoggerLog(JNIEnv* env, jclass cls, jlong envPtr, - jint level, jstring message, - jstring category, jstring errorInfo, - jlong memPtr); - JNIEXPORT jboolean JNICALL JniLoggerIsLevelEnabled(JNIEnv* env, jclass cls, - jlong envPtr, jint level); - - JNIEXPORT jlong JNICALL JniInLongOutLong(JNIEnv* env, jclass cls, jlong envPtr, - jint type, jlong val); - JNIEXPORT jlong JNICALL JniInLongLongLongObjectOutLong(JNIEnv* env, jclass cls, - jlong envPtr, jint type, - jlong val1, jlong val2, - jlong val3, jobject arg); - } // namespace java - } // namespace jni - } // namespace odbc -} // namespace ignite - -#endif //_IGNITE_ODBC_JNI_JAVA diff --git a/src/odbc/include/ignite/odbc/jni/utils.h b/src/odbc/include/ignite/odbc/jni/utils.h deleted file mode 100644 index 508a40756..000000000 --- a/src/odbc/include/ignite/odbc/jni/utils.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _IGNITE_ODBC_JNI_UTILS -#define _IGNITE_ODBC_JNI_UTILS - -#include - -#include -#include -#include - -namespace ignite -{ - namespace odbc - { - namespace jni - { - /** - * Helper class to manage attached threads. - */ - class AttachHelper - { - public: - /** - * Destructor. - */ - ~AttachHelper(); - - /** - * Callback invoked on successful thread attach ot JVM. - */ - static void OnThreadAttach(); - }; - - /** - * Represents global reference to Java object. - */ - class IGNITE_IMPORT_EXPORT JavaGlobalRef - { - public: - /** - * Default constructor - */ - JavaGlobalRef() : - obj(NULL) - { - // No-op. - } - - /** - * Constructor - * - * @param ctx JNI context. - * @param obj Java object. - */ - JavaGlobalRef(common::concurrent::SharedPointer& ctx, jobject obj) - : obj(NULL) - { - Init(ctx, obj); - } - - /** - * Copy constructor - * - * @param other Other instance. - */ - JavaGlobalRef(const JavaGlobalRef& other) - : obj(NULL) - { - Init(other.ctx, other.obj); - } - - /** - * Assignment operator. - * - * @param other Other instance. - * @return *this. - */ - JavaGlobalRef& operator=(const JavaGlobalRef& other) - { - if (this != &other) - { - java::JniContext::Release(obj); - - Init(other.ctx, other.obj); - } - - return *this; - } - - /** - * Destructor. - */ - ~JavaGlobalRef() - { - java::JniContext::Release(obj); - } - - /** - * Get object. - * - * @return Object. - */ - jobject Get() - { - return obj; - } - - private: - /** Initializer */ - void Init(const common::concurrent::SharedPointer& ctx0, jobject obj0) { - ctx = ctx0; - - if (ctx.IsValid()) - this->obj = ctx.Get()->Acquire(obj0); - } - - /** Context. */ - common::concurrent::SharedPointer ctx; - - /** Object. */ - jobject obj; - }; - - /** - * Attempts to find JVM library to load it into the process later. - * First search is performed using the passed path argument (is not NULL). - * Then JRE_HOME is evaluated. Last, JAVA_HOME is evaluated. - * - * @param path Explicitly defined path (optional). - * @return Path to the file. Empty string if the library was not found. - */ - IGNITE_IMPORT_EXPORT std::string FindJvmLibrary(const std::string& path); - - /** - * Load JVM library into the process. - * - * @param path Optional path to the library. - * @return Whether load was successful. - */ - IGNITE_IMPORT_EXPORT bool LoadJvmLibrary(const std::string& path); - - /** - * Helper function to create classpath based on Ignite home directory. - * - * @param home Home directory; expected to be valid. - * @param forceTest Force test classpath. - * @return Classpath. - */ - IGNITE_IMPORT_EXPORT std::string CreateDocumentDbHomeClasspath(const std::string& home, bool forceTest); - - /** - * Create Ignite classpath based on user input and home directory. - * - * @param usrCp User's classpath. - * @param home Ignite home directory. - * @return Classpath. - */ - IGNITE_IMPORT_EXPORT std::string CreateDocumentDbClasspath(const std::string& usrCp, const std::string& home); - - /** - * Resolve DOCUMENTDB_HOME directory. Resolution is performed in several - * steps: - * 1) Check for path provided as argument. - * 2) Check for environment variable. - * 3) Check for current working directory. - * Result of these checks are evaluated based on existence of certain - * predefined folders inside possible Ignite home. If they are found, - * IGNITE_HOME is considered resolved. - * - * @param path Optional path to evaluate. - * @return Resolved Ignite home. - */ - IGNITE_IMPORT_EXPORT std::string ResolveDocumentDbHome(const std::string& path = ""); - } - } -} - -#endif //_IGNITE_ODBC_JNI_UTILS diff --git a/src/odbc/include/ignite/odbc/log.h b/src/odbc/include/ignite/odbc/log.h index 2e361ea20..5a6dafcb9 100644 --- a/src/odbc/include/ignite/odbc/log.h +++ b/src/odbc/include/ignite/odbc/log.h @@ -22,8 +22,8 @@ #include #include -#include "ignite/odbc/common/common.h" -#include "ignite/odbc/common/concurrent.h" +#include "ignite/common/common.h" +#include "ignite/common/concurrent.h" # define LOG_MSG(param) \ if (ignite::odbc::Logger* p = ignite::odbc::Logger::Get()) \ @@ -112,7 +112,7 @@ namespace ignite IGNITE_NO_COPY_ASSIGNMENT(Logger); /** Mutex for writes synchronization. */ - odbc::common::concurrent::CriticalSection mutex; + ignite::common::concurrent::CriticalSection mutex; /** File stream. */ std::ofstream stream; diff --git a/src/odbc/include/ignite/odbc/meta/column_meta.h b/src/odbc/include/ignite/odbc/meta/column_meta.h index d38ed2b9c..5144fa3b8 100644 --- a/src/odbc/include/ignite/odbc/meta/column_meta.h +++ b/src/odbc/include/ignite/odbc/meta/column_meta.h @@ -75,7 +75,7 @@ namespace ignite /** * Default constructor. */ - ColumnMeta() : dataType(), nullability(), precision(), scale() + ColumnMeta() { // No-op. } diff --git a/src/odbc/include/ignite/odbc/meta/primary_key_meta.h b/src/odbc/include/ignite/odbc/meta/primary_key_meta.h index 1cb69f741..a2f531863 100644 --- a/src/odbc/include/ignite/odbc/meta/primary_key_meta.h +++ b/src/odbc/include/ignite/odbc/meta/primary_key_meta.h @@ -40,7 +40,7 @@ namespace ignite /** * Default constructor. */ - PrimaryKeyMeta() : keySeq(0) + PrimaryKeyMeta() { // No-op. } diff --git a/src/odbc/include/ignite/odbc/odbc_error.h b/src/odbc/include/ignite/odbc/odbc_error.h index 07664329d..9b3b48d4f 100644 --- a/src/odbc/include/ignite/odbc/odbc_error.h +++ b/src/odbc/include/ignite/odbc/odbc_error.h @@ -21,7 +21,7 @@ #include #include -#include +#include namespace ignite { @@ -102,13 +102,13 @@ namespace ignite std::string errMessage; }; - typedef odbc::common::Unexpected OdbcUnexpected; + typedef common::Unexpected OdbcUnexpected; /** * Expected specialization for OdbcError. */ template - struct OdbcExpected : odbc::common::Expected + struct OdbcExpected : common::Expected { OdbcExpected(const R& res) : common::Expected(res) diff --git a/src/odbc/include/ignite/odbc/utility.h b/src/odbc/include/ignite/odbc/utility.h index cf31de0d6..152da6635 100644 --- a/src/odbc/include/ignite/odbc/utility.h +++ b/src/odbc/include/ignite/odbc/utility.h @@ -26,8 +26,8 @@ #include -#include -#include +#include +#include #include "ignite/impl/binary/binary_reader_impl.h" #include "ignite/impl/binary/binary_writer_impl.h" @@ -83,7 +83,7 @@ namespace ignite * @param reader Reader. * @param decimal Decimal value. */ - void ReadDecimal(impl::binary::BinaryReaderImpl& reader, odbc::common::Decimal& decimal); + void ReadDecimal(impl::binary::BinaryReaderImpl& reader, common::Decimal& decimal); /** * Write decimal value using writer. @@ -91,7 +91,7 @@ namespace ignite * @param writer Writer. * @param decimal Decimal value. */ - void WriteDecimal(impl::binary::BinaryWriterImpl& writer, const odbc::common::Decimal& decimal); + void WriteDecimal(impl::binary::BinaryWriterImpl& writer, const common::Decimal& decimal); /** * Convert SQL string buffer to std::string. diff --git a/src/odbc/install/install_amd64.cmd b/src/odbc/install/install_amd64.cmd index 5795e0cf8..6c7de9393 100644 --- a/src/odbc/install/install_amd64.cmd +++ b/src/odbc/install/install_amd64.cmd @@ -29,7 +29,7 @@ if exist %ODBC_AMD64% ( if [%ODBC_X86%] == [] ( echo warning: 32-bit driver is not specified. If you want to install 32-bit driver please specify path to it as a second argument. pause - exit /b 0 + exit /b 1 ) if exist %ODBC_X86% ( @@ -44,6 +44,5 @@ if exist %ODBC_X86% ( reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI\ODBC Drivers" /v "Apache Ignite" /t REG_SZ /d "Installed" /f ) else ( echo warning: 32-bit driver can not be found: %ODBC_X86% - exit /b 1 ) diff --git a/src/odbc/os/linux/include/ignite/odbc/common/common.h b/src/odbc/os/linux/include/ignite/odbc/common/common.h deleted file mode 100644 index 5e3924c3a..000000000 --- a/src/odbc/os/linux/include/ignite/odbc/common/common.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IGNITE_ODBC_COMMON_COMMON -#define _IGNITE_ODBC_COMMON_COMMON - -#ifndef __has_attribute -# define __has_attribute(x) 0 -#endif - -#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) -# define IGNITE_EXPORT __attribute__((visibility("default"))) -# define IGNITE_IMPORT __attribute__((visibility("default"))) -#else -# define IGNITE_EXPORT -# define IGNITE_IMPORT -#endif - -#define IGNITE_CALL - -#ifdef IGNITE_IMPL -# define IGNITE_IMPORT_EXPORT IGNITE_EXPORT -#else -# define IGNITE_IMPORT_EXPORT IGNITE_IMPORT -#endif - -#if (__cplusplus >= 201103L) -# define IGNITE_NO_THROW noexcept -#else -# define IGNITE_NO_THROW throw() -#endif - -#define IGNITE_UNUSED(x) ((void) x) - -/** - * Common construction to disable copy constructor and assignment for class. - */ -#define IGNITE_NO_COPY_ASSIGNMENT(cls) \ - cls(const cls& src); \ - cls& operator= (const cls& other) - -#endif //_IGNITE_ODBC_COMMON_COMMON diff --git a/src/odbc/os/linux/include/ignite/odbc/common/concurrent_os.h b/src/odbc/os/linux/include/ignite/odbc/common/concurrent_os.h deleted file mode 100644 index 74711337b..000000000 --- a/src/odbc/os/linux/include/ignite/odbc/common/concurrent_os.h +++ /dev/null @@ -1,701 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IGNITE_ODBC_COMMON_CONCURRENT_OS -#define _IGNITE_ODBC_COMMON_CONCURRENT_OS - -#include -#include -#include - -#include - -#include -#include - -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace concurrent - { - /** - * Static class to manage memory visibility semantics. - */ - class IGNITE_IMPORT_EXPORT Memory { - public: - /** - * Full fence. - */ - static void Fence(); - }; - - /** - * Critical section. - */ - class IGNITE_IMPORT_EXPORT CriticalSection - { - friend class ConditionVariable; - public: - /** - * Constructor. - */ - CriticalSection(); - - /** - * Destructor. - */ - ~CriticalSection(); - - /** - * Enter critical section. - */ - void Enter(); - - /** - * Leave critical section. - */ - void Leave(); - private: - pthread_mutex_t mux; - - IGNITE_NO_COPY_ASSIGNMENT(CriticalSection); - }; - - class IGNITE_IMPORT_EXPORT ReadWriteLock - { - public: - /** - * Constructor. - */ - ReadWriteLock(); - - /** - * Destructor. - */ - ~ReadWriteLock(); - - /** - * Lock in exclusive mode. - */ - void LockExclusive(); - - /** - * Release in exclusive mode. - */ - void ReleaseExclusive(); - - /** - * Lock in shared mode. - */ - void LockShared(); - - /** - * Release in shared mode. - */ - void ReleaseShared(); - - private: - /** Lock. */ - pthread_rwlock_t lock; - - IGNITE_NO_COPY_ASSIGNMENT(ReadWriteLock); - }; - - /** - * Special latch with count = 1. - */ - class IGNITE_IMPORT_EXPORT SingleLatch - { - public: - /** - * Constructor. - */ - SingleLatch(); - - /** - * Destructor. - */ - ~SingleLatch(); - - /** - * Perform the countdown. - */ - void CountDown(); - - /** - * Await the countdown. - */ - void Await(); - private: - /** Mutex. */ - pthread_mutex_t mux; - - /** Condition. */ - pthread_cond_t cond; - - /** Ready flag. */ - bool ready; - - IGNITE_NO_COPY_ASSIGNMENT(SingleLatch); - }; - - /** - * Primitives for atomic access. - */ - class IGNITE_IMPORT_EXPORT Atomics - { - public: - /** - * Update the 32-bit integer value if it is equal to expected value. - * - * @param ptr Pointer. - * @param expVal Expected value. - * @param newVal New value. - * @return True if update occurred as a result of this call, false otherwise. - */ - static bool CompareAndSet32(int32_t* ptr, int32_t expVal, int32_t newVal); - - /** - * Update the 32-bit integer value if it is equal to expected value. - * - * @param ptr Pointer. - * @param expVal Expected value. - * @param newVal New value. - * @return Value which were observed during CAS attempt. - */ - static int32_t CompareAndSet32Val(int32_t* ptr, int32_t expVal, int32_t newVal); - - /** - * Increment 32-bit integer and return new value. - * - * @param ptr Pointer. - * @return Value after increment. - */ - static int32_t IncrementAndGet32(int32_t* ptr); - - /** - * Decrement 32-bit integer and return new value. - * - * @param ptr Pointer. - * @return Value after decrement. - */ - static int32_t DecrementAndGet32(int32_t* ptr); - - /** - * Update the 64-bit integer value if it is equal to expected value. - * - * @param ptr Pointer. - * @param expVal Expected value. - * @param newVal New value. - * @return True if update occurred as a result of this call, false otherwise. - */ - static bool CompareAndSet64(int64_t* ptr, int64_t expVal, int64_t newVal); - - /** - * Update the 64-bit integer value if it is equal to expected value. - * - * @param ptr Pointer. - * @param expVal Expected value. - * @param newVal New value. - * @return Value which were observed during CAS attempt. - */ - static int64_t CompareAndSet64Val(int64_t* ptr, int64_t expVal, int64_t newVal); - - /** - * Increment 64-bit integer and return new value. - * - * @param ptr Pointer. - * @return Value after increment. - */ - static int64_t IncrementAndGet64(int64_t* ptr); - - /** - * Decrement 64-bit integer and return new value. - * - * @param ptr Pointer. - * @return Value after decrement. - */ - static int64_t DecrementAndGet64(int64_t* ptr); - }; - - /** - * Thread-local entry. - */ - class IGNITE_IMPORT_EXPORT ThreadLocalEntry - { - public: - /** - * Virtual destructor to allow for correct typed entries cleanup. - */ - virtual ~ThreadLocalEntry() - { - // No-op. - } - }; - - /** - * Typed thread-local entry. - */ - template - class IGNITE_IMPORT_EXPORT ThreadLocalTypedEntry : public ThreadLocalEntry - { - public: - /** - * Constructor. - * - * @param val Value. - */ - ThreadLocalTypedEntry(T val) : val(val) - { - // No-op. - } - - ~ThreadLocalTypedEntry() - { - // No-op. - } - - /** - * Get value. - * - * @return Value. - */ - T Get() - { - return val; - } - private: - /** Value. */ - T val; - }; - - /** - * Thread-local abstraction. - */ - class IGNITE_IMPORT_EXPORT ThreadLocal - { - public: - /** - * Get next available index to be used in thread-local storage. - * - * @return Index. - */ - static int32_t NextIndex(); - - /** - * Get value by index. - * - * @param idx Index. - * @return Value associated with the index or NULL. - */ - template - static T Get(int32_t idx) - { - void* linuxVal = Get0(); - - if (linuxVal) - { - std::map* map = - static_cast*>(linuxVal); - - ThreadLocalTypedEntry* entry = static_cast*>((*map)[idx]); - - if (entry) - return entry->Get(); - } - - return T(); - } - - /** - * Set value at the given index. - * - * @param idx Index. - * @param val Value to be associated with the index. - */ - template - static void Set(int32_t idx, const T& val) - { - void* linuxVal = Get0(); - - if (linuxVal) - { - std::map* map = - static_cast*>(linuxVal); - - ThreadLocalEntry* appVal = (*map)[idx]; - - if (appVal) - delete appVal; - - (*map)[idx] = new ThreadLocalTypedEntry(val); - } - else - { - std::map* map = new std::map(); - - Set0(map); - - (*map)[idx] = new ThreadLocalTypedEntry(val); - } - } - - /** - * Remove value at the given index. - * - * @param idx Index. - */ - static void Remove(int32_t idx); - - /** - * Internal thread-local map clear routine. - * - * @param mapPtr Pointer to map. - */ - static void Clear0(void* mapPtr); - - private: - /** - * Internal get routine. - * - * @param Associated value. - */ - static void* Get0(); - - /** - * Internal set routine. - * - * @param ptr Pointer. - */ - static void Set0(void* ptr); - }; - - /** - * Thread-local instance. Simplifies API avoiding direct index allocations. - */ - template - class IGNITE_IMPORT_EXPORT ThreadLocalInstance - { - public: - /** - * Constructor. - */ - ThreadLocalInstance() : idx(ThreadLocal::NextIndex()) - { - // No-op. - } - - /** - * Destructor. - */ - ~ThreadLocalInstance() - { - Remove(); - } - - /** - * Get value. - * - * @return Value. - */ - T Get() - { - return ThreadLocal::Get(idx); - } - - /** - * Set instance. - * - * @param val Value. - */ - void Set(const T& val) - { - ThreadLocal::Set(idx, val); - } - - /** - * Remove instance. - */ - void Remove() - { - ThreadLocal::Remove(idx); - } - - private: - /** Index. */ - int32_t idx; - }; - - /** - * Cross-platform wrapper for Condition Variable synchronization - * primitive concept. - */ - class ConditionVariable - { - public: - /** - * Constructor. - */ - ConditionVariable() - { - pthread_condattr_t attr; - int err = pthread_condattr_init(&attr); - assert(!err); - IGNITE_UNUSED(err); - - #if !defined(__APPLE__) - err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); - assert(!err); - IGNITE_UNUSED(err); - #endif - err = pthread_cond_init(&cond, &attr); - assert(!err); - IGNITE_UNUSED(err); - } - - /** - * Destructor. - */ - ~ConditionVariable() - { - pthread_cond_destroy(&cond); - } - - /** - * Wait for Condition Variable to be notified. - * - * @param cs Critical section in which to wait. - */ - void Wait(CriticalSection& cs) - { - pthread_cond_wait(&cond, &cs.mux); - } - - /** - * Wait for Condition Variable to be notified for specified time. - * - * @param cs Critical section in which to wait. - * @param msTimeout Timeout in milliseconds. - * @return True if the object has been notified and false in case of timeout. - */ - bool WaitFor(CriticalSection& cs, int32_t msTimeout) - { - timespec ts; - int err = clock_gettime(CLOCK_MONOTONIC, &ts); - assert(!err); - - IGNITE_UNUSED(err); - - ts.tv_sec += msTimeout / 1000 + (ts.tv_nsec + (msTimeout % 1000) * 1000000) / 1000000000; - ts.tv_nsec = (ts.tv_nsec + (msTimeout % 1000) * 1000000) % 1000000000; - - int res = pthread_cond_timedwait(&cond, &cs.mux, &ts); - - return res == 0; - } - - /** - * Notify single thread waiting for the condition variable. - */ - void NotifyOne() - { - int err = pthread_cond_signal(&cond); - - assert(!err); - - IGNITE_UNUSED(err); - } - - /** - * Notify all threads that are waiting on the variable. - */ - void NotifyAll() - { - int err = pthread_cond_broadcast(&cond); - - assert(!err); - - IGNITE_UNUSED(err); - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(ConditionVariable); - - /** OS-specific type. */ - pthread_cond_t cond; - }; - - /** - * Manually triggered event. - * Once triggered it stays in passing state until manually reset. - */ - class ManualEvent - { - public: - /** - * Constructs manual event. - * Initial state is untriggered. - */ - ManualEvent() : - cond(), - mutex(), - state(false) - { - pthread_condattr_t attr; - int err = pthread_condattr_init(&attr); - assert(!err); - IGNITE_UNUSED(err); - - #if !defined(__APPLE__) - err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); - assert(!err); - IGNITE_UNUSED(err); - #endif - - err = pthread_cond_init(&cond, &attr); - assert(!err); - IGNITE_UNUSED(err); - - err = pthread_mutex_init(&mutex, NULL); - assert(!err); - IGNITE_UNUSED(err); - } - - /** - * Destructor. - */ - ~ManualEvent() - { - pthread_mutex_destroy(&mutex); - pthread_cond_destroy(&cond); - } - - /** - * Sets event into triggered state. - */ - void Set() - { - int err = pthread_mutex_lock(&mutex); - assert(!err); - IGNITE_UNUSED(err); - - state = true; - - err = pthread_cond_broadcast(&cond); - assert(!err); - IGNITE_UNUSED(err); - - err = pthread_mutex_unlock(&mutex); - assert(!err); - IGNITE_UNUSED(err); - } - - /** - * Resets event into non-triggered state. - */ - void Reset() - { - int err = pthread_mutex_lock(&mutex); - assert(!err); - IGNITE_UNUSED(err); - - state = false; - - err = pthread_mutex_unlock(&mutex); - assert(!err); - IGNITE_UNUSED(err); - } - - /** - * Wait for event to be triggered. - */ - void Wait() - { - int err = pthread_mutex_lock(&mutex); - assert(!err); - IGNITE_UNUSED(err); - - while (!state) - { - err = pthread_cond_wait(&cond, &mutex); - assert(!err); - IGNITE_UNUSED(err); - } - - err = pthread_mutex_unlock(&mutex); - assert(!err); - IGNITE_UNUSED(err); - } - - /** - * Wait for event to be triggered for specified time. - * - * @param msTimeout Timeout in milliseconds. - * @return True if the object has been triggered and false in case of timeout. - */ - bool WaitFor(int32_t msTimeout) - { - int res = 0; - int err = pthread_mutex_lock(&mutex); - assert(!err); - IGNITE_UNUSED(err); - - if (!state) - { - timespec ts; - err = clock_gettime(CLOCK_MONOTONIC, &ts); - assert(!err); - IGNITE_UNUSED(err); - - ts.tv_sec += msTimeout / 1000 + (ts.tv_nsec + (msTimeout % 1000) * 1000000) / 1000000000; - ts.tv_nsec = (ts.tv_nsec + (msTimeout % 1000) * 1000000) % 1000000000; - - res = pthread_cond_timedwait(&cond, &mutex, &ts); - assert(res == 0 || res == ETIMEDOUT); - IGNITE_UNUSED(res); - } - - err = pthread_mutex_unlock(&mutex); - assert(!err); - IGNITE_UNUSED(err); - - return res == 0; - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(ManualEvent); - - /** Condition variable. */ - pthread_cond_t cond; - - /** Mutex. */ - pthread_mutex_t mutex; - - /** State. */ - bool state; - }; - } - } - } -} - -#endif // _IGNITE_ODBC_COMMON_CONCURRENT_OS diff --git a/src/odbc/os/linux/src/common/concurrent_os.cpp b/src/odbc/os/linux/src/common/concurrent_os.cpp deleted file mode 100644 index aa04e55c9..000000000 --- a/src/odbc/os/linux/src/common/concurrent_os.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ignite/odbc/common/concurrent_os.h" - -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace concurrent - { - /** Key indicating that the thread is attached. */ - static pthread_key_t tlsKey; - - /** Helper to ensure that attach key is allocated only once. */ - static pthread_once_t tlsKeyInit = PTHREAD_ONCE_INIT; - - /** - * Routine to destroy TLS key. - * - * @param key Key. - */ - void DestroyTlsKey(void* key) { - ThreadLocal::Clear0(key); - } - - /** - * Routine to allocate TLS key. - */ - void AllocateTlsKey() { - pthread_key_create(&tlsKey, DestroyTlsKey); - } - - void Memory::Fence() { - __asm__ volatile ("" ::: "memory"); - } - - CriticalSection::CriticalSection() { - pthread_mutex_init(&mux, NULL); - - Memory::Fence(); - } - - CriticalSection::~CriticalSection() { - Memory::Fence(); - - pthread_mutex_destroy(&mux); - } - - void CriticalSection::Enter() { - Memory::Fence(); - - pthread_mutex_lock(&mux); - } - - void CriticalSection::Leave() { - Memory::Fence(); - - pthread_mutex_unlock(&mux); - } - - ReadWriteLock::ReadWriteLock() : - lock() - { - pthread_rwlock_init(&lock, NULL); - - Memory::Fence(); - } - - ReadWriteLock::~ReadWriteLock() - { - pthread_rwlock_destroy(&lock); - } - - void ReadWriteLock::LockExclusive() - { - pthread_rwlock_wrlock(&lock); - } - - void ReadWriteLock::ReleaseExclusive() - { - pthread_rwlock_unlock(&lock); - } - - void ReadWriteLock::LockShared() - { - pthread_rwlock_rdlock(&lock); - } - - void ReadWriteLock::ReleaseShared() - { - pthread_rwlock_unlock(&lock); - } - - SingleLatch::SingleLatch() - { - pthread_mutex_init(&mux, NULL); - pthread_cond_init(&cond, NULL); - ready = false; - - Memory::Fence(); - } - - SingleLatch::~SingleLatch() - { - Memory::Fence(); - - pthread_cond_destroy(&cond); - pthread_mutex_destroy(&mux); - } - - void SingleLatch::CountDown() - { - pthread_mutex_lock(&mux); - - if (!ready) { - ready = true; - - pthread_cond_broadcast(&cond); - } - - pthread_mutex_unlock(&mux); - - Memory::Fence(); - } - - void SingleLatch::Await() - { - pthread_mutex_lock(&mux); - - while (!ready) - pthread_cond_wait(&cond, &mux); - - pthread_mutex_unlock(&mux); - - Memory::Fence(); - } - - bool Atomics::CompareAndSet32(int32_t* ptr, int32_t expVal, int32_t newVal) - { - return __sync_bool_compare_and_swap(ptr, expVal, newVal); - } - - int32_t Atomics::CompareAndSet32Val(int32_t* ptr, int32_t expVal, int32_t newVal) - { - return __sync_val_compare_and_swap(ptr, expVal, newVal); - } - - int32_t Atomics::IncrementAndGet32(int32_t* ptr) - { - return __sync_fetch_and_add(ptr, 1) + 1; - } - - int32_t Atomics::DecrementAndGet32(int32_t* ptr) - { - return __sync_fetch_and_sub(ptr, 1) - 1; - } - - bool Atomics::CompareAndSet64(int64_t* ptr, int64_t expVal, int64_t newVal) - { - return __sync_bool_compare_and_swap(ptr, expVal, newVal); - } - - int64_t Atomics::CompareAndSet64Val(int64_t* ptr, int64_t expVal, int64_t newVal) - { - return __sync_val_compare_and_swap(ptr, expVal, newVal); - } - - int64_t Atomics::IncrementAndGet64(int64_t* ptr) - { - return __sync_fetch_and_add(ptr, 1) + 1; - } - - int64_t Atomics::DecrementAndGet64(int64_t* ptr) - { - return __sync_fetch_and_sub(ptr, 1) - 1; - } - - void* ThreadLocal::Get0() - { - pthread_once(&tlsKeyInit, AllocateTlsKey); - - return pthread_getspecific(tlsKey); - } - - void ThreadLocal::Set0(void* ptr) - { - pthread_once(&tlsKeyInit, AllocateTlsKey); - - pthread_setspecific(tlsKey, ptr); - } - } - } - } -} diff --git a/src/odbc/os/linux/src/common/platform_utils.cpp b/src/odbc/os/linux/src/common/platform_utils.cpp deleted file mode 100644 index f0076598f..000000000 --- a/src/odbc/os/linux/src/common/platform_utils.cpp +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - time_t IgniteTimeGm(const tm& time) - { - tm tmc = time; - - return timegm(&tmc); - } - - time_t IgniteTimeLocal(const tm& time) - { - tm tmc = time; - - return mktime(&tmc); - } - - bool IgniteGmTime(time_t in, tm& out) - { - return gmtime_r(&in, &out) != NULL; - } - - bool IgniteLocalTime(time_t in, tm& out) - { - return localtime_r(&in, &out) == 0; - } - - std::string GetEnv(const std::string& name) - { - static const std::string empty; - - return GetEnv(name, empty); - } - - std::string GetEnv(const std::string& name, const std::string& dflt) - { - char* val0 = std::getenv(name.c_str()); - - if (!val0) - return dflt; - - return std::string(val0); - } - - bool FileExists(const std::string& path) - { - glob_t gs; - - int res = glob(path.c_str(), 0, 0, &gs); - - globfree(&gs); - - return res == 0; - } - - bool IsValidDirectory(const std::string& path) - { - if (path.empty()) - return false; - - struct stat pathStat; - - return stat(path.c_str(), &pathStat) != -1 && S_ISDIR(pathStat.st_mode); - } - - static int rmFiles(const char *pathname, const struct stat*, int, struct FTW*) - { - remove(pathname); - - return 0; - } - - bool DeletePath(const std::string& path) - { - return nftw(path.c_str(), rmFiles, 10, FTW_DEPTH | FTW_MOUNT | FTW_PHYS) == 0; - } - - StdCharOutStream& Fs(StdCharOutStream& ostr) - { - ostr.put('/'); - return ostr; - } - - StdCharOutStream& Dle(StdCharOutStream& ostr) - { - #ifdef __APPLE__ - static const char expansion[] = ".dylib"; - #else - static const char expansion[] = ".so"; - #endif - ostr.write(expansion, sizeof(expansion) - 1); - - return ostr; - } - - IGNITE_IMPORT_EXPORT unsigned GetRandSeed() - { - timespec ts; - - clock_gettime(CLOCK_MONOTONIC, &ts); - - unsigned res = static_cast(ts.tv_sec); - res ^= static_cast(ts.tv_nsec); - res ^= static_cast(getpid()); - - return res; - } - } - } -} diff --git a/src/odbc/os/win/include/ignite/odbc/common/common.h b/src/odbc/os/win/include/ignite/odbc/common/common.h deleted file mode 100644 index e7cda4b52..000000000 --- a/src/odbc/os/win/include/ignite/odbc/common/common.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _IGNITE_COMMON_COMMON -#define _IGNITE_COMMON_COMMON - -#define IGNITE_EXPORT __declspec(dllexport) -#define IGNITE_IMPORT __declspec(dllimport) -#define IGNITE_CALL __stdcall - -#define IGNITE_IMPORT_EXPORT IGNITE_EXPORT - -#include - -#define IGNITE_TRACE_ALLOC(addr) \ - std::cout << "ALLOC " << __FILE__ << "(" << __LINE__ << "): 0x" << (void*)addr << std::endl; - -/** - * Common construction to disable copy constructor and assignment for class. - */ -#define IGNITE_NO_COPY_ASSIGNMENT(cls) \ - cls(const cls& src); \ - cls& operator= (const cls& other); - -#if (__cplusplus >= 201103L) -# define IGNITE_NO_THROW noexcept -#else -# define IGNITE_NO_THROW throw() -#endif - -#define IGNITE_UNUSED(x) ((void) x) - -#endif //_IGNITE_COMMON_COMMON \ No newline at end of file diff --git a/src/odbc/os/win/include/ignite/odbc/common/concurrent_os.h b/src/odbc/os/win/include/ignite/odbc/common/concurrent_os.h deleted file mode 100644 index 855a995b6..000000000 --- a/src/odbc/os/win/include/ignite/odbc/common/concurrent_os.h +++ /dev/null @@ -1,610 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IGNITE_ODBC_COMMON_CONCURRENT_OS -#define _IGNITE_ODBC_COMMON_CONCURRENT_OS - -#include - -#include -#include - -#include - -#include "ignite/odbc/common/common.h" -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace concurrent - { - /** - * Static class to manage memory visibility semantics. - */ - class IGNITE_IMPORT_EXPORT Memory - { - public: - /** - * Full fence. - */ - static void Fence(); - }; - - /** - * Critical section. - */ - class IGNITE_IMPORT_EXPORT CriticalSection - { - friend class ConditionVariable; - public: - /** - * Constructor. - */ - CriticalSection(); - - /** - * Destructor. - */ - ~CriticalSection(); - - /** - * Enter critical section. - */ - void Enter(); - - /** - * Leave critical section. - */ - void Leave(); - private: - /** Handle. */ - CRITICAL_SECTION hnd; - - IGNITE_NO_COPY_ASSIGNMENT(CriticalSection) - }; - - class IGNITE_IMPORT_EXPORT ReadWriteLock - { - public: - /** - * Constructor. - */ - ReadWriteLock(); - - /** - * Destructor. - */ - ~ReadWriteLock(); - - /** - * Lock in exclusive mode. - */ - void LockExclusive(); - - /** - * Release in exclusive mode. - */ - void ReleaseExclusive(); - - /** - * Lock in shared mode. - */ - void LockShared(); - - /** - * Release in shared mode. - */ - void ReleaseShared(); - - private: - /** Lock. */ - SRWLOCK lock; - - IGNITE_NO_COPY_ASSIGNMENT(ReadWriteLock) - }; - - /** - * Special latch with count = 1. - */ - class IGNITE_IMPORT_EXPORT SingleLatch - { - public: - /** - * Constructor. - */ - SingleLatch(); - - /** - * Destructor. - */ - ~SingleLatch(); - - /** - * Perform the countdown. - */ - void CountDown(); - - /** - * Await the countdown. - */ - void Await(); - private: - /** Handle. */ - HANDLE hnd = CreateEvent(nullptr, TRUE, FALSE, nullptr); - - IGNITE_NO_COPY_ASSIGNMENT(SingleLatch) - }; - - /** - * Primitives for atomic access. - */ - class IGNITE_IMPORT_EXPORT Atomics - { - public: - /** - * Update the 32-bit integer value if it is equal to expected value. - * - * @param ptr Pointer. - * @param expVal Expected value. - * @param newVal New value. - * @return True if update occurred as a result of this call, false otherwise. - */ - static bool CompareAndSet32(int32_t* ptr, int32_t expVal, int32_t newVal); - - /** - * Update the 32-bit integer value if it is equal to expected value. - * - * @param ptr Pointer. - * @param expVal Expected value. - * @param newVal New value. - * @return Value which were observed during CAS attempt. - */ - static int32_t CompareAndSet32Val(int32_t* ptr, int32_t expVal, int32_t newVal); - - /** - * Increment 32-bit integer and return new value. - * - * @param ptr Pointer. - * @return Value after increment. - */ - static int32_t IncrementAndGet32(int32_t* ptr); - - /** - * Decrement 32-bit integer and return new value. - * - * @param ptr Pointer. - * @return Value after decrement. - */ - static int32_t DecrementAndGet32(int32_t* ptr); - - /** - * Update the 64-bit integer value if it is equal to expected value. - * - * @param ptr Pointer. - * @param expVal Expected value. - * @param newVal New value. - * @return True if update occurred as a result of this call, false otherwise. - */ - static bool CompareAndSet64(int64_t* ptr, int64_t expVal, int64_t newVal); - - /** - * Update the 64-bit integer value if it is equal to expected value. - * - * @param ptr Pointer. - * @param expVal Expected value. - * @param newVal New value. - * @return Value which were observed during CAS attempt. - */ - static int64_t CompareAndSet64Val(int64_t* ptr, int64_t expVal, int64_t newVal); - - /** - * Increment 64-bit integer and return new value. - * - * @param ptr Pointer. - * @return Value after increment. - */ - static int64_t IncrementAndGet64(int64_t* ptr); - - /** - * Decrement 64-bit integer and return new value. - * - * @param ptr Pointer. - * @return Value after decrement. - */ - static int64_t DecrementAndGet64(int64_t* ptr); - }; - - /** - * Thread-local entry. - */ - class IGNITE_IMPORT_EXPORT ThreadLocalEntry - { - public: - /** - * Virtual destructor to allow for correct typed entries cleanup. - */ - virtual ~ThreadLocalEntry() - { - // No-op. - } - }; - - /** - * Typed thread-local entry. - */ - template - class IGNITE_IMPORT_EXPORT ThreadLocalTypedEntry : public ThreadLocalEntry - { - public: - /** - * Constructor. - * - * @param val Value. - */ - ThreadLocalTypedEntry(T val) : val(val) - { - // No-op. - } - - ~ThreadLocalTypedEntry() - { - // No-op. - } - - /** - * Get value. - * - * @return Value. - */ - T Get() - { - return val; - } - private: - /** Value. */ - T val; - }; - - /** - * Thread-local abstraction. - */ - class IGNITE_IMPORT_EXPORT ThreadLocal - { - public: - /** - * Allocate thread-local index. Invoked once on DLL process attach. - * - * @return True if allocation was successful. - */ - static bool OnProcessAttach(); - - /** - * Release thread-local entry. Invoked on DLL thread detach. - */ - static void OnThreadDetach(); - - /** - * Release thread-local index. Invoked once on DLL process detach. - */ - static void OnProcessDetach(); - - /** - * Get next available index to be used in thread-local storage. - * - * @return Index. - */ - static int32_t NextIndex(); - - /** - * Get value by index. - * - * @param idx Index. - * @return Value associated with the index or NULL. - */ - template - static T Get(int32_t idx) - { - void* winVal = Get0(); - - if (winVal) - { - std::map* map = - static_cast*>(winVal); - - ThreadLocalTypedEntry* entry = static_cast*>((*map)[idx]); - - if (entry) - return entry->Get(); - } - - return T(); - } - - /** - * Set value at the given index. - * - * @param idx Index. - * @param val Value to be associated with the index. - */ - template - static void Set(int32_t idx, const T& val) - { - void* winVal = Get0(); - - if (winVal) - { - std::map* map = - static_cast*>(winVal); - - ThreadLocalEntry* appVal = (*map)[idx]; - - if (appVal) - delete appVal; - - (*map)[idx] = new ThreadLocalTypedEntry(val); - } - else - { - std::map* map = new std::map(); - - Set0(map); - - (*map)[idx] = new ThreadLocalTypedEntry(val); - } - } - - /** - * Remove value at the given index. - * - * @param idx Index. - */ - static void Remove(int32_t idx); - - private: - /** - * Internal get routine. - * - * @param Associated value. - */ - static void* Get0(); - - /** - * Internal set routine. - * - * @param ptr Pointer. - */ - static void Set0(void* ptr); - - /** - * Internal thread-local map clear routine. - * - * @param mapPtr Pointer to map. - */ - static void Clear0(void* mapPtr); - }; - - /** - * Thread-local instance. Simplifies API avoiding direct index allocations. - */ - template - class IGNITE_IMPORT_EXPORT ThreadLocalInstance - { - public: - /** - * Constructor. - */ - ThreadLocalInstance() : idx(ThreadLocal::NextIndex()) - { - // No-op. - } - - /** - * Destructor. - */ - ~ThreadLocalInstance() - { - Remove(); - } - - /** - * Get value. - * - * @return Value. - */ - T Get() - { - return ThreadLocal::Get(idx); - } - - /** - * Set instance. - * - * @param val Value. - */ - void Set(const T& val) - { - ThreadLocal::Set(idx, val); - } - - /** - * Remove instance. - */ - void Remove() - { - ThreadLocal::Remove(idx); - } - - private: - /** Index. */ - int32_t idx; - }; - - /** - * Cross-platform wrapper for Condition Variable synchronization - * primitive concept. - */ - class ConditionVariable - { - public: - /** - * Constructor. - */ - ConditionVariable() - { - InitializeConditionVariable(&cond); - } - - /** - * Destructor. - */ - ~ConditionVariable() - { - // No-op. - } - - /** - * Wait for Condition Variable to be notified. - * - * @param cs Critical section in which to wait. - */ - void Wait(CriticalSection& cs) - { - SleepConditionVariableCS(&cond, &cs.hnd, INFINITE); - } - - /** - * Wait for Condition Variable to be notified for specified time. - * - * @param cs Critical section in which to wait. - * @param msTimeout Timeout in milliseconds. - * @return True if the object has been notified and false in case of timeout. - */ - bool WaitFor(CriticalSection& cs, int32_t msTimeout) - { - BOOL notified = SleepConditionVariableCS(&cond, &cs.hnd, msTimeout); - - return notified != FALSE; - } - - /** - * Notify single thread waiting for the condition variable. - */ - void NotifyOne() - { - WakeConditionVariable(&cond); - } - - /** - * Notify all threads that are waiting on the variable. - */ - void NotifyAll() - { - WakeAllConditionVariable(&cond); - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(ConditionVariable); - - /** OS-specific type. */ - CONDITION_VARIABLE cond; - }; - - /** - * Manually triggered event. - * Once triggered it stays in passing state until manually reset. - */ - class ManualEvent - { - public: - /** - * Constructs manual event. - * Initial state is untriggered. - */ - ManualEvent() - { - handle = CreateEvent(NULL, TRUE, FALSE, NULL); - - assert(handle != NULL); - } - - /** - * Destructor. - */ - ~ManualEvent() - { - CloseHandle(handle); - } - - /** - * Sets event into triggered state. - */ - void Set() - { - BOOL success = SetEvent(handle); - - assert(success); - } - - /** - * Resets event into non-triggered state. - */ - void Reset() - { - BOOL success = ResetEvent(handle); - - assert(success); - } - - /** - * Wait for event to be triggered. - */ - void Wait() - { - DWORD res = WaitForSingleObject(handle, INFINITE); - - assert(res == WAIT_OBJECT_0); - } - - /** - * Wait for event to be triggered for specified time. - * - * @param msTimeout Timeout in milliseconds. - * @return True if the object has been triggered and false in case of timeout. - */ - bool WaitFor(int32_t msTimeout) - { - DWORD res = WaitForSingleObject(handle, static_cast(msTimeout)); - - assert(res == WAIT_OBJECT_0 || res == WAIT_TIMEOUT); - - return res == WAIT_OBJECT_0; - } - - private: - IGNITE_NO_COPY_ASSIGNMENT(ManualEvent); - - /** Event handle. */ - HANDLE handle; - }; - } - } - } -} - -#endif //_IGNITE_ODBC_COMMON_CONCURRENT_OS diff --git a/src/odbc/os/win/src/common/concurrent_os.cpp b/src/odbc/os/win/src/common/concurrent_os.cpp deleted file mode 100644 index 71f5587db..000000000 --- a/src/odbc/os/win/src/common/concurrent_os.cpp +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ignite/odbc/common/concurrent_os.h" - -#pragma intrinsic(_InterlockedCompareExchange64) - -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace concurrent - { - /** Thread-local index for Windows. */ - DWORD winTlsIdx; - - void Memory::Fence() { - MemoryBarrier(); - } - - CriticalSection::CriticalSection() : - hnd() - { - InitializeCriticalSection(&hnd); - - Memory::Fence(); - } - - CriticalSection::~CriticalSection() = default; - - void CriticalSection::Enter() - { - Memory::Fence(); - - EnterCriticalSection(&hnd); - } - - void CriticalSection::Leave() - { - Memory::Fence(); - - LeaveCriticalSection(&hnd); - } - - ReadWriteLock::ReadWriteLock() : - lock() - { - InitializeSRWLock(&lock); - - Memory::Fence(); - } - - ReadWriteLock::~ReadWriteLock() = default; - - void ReadWriteLock::LockExclusive() - { - AcquireSRWLockExclusive(&lock); - } - - void ReadWriteLock::ReleaseExclusive() - { - ReleaseSRWLockExclusive(&lock); - } - - void ReadWriteLock::LockShared() - { - AcquireSRWLockShared(&lock); - } - - void ReadWriteLock::ReleaseShared() - { - ReleaseSRWLockShared(&lock); - } - - SingleLatch::SingleLatch() - { - Memory::Fence(); - } - - SingleLatch::~SingleLatch() - { - Memory::Fence(); - - CloseHandle(hnd); - } - - void SingleLatch::CountDown() - { - SetEvent(hnd); - } - - void SingleLatch::Await() - { - WaitForSingleObject(hnd, INFINITE); - } - - bool Atomics::CompareAndSet32(int32_t* ptr, int32_t expVal, int32_t newVal) - { - return CompareAndSet32Val(ptr, expVal, newVal) == expVal; - } - - int32_t Atomics::CompareAndSet32Val(int32_t* ptr, int32_t expVal, int32_t newVal) - { - return InterlockedCompareExchange(reinterpret_cast(ptr), newVal, expVal); - } - - int32_t Atomics::IncrementAndGet32(int32_t* ptr) - { - return InterlockedIncrement(reinterpret_cast(ptr)); - } - - int32_t Atomics::DecrementAndGet32(int32_t* ptr) - { - return InterlockedDecrement(reinterpret_cast(ptr)); - } - - bool Atomics::CompareAndSet64(int64_t* ptr, int64_t expVal, int64_t newVal) - { - return CompareAndSet64Val(ptr, expVal, newVal) == expVal; - } - - int64_t Atomics::CompareAndSet64Val(int64_t* ptr, int64_t expVal, int64_t newVal) - { - return _InterlockedCompareExchange64(ptr, newVal, expVal); - } - - int64_t Atomics::IncrementAndGet64(int64_t* ptr) - { - #ifdef _WIN64 - return InterlockedIncrement64(ptr); - #else - while (true) - { - int64_t expVal = *ptr; - int64_t newVal = expVal + 1; - - if (CompareAndSet64(ptr, expVal, newVal)) - return newVal; - } - #endif - } - - int64_t Atomics::DecrementAndGet64(int64_t* ptr) - { - #ifdef _WIN64 - return InterlockedDecrement64(ptr); - #else - while (true) - { - int64_t expVal = *ptr; - int64_t newVal = expVal - 1; - - if (CompareAndSet64(ptr, expVal, newVal)) - return newVal; - } - #endif - } - - bool ThreadLocal::OnProcessAttach() - { - return (winTlsIdx = TlsAlloc()) != TLS_OUT_OF_INDEXES; - } - - void ThreadLocal::OnThreadDetach() - { - if (winTlsIdx != TLS_OUT_OF_INDEXES) - { - void* mapPtr = Get0(); - - Clear0(mapPtr); - } - } - - void ThreadLocal::OnProcessDetach() - { - if (winTlsIdx != TLS_OUT_OF_INDEXES) - TlsFree(winTlsIdx); - } - - void* ThreadLocal::Get0() - { - return TlsGetValue(winTlsIdx); - } - - void ThreadLocal::Set0(void* ptr) - { - TlsSetValue(winTlsIdx, ptr); - } - } - } - } -} diff --git a/src/odbc/os/win/src/common/platform_utils.cpp b/src/odbc/os/win/src/common/platform_utils.cpp deleted file mode 100644 index 35261fa0d..000000000 --- a/src/odbc/os/win/src/common/platform_utils.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include - -#include - -namespace ignite { - namespace odbc - { - namespace common - { - time_t IgniteTimeGm(const tm& time) - { - tm tmc = time; - - return _mkgmtime(&tmc); - } - - time_t IgniteTimeLocal(const tm& time) - { - tm tmc = time; - - return mktime(&tmc); - } - - bool IgniteGmTime(time_t in, tm& out) - { - return gmtime_s(&out, &in) == 0; - } - - bool IgniteLocalTime(time_t in, tm& out) - { - return localtime_s(&out, &in) == 0; - } - - std::string GetEnv(const std::string& name) - { - static const std::string empty; - - return GetEnv(name, empty); - } - - std::string GetEnv(const std::string& name, const std::string& dflt) - { - char res[32767]; - - DWORD envRes = GetEnvironmentVariableA(name.c_str(), res, sizeof(res) / sizeof(res[0])); - - if (envRes == 0 || envRes > sizeof(res)) - return dflt; - - return std::string(res, static_cast(envRes)); - } - - bool FileExists(const std::string& path) - { - WIN32_FIND_DATAA findres; - - HANDLE hnd = FindFirstFileA(path.c_str(), &findres); - - if (hnd == INVALID_HANDLE_VALUE) - return false; - - FindClose(hnd); - - return true; - } - - bool IsValidDirectory(const std::string& path) - { - if (path.empty()) - return false; - - DWORD attrs = GetFileAttributesA(path.c_str()); - - return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0; - } - - bool DeletePath(const std::string& path) - { - std::vector path0(path.begin(), path.end()); - path0.push_back('\0'); - path0.push_back('\0'); - - SHFILEOPSTRUCT fileop; - fileop.hwnd = nullptr; - fileop.wFunc = FO_DELETE; - fileop.pFrom = &path0[0]; - fileop.pTo = nullptr; - fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; - - fileop.fAnyOperationsAborted = FALSE; - fileop.lpszProgressTitle = nullptr; - fileop.hNameMappings = nullptr; - - int ret = SHFileOperation(&fileop); - - return ret == 0; - } - - StdCharOutStream& Fs(StdCharOutStream& ostr) - { - ostr.put('\\'); - return ostr; - } - - StdCharOutStream& Dle(StdCharOutStream& ostr) - { - static const char expansion[] = ".dll"; - - ostr.write(expansion, sizeof(expansion) - 1); - - return ostr; - } - - IGNITE_IMPORT_EXPORT unsigned GetRandSeed() - { - return static_cast(GetTickCount64() ^ GetCurrentProcessId()); - } - } - } -} diff --git a/src/odbc/os/win/src/system/ui/window.cpp b/src/odbc/os/win/src/system/ui/window.cpp index 8512bda8a..02d62e2d8 100644 --- a/src/odbc/os/win/src/system/ui/window.cpp +++ b/src/odbc/os/win/src/system/ui/window.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -#include +#include #include "ignite/odbc/system/ui/window.h" @@ -58,7 +58,7 @@ namespace ignite title(), handle(handle), created(false), - parent(nullptr) + parent(0) { // No-op. } @@ -88,7 +88,7 @@ namespace ignite posY, width, height, - parent ? parent->GetHandle() : nullptr, + parent ? parent->GetHandle() : NULL, reinterpret_cast(static_cast(id)), GetHInstance(), this @@ -125,7 +125,7 @@ namespace ignite if (handle) DestroyWindow(handle); - handle = nullptr; + handle = NULL; } void Window::GetText(std::string& text) const diff --git a/src/odbc/src/app/application_data_buffer.cpp b/src/odbc/src/app/application_data_buffer.cpp index f4977bb09..2942defc8 100644 --- a/src/odbc/src/app/application_data_buffer.cpp +++ b/src/odbc/src/app/application_data_buffer.cpp @@ -19,7 +19,7 @@ #include #include -#include "ignite/odbc/common/bits.h" +#include "ignite/common/bits.h" #include "ignite/impl/binary/binary_utils.h" diff --git a/src/odbc/src/common/big_integer.cpp b/src/odbc/src/common/big_integer.cpp deleted file mode 100644 index 3114a452f..000000000 --- a/src/odbc/src/common/big_integer.cpp +++ /dev/null @@ -1,866 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ignite/odbc/ignite_error.h" -#include "ignite/odbc/common/bits.h" -#include "ignite/odbc/common/big_integer.h" - -namespace ignite -{ - namespace odbc - { - namespace common - { - BigInteger::BigInteger() : - sign(1), - mag() - { - // No-op. - } - - BigInteger::BigInteger(int64_t val) : - sign(1), - mag() - { - AssignInt64(val); - } - - BigInteger::BigInteger(const char* val, int32_t len) : - sign(1), - mag() - { - AssignString(val, len); - } - - BigInteger::BigInteger(const BigInteger& other) : - sign(other.sign), - mag(other.mag) - { - // No-op. - } - - BigInteger::BigInteger(const int8_t* val, int32_t len, int32_t sign, bool bigEndian) : - sign(sign), - mag() - { - assert(val != 0); - assert(len >= 0); - assert(sign == 1 || sign == 0 || sign == -1); - - if (bigEndian) - { - int32_t firstNonZero = 0; - while (firstNonZero < len && val[firstNonZero] == 0) - ++firstNonZero; - - if (firstNonZero == len) - { - AssignInt64(0); - - return; - } - - int32_t intLength = (len - firstNonZero + 3) / 4; - - mag.Resize(intLength); - - int32_t b = len - 1; - - for (int32_t i = 0; i < intLength - 1; ++i) - { - mag[i] = (val[b] & 0xFFUL) - | ((val[b - 1] & 0xFFUL) << 8) - | ((val[b - 2] & 0xFFUL) << 16) - | ((val[b - 3] & 0xFFUL) << 24); - - b -= 4; - } - - int32_t bytesRemaining = b - firstNonZero + 1; - - assert(bytesRemaining > 0 && bytesRemaining <= 4); - - switch (bytesRemaining) - { - case 4: - mag[intLength - 1] |= (val[b - 3] & 0xFF) << 24; - // Fall-through. - - case 3: - mag[intLength - 1] |= (val[b - 2] & 0xFF) << 16; - // Fall-through. - - case 2: - mag[intLength - 1] |= (val[b - 1] & 0xFF) << 8; - // Fall-through. - - case 1: - mag[intLength - 1] |= val[b] & 0xFF; - // Fall-through. - - default: - break; - } - } - else - { - int32_t firstNonZero = len - 1; - - while (firstNonZero >= 0 && val[firstNonZero] == 0) - --firstNonZero; - - if (firstNonZero == -1) - { - AssignInt64(0); - - return; - } - - int32_t intLength = (firstNonZero + 4) / 4; - - mag.Resize(intLength); - - int32_t b = 0; - - for (int32_t i = 0; i < intLength - 1; ++i) - { - mag[i] = (val[b] & 0xFFUL) - | ((val[b + 1] & 0xFFUL) << 8) - | ((val[b + 2] & 0xFFUL) << 16) - | ((val[b + 3] & 0xFFUL) << 24); - - b += 4; - } - - int32_t bytesRemaining = firstNonZero - b + 1; - - assert(bytesRemaining > 0 && bytesRemaining <= 4); - - switch (bytesRemaining) - { - case 4: - mag[intLength - 1] |= (val[b + 3] & 0xFF) << 24; - // Fall-through. - - case 3: - mag[intLength - 1] |= (val[b + 2] & 0xFF) << 16; - // Fall-through. - - case 2: - mag[intLength - 1] |= (val[b + 1] & 0xFF) << 8; - // Fall-through. - - case 1: - mag[intLength - 1] |= val[b] & 0xFF; - // Fall-through. - - default: - break; - } - } - } - - BigInteger::BigInteger(MagArray &mag, int8_t sign) : - sign(sign), - mag() - { - this->mag.Swap(mag); - } - - BigInteger& BigInteger::operator=(const BigInteger& other) - { - Assign(other); - - return *this; - } - - void BigInteger::Assign(const BigInteger& val) - { - if (this != &val) - { - sign = val.sign; - mag = val.mag; - } - } - - void BigInteger::AssignInt64(int64_t val) - { - if (val < 0) - { - AssignUint64(static_cast(-val)); - - sign = -1; - } - else - AssignUint64(static_cast(val)); - } - - void BigInteger::AssignString(const char* val, int32_t len) - { - std::stringstream converter; - - converter.write(val, len); - - converter >> *this; - } - - void BigInteger::AssignUint64(uint64_t val) - { - sign = 1; - - if (val == 0) - { - mag.Clear(); - - return; - } - - uint32_t highWord = static_cast(val >> 32); - - if (highWord == 0) - mag.Resize(1); - else - { - mag.Resize(2); - mag[1] = highWord; - } - - mag[0] = static_cast(val); - } - - int8_t BigInteger::GetSign() const - { - return sign; - } - - void BigInteger::Swap(BigInteger& other) - { - using std::swap; - - swap(sign, other.sign); - mag.Swap(other.mag); - } - - const BigInteger::MagArray& BigInteger::GetMagnitude() const - { - return mag; - } - - uint32_t BigInteger::GetBitLength() const - { - if (mag.IsEmpty()) - return 0; - - int32_t res = bits::BitLengthU32(mag[mag.GetSize() - 1]); - - if (mag.GetSize() > 1) - res += (mag.GetSize() - 1) * 32; - - return res; - } - - int32_t BigInteger::GetPrecision() const - { - // See http://graphics.stanford.edu/~seander/bithacks.html - // for the details on the algorithm. - - if (mag.GetSize() == 0) - return 1; - - int32_t r = static_cast((( - static_cast(GetBitLength()) + 1) * 646456993) >> 31); - - BigInteger prec; - BigInteger::GetPowerOfTen(r, prec); - - return Compare(prec, true) < 0 ? r : r + 1; - } - - void BigInteger::MagnitudeToBytes(common::FixedSizeArray& buffer) const - { - int32_t bytesNum = static_cast((GetBitLength() + 7) / 8); - - if (bytesNum == 0) - { - buffer.Reset(1); - - return; - } - - buffer.Reset(bytesNum); - - int32_t i; - for (i = 0; i < mag.GetSize() - 1; ++i) - { - int32_t j = bytesNum - 1 - 4 * i; - - buffer[j] = static_cast(mag[i]); - buffer[j - 1] = static_cast(mag[i] >> 8); - buffer[j - 2] = static_cast(mag[i] >> 16); - buffer[j - 3] = static_cast(mag[i] >> 24); - } - - int32_t bytesRemaining = bytesNum - 4 * i; - - assert(bytesRemaining >= 0 && bytesRemaining <= 4); - - i = 0; - switch (bytesRemaining) - { - case 4: - buffer[i++] |= static_cast(mag[mag.GetSize() - 1] >> 24); - // Fall-through. - - case 3: - buffer[i++] |= static_cast(mag[mag.GetSize() - 1] >> 16); - // Fall-through. - - case 2: - buffer[i++] |= static_cast(mag[mag.GetSize() - 1] >> 8); - // Fall-through. - - case 1: - buffer[i++] |= static_cast(mag[mag.GetSize() - 1]); - // Fall-through. - - default: - break; - } - } - - void BigInteger::Pow(int32_t exp) - { - if (exp < 0) - { - AssignInt64(0); - - return; - } - - uint32_t bitsLen = GetBitLength(); - - if (!bitsLen) - return; - - if (bitsLen == 1) - { - if ((exp % 2 == 0) && sign < 0) - sign = -sign; - - return; - } - - BigInteger multiplicant(*this); - AssignInt64(1); - - int32_t mutExp = exp; - while (mutExp) - { - if (mutExp & 1) - Multiply(multiplicant, *this); - - mutExp >>= 1; - - if (mutExp) - multiplicant.Multiply(multiplicant, multiplicant); - } - } - - void BigInteger::Multiply(const BigInteger& other, BigInteger& res) const - { - MagArray resMag(mag.GetSize() + other.mag.GetSize()); - - resMag.Resize(mag.GetSize() + other.mag.GetSize()); - - for (int32_t i = 0; i < other.mag.GetSize(); ++i) - { - uint32_t carry = 0; - - for (int32_t j = 0; j < mag.GetSize(); ++j) - { - uint64_t product = static_cast(mag[j]) * other.mag[i] + - + resMag[i + j] + carry; - - resMag[i + j] = static_cast(product); - carry = static_cast(product >> 32); - } - - resMag[i + mag.GetSize()] = carry; - } - - res.mag.Swap(resMag); - res.sign = sign * other.sign; - - res.Normalize(); - } - - /** - * Shift magnitude left by the specified number of bits. - * - * @param in Input magnitude. - * @param len Magnitude length. - * @param out Output magnitude. Should be not shorter than the input - * magnitude. - * @param n Number of bits to shift to. - */ - void ShiftLeft(const uint32_t* in, int32_t len, uint32_t* out, unsigned n) - { - assert(n < 32); - - if (n == 0) - { - std::copy(in, in + len, out); - - return; - } - - for (int32_t i = len - 1; i > 0; --i) - out[i] = (in[i] << n) | (in[i - 1] >> (32 - n)); - - out[0] = in[0] << n; - } - - /** - * Shift magnitude right by the specified number of bits. - * - * @param in Input magnitude. - * @param len Magnitude length. - * @param out Output magnitude. Should be not shorter than the input - * magnitude. - * @param n Number of bits to shift to. - */ - void ShiftRight(const uint32_t* in, int32_t len, uint32_t* out, unsigned n) - { - assert(n < 32); - - if (n == 0) - { - std::copy(in, in + len, out); - - return; - } - - for (int32_t i = 0; i < len - 1; ++i) - out[i] = (in[i] >> n) | (in[i + 1] << (32 - n)); - - out[len - 1] = in[len - 1] >> n; - } - - /** - * Part of the division algorithm. Computes q - (a * x). - * - * @param q Minuend. - * @param a Multipliplier of the subtrahend. - * @param alen Length of the a. - * @param x Multipliplicand of the subtrahend. - * @return Carry. - */ - uint32_t MultiplyAndSubstruct(uint32_t* q, const uint32_t* a, int32_t alen, uint32_t x) - { - uint64_t carry = 0; - - for (int32_t i = 0; i < alen; ++i) - { - uint64_t product = a[i] * static_cast(x); - int64_t difference = q[i] - carry - (product & 0xFFFFFFFF); - - q[i] = static_cast(difference); - - // This will add one if difference is negative. - carry = (product >> 32) - (difference >> 32); - } - - return static_cast(carry); - } - - /** - * Add two magnitude arrays and return carry. - * - * @param res First addend. Result is placed here. Length of this addend - * should be equal or greater than len. - * @param addend Second addend. - * @param len Length of the second addend. - * @return Carry. - */ - uint32_t Add(uint32_t* res, const uint32_t* addend, int32_t len) - { - uint64_t carry = 0; - - for (int32_t i = 0; i < len; ++i) - { - uint64_t sum = static_cast(res[i]) + addend[i] + carry; - res[i] = static_cast(sum); - carry = sum >> 32; - } - - return static_cast(carry); - } - - /** - * Add single number to a magnitude array and return carry. - * - * @param res First addend. Result is placed here. Length of this addend - * should be equal or greater than len. - * @param len Length of the First addend. - * @param addend Second addend. - * @return Carry. - */ - uint32_t Add(uint32_t* res, int32_t len, uint32_t addend) - { - uint64_t carry = addend; - - for (int32_t i = 0; (i < len) && carry; ++i) - { - uint64_t sum = static_cast(res[i]) + carry; - res[i] = static_cast(sum); - carry = sum >> 32; - } - - return static_cast(carry); - } - - void BigInteger::Divide(const BigInteger& divisor, BigInteger& res) const - { - Divide(divisor, res, 0); - } - - void BigInteger::Divide(const BigInteger& divisor, BigInteger& res, BigInteger& rem) const - { - Divide(divisor, res, &rem); - } - - void BigInteger::Add(const uint32_t* addend, int32_t len) - { - if (mag.GetSize() < len) - { - mag.Reserve(len + 1); - - mag.Resize(len); - } - else - mag.Reserve(mag.GetSize() + 1); - - uint32_t carry = common::Add(mag.GetData(), addend, len); - - if (carry) - { - carry = common::Add(mag.GetData() + len, mag.GetSize() - len, carry); - - if (carry) - mag.PushBack(carry); - } - } - - void BigInteger::Add(uint64_t x) - { - if (x == 0) - return; - - if (IsZero()) - { - AssignUint64(x); - - return; - } - - uint32_t val[2]; - - val[0] = static_cast(x); - val[1] = static_cast(x >> 32); - - Add(val, val[1] ? 2 : 1); - } - - int32_t BigInteger::Compare(const BigInteger& other, bool ignoreSign) const - { - // What we should return if magnitude is greater. - int32_t mgt = 1; - - if (!ignoreSign) - { - if (sign != other.sign) - return sign > other.sign ? 1 : -1; - else - mgt = sign; - } - - if (mag.GetSize() != other.mag.GetSize()) - return mag.GetSize() > other.mag.GetSize() ? mgt : -mgt; - - for (int32_t i = mag.GetSize() - 1; i >= 0; --i) - { - if (mag[i] == other.mag[i]) - continue; - else if (mag[i] > other.mag[i]) - return mgt; - else - return -mgt; - } - - return 0; - } - - int64_t BigInteger::ToInt64() const - { - return (static_cast(GetMagInt(1)) << 32) | GetMagInt(0); - } - - void BigInteger::GetPowerOfTen(int32_t pow, BigInteger& res) - { - using namespace common; - - assert(pow >= 0); - - if (pow < bits::UINT64_MAX_PRECISION) - { - res.AssignUint64(bits::TenPowerU64(pow)); - - return; - } - - res.AssignInt64(10); - res.Pow(pow); - } - - uint32_t BigInteger::GetMagInt(int32_t n) const - { - assert(n >= 0); - - if (n >= mag.GetSize()) - return sign > 0 ? 0 : -1; - - return sign * mag[n]; - } - - void BigInteger::Divide(const BigInteger& divisor, BigInteger& res, BigInteger* rem) const - { - // Can't divide by zero. - if (divisor.mag.IsEmpty()) - throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, "Division by zero."); - - int32_t compRes = Compare(divisor, true); - - int8_t resSign = sign * divisor.sign; - - // The same magnitude. Result is [-]1 and remainder is zero. - if (compRes == 0) - { - res.AssignInt64(resSign); - - if (rem) - rem->AssignInt64(0); - - return; - } - - // Divisor is greater than this. Result is 0 and remainder is this. - if (compRes == -1) - { - // Order is important here! Copy to rem first to handle the case - // when &res == this. - if (rem) - rem->Assign(*this); - - res.AssignInt64(0); - - return; - } - - // If divisor is [-]1 result is [-]this and remainder is zero. - if (divisor.GetBitLength() == 1) - { - // Once again: order is important. - res.Assign(*this); - res.sign = sign * divisor.sign; - - if (rem) - rem->AssignInt64(0); - - return; - } - - // Trivial case. - if (mag.GetSize() <= 2) - { - uint64_t u = mag[0]; - uint64_t v = divisor.mag[0]; - - if (mag.GetSize() == 2) - u |= static_cast(mag[1]) << 32; - - if (divisor.mag.GetSize() == 2) - v |= static_cast(divisor.mag[1]) << 32; - - // Divisor can not be 1, or 0. - assert(v > 1); - - // It should also be less than dividend. - assert(v < u); - - // (u / v) is always fits into int64_t because abs(v) >= 2. - res.AssignInt64(resSign * static_cast(u / v)); - - // (u % v) is always fits into int64_t because (u > v) -> - // (u % v) < (u / 2). - if (rem) - rem->AssignInt64(resSign * static_cast(u % v)); - - return; - } - - // Using Knuth division algorithm D for common case. - - // Short aliases. - const MagArray& u = mag; - const MagArray& v = divisor.mag; - MagArray& q = res.mag; - int32_t ulen = u.GetSize(); - int32_t vlen = v.GetSize(); - - // First we need to normilize divisor. - MagArray nv; - nv.Resize(v.GetSize()); - - int32_t shift = bits::NumberOfLeadingZerosU32(v.Back()); - ShiftLeft(v.GetData(), vlen, nv.GetData(), shift); - - // Divisor is normilized. Now we need to normilize divident. - MagArray nu; - - // First find out what is the size of it. - if (bits::NumberOfLeadingZerosU32(u.Back()) >= shift) - { - // Everything is the same as with divisor. Just add leading zero. - nu.Resize(ulen + 1); - - ShiftLeft(u.GetData(), ulen, nu.GetData(), shift); - - assert((static_cast(u.Back()) >> (32 - shift)) == 0); - } - else - { - // We need one more byte here. Also adding leading zero. - nu.Resize(ulen + 2); - - ShiftLeft(u.GetData(), ulen, nu.GetData(), shift); - - nu[ulen] = u[ulen - 1] >> (32 - shift); - - assert(nu[ulen] != 0); - } - - assert(nu.Back() == 0); - - // Resizing resulting array. - q.Resize(ulen - vlen + 1); - - // Main loop - for (int32_t i = ulen - vlen; i >= 0; --i) - { - uint64_t base = bits::MakeU64(nu[i + vlen], nu[i + vlen - 1]); - - uint64_t qhat = base / nv[vlen - 1]; // Estimated quotient. - uint64_t rhat = base % nv[vlen - 1]; // A remainder. - - // Adjusting result if needed. - while (qhat > UINT32_MAX || - ((qhat * nv[vlen - 2]) > ((UINT32_MAX + static_cast(1)) * rhat + nu[i + vlen - 2]))) - { - --qhat; - rhat += nv[vlen - 1]; - - if (rhat > UINT32_MAX) - break; - } - - uint32_t qhat32 = static_cast(qhat); - - // Multiply and subtract. - uint32_t carry = MultiplyAndSubstruct(nu.GetData() + i, nv.GetData(), vlen, qhat32); - - int64_t difference = nu[i + vlen] - carry; - - nu[i + vlen] = static_cast(difference); - - if (difference < 0) - { - --qhat32; - carry = common::Add(nu.GetData() + i, nv.GetData(), vlen); - - assert(carry == 0); - } - - q[i] = qhat32; - } - - res.sign = resSign; - res.Normalize(); - - // If remainder is needed unnormolize it. - if (rem) - { - rem->sign = resSign; - rem->mag.Resize(vlen); - - ShiftRight(nu.GetData(), rem->mag.GetSize(), rem->mag.GetData(), shift); - - rem->Normalize(); - } - } - - void BigInteger::Normalize() - { - int32_t lastNonZero = mag.GetSize() - 1; - while (lastNonZero >= 0 && mag[lastNonZero] == 0) - --lastNonZero; - - mag.Resize(lastNonZero + 1); - } - - bool operator==(const BigInteger& val1, const BigInteger& val2) - { - return val1.Compare(val2) == 0; - } - - bool operator!=(const BigInteger& val1, const BigInteger& val2) - { - return val1.Compare(val2) != 0; - } - - bool operator<(const BigInteger& val1, const BigInteger& val2) - { - return val1.Compare(val2) < 0; - } - - bool operator<=(const BigInteger& val1, const BigInteger& val2) - { - return val1.Compare(val2) <= 0; - } - - bool operator>(const BigInteger& val1, const BigInteger& val2) - { - return val1.Compare(val2) > 0; - } - - bool operator>=(const BigInteger& val1, const BigInteger& val2) - { - return val1.Compare(val2) >= 0; - } - } - } -} - diff --git a/src/odbc/src/common/bits.cpp b/src/odbc/src/common/bits.cpp deleted file mode 100644 index a5c922a8b..000000000 --- a/src/odbc/src/common/bits.cpp +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "ignite/odbc/common/bits.h" - -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace bits - { - int32_t NumberOfTrailingZerosI32(int32_t i) - { - int32_t y; - - if (i == 0) return 32; - - int32_t n = 31; - - y = i << 16; - - if (y != 0) { - n = n - 16; - i = y; - } - - y = i << 8; - - if (y != 0) { - n = n - 8; - i = y; - } - - y = i << 4; - - if (y != 0) { - n = n - 4; - i = y; - } - - y = i << 2; - - if (y != 0) { - n = n - 2; - i = y; - } - - return n - static_cast(static_cast(i << 1) >> 31); - } - - int32_t NumberOfLeadingZerosI32(int32_t i) - { - return NumberOfLeadingZerosU32(static_cast(i)); - } - - int32_t NumberOfLeadingZerosU32(uint32_t i) - { - if (i == 0) - return 32; - - int32_t n = 1; - - if (i >> 16 == 0) { - n += 16; - i <<= 16; - } - - if (i >> 24 == 0) { - n += 8; - i <<= 8; - } - - if (i >> 28 == 0) { - n += 4; - i <<= 4; - } - - if (i >> 30 == 0) { - n += 2; - i <<= 2; - } - - return n - static_cast(i >> 31); - } - - int32_t NumberOfLeadingZerosI64(int64_t i) - { - return NumberOfLeadingZerosU64(static_cast(i)); - } - - int32_t NumberOfLeadingZerosU64(uint64_t i) - { - if (i == 0) - return 64; - - int32_t n = 1; - - uint32_t x = static_cast(i >> 32); - - if (x == 0) { - n += 32; - x = static_cast(i); - } - - if (x >> 16 == 0) { - n += 16; - x <<= 16; - } - - if (x >> 24 == 0) { - n += 8; - x <<= 8; - } - - if (x >> 28 == 0) { - n += 4; - x <<= 4; - } - - if (x >> 30 == 0) { - n += 2; - x <<= 2; - } - - n -= x >> 31; - - return n; - } - - int32_t BitCountI32(int32_t i) - { - uint32_t ui = static_cast(i); - - ui -= (ui >> 1) & 0x55555555; - ui = (ui & 0x33333333) + ((ui >> 2) & 0x33333333); - ui = (ui + (ui >> 4)) & 0x0f0f0f0f; - ui += ui >> 8; - ui += ui >> 16; - - return static_cast(ui & 0x3f); - } - - int32_t BitLengthI32(int32_t i) - { - return 32 - NumberOfLeadingZerosI32(i); - } - - int32_t BitLengthU32(uint32_t i) - { - return 32 - NumberOfLeadingZerosU32(i); - } - - int32_t GetCapasityForSize(int32_t size) - { - assert(size > 0); - - if (size <= 8) - return 8; - - int32_t bl = BitLengthI32(size); - - if (bl > 30) - return INT32_MAX; - - int32_t res = 1 << bl; - - return size > res ? res << 1 : res; - } - - int32_t DigitLength(uint64_t x) - { - // See http://graphics.stanford.edu/~seander/bithacks.html - // for the details on the algorithm. - - if (x < 10) - return 1; - - int32_t r = ((64 - NumberOfLeadingZerosU64(x) + 1) * 1233) >> 12; - - assert(r <= UINT64_MAX_PRECISION); - - return (r == UINT64_MAX_PRECISION || x < TenPowerU64(r)) ? r : r + 1; - } - - uint64_t TenPowerU64(int32_t n) - { - static const uint64_t TEN_POWERS_TABLE[UINT64_MAX_PRECISION] = { - 1U, // 0 / 10^0 - 10U, // 1 / 10^1 - 100U, // 2 / 10^2 - 1000U, // 3 / 10^3 - 10000U, // 4 / 10^4 - 100000U, // 5 / 10^5 - 1000000U, // 6 / 10^6 - 10000000U, // 7 / 10^7 - 100000000U, // 8 / 10^8 - 1000000000U, // 9 / 10^9 - 10000000000U, // 10 / 10^10 - 100000000000U, // 11 / 10^11 - 1000000000000U, // 12 / 10^12 - 10000000000000U, // 13 / 10^13 - 100000000000000U, // 14 / 10^14 - 1000000000000000U, // 15 / 10^15 - 10000000000000000U, // 16 / 10^16 - 100000000000000000U, // 17 / 10^17 - 1000000000000000000U, // 18 / 10^18 - 10000000000000000000U // 19 / 10^19 - }; - - assert(n >= 0 && n < UINT64_MAX_PRECISION); - - return TEN_POWERS_TABLE[n]; - } - } - } - } -} diff --git a/src/odbc/src/common/concurrent.cpp b/src/odbc/src/common/concurrent.cpp deleted file mode 100644 index 1d041644c..000000000 --- a/src/odbc/src/common/concurrent.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "ignite/odbc/common/concurrent.h" - -namespace ignite -{ - namespace odbc - { - namespace common - { - namespace concurrent - { - /** Thread-local index generator for application. */ - int32_t appTlsIdxGen = 0; - - int32_t ThreadLocal::NextIndex() - { - return Atomics::IncrementAndGet32(&appTlsIdxGen); - } - - void ThreadLocal::Remove(int32_t idx) - { - void* val = Get0(); - - if (val) - { - std::map* map = - static_cast*>(val); - - ThreadLocalEntry* appVal = (*map)[idx]; - - if (appVal) - delete appVal; - - map->erase(idx); - - if (map->size() == 0) - { - delete map; - - Set0(NULL); - } - } - } - - void ThreadLocal::Clear0(void* mapPtr) - { - if (mapPtr) - { - std::map* map = - static_cast*>(mapPtr); - - for (std::map::iterator it = map->begin(); it != map->end(); ++it) - delete it->second; - - delete map; - } - } - - SharedPointerImpl::SharedPointerImpl(void* ptr, DeleterType deleter) : - ptr(ptr), deleter(deleter), refCnt(1) - { - Memory::Fence(); - } - - void* SharedPointerImpl::Pointer() - { - return ptr; - } - - const void* SharedPointerImpl::Pointer() const - { - return ptr; - } - - SharedPointerImpl::DeleterType SharedPointerImpl::Deleter() - { - return deleter; - } - - void SharedPointerImpl::Increment() - { - Atomics::IncrementAndGet32(&refCnt); - } - - bool SharedPointerImpl::Decrement() - { - return Atomics::DecrementAndGet32(&refCnt) == 0; - } - } - } - } -} diff --git a/src/odbc/src/common/decimal.cpp b/src/odbc/src/common/decimal.cpp deleted file mode 100644 index 40d597547..000000000 --- a/src/odbc/src/common/decimal.cpp +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "ignite/odbc/common/utils.h" -#include "ignite/odbc/common/decimal.h" - -using ignite::odbc::common::BigInteger; - -namespace ignite -{ - namespace odbc - { - namespace common - { - Decimal::Decimal() : - scale(0), - magnitude(0) - { - // No-op. - } - - Decimal::Decimal(const int8_t* mag, int32_t len, int32_t scale, int32_t sign, bool bigEndian) : - scale(scale & 0x7FFFFFFF), - magnitude(mag, len, sign, bigEndian) - { - // No-op. - } - - Decimal::Decimal(const Decimal& other) : - scale(other.scale), - magnitude(other.magnitude) - { - // No-op. - } - - Decimal::Decimal(int64_t val) : - scale(0), - magnitude(val) - { - // No-op. - } - - Decimal::Decimal(int64_t val, int32_t scale) : - scale(scale), - magnitude(val) - { - // No-op. - } - - Decimal::Decimal(const BigInteger& val, int32_t scale) : - scale(scale), - magnitude(val) - { - // No-op. - } - - Decimal::Decimal(const char* val, int32_t len) : - scale(0), - magnitude(0) - { - AssignString(val, len); - } - - Decimal::~Decimal() - { - // No-op. - } - - Decimal& Decimal::operator=(const Decimal& other) - { - scale = other.scale; - magnitude = other.magnitude; - - return *this; - } - - Decimal::operator double() const - { - return ToDouble(); - } - - Decimal::operator int64_t() const - { - return ToInt64(); - } - - double Decimal::ToDouble() const - { - return common::LexicalCast(*this); - } - - int64_t Decimal::ToInt64() const - { - if (scale == 0) - return magnitude.ToInt64(); - - Decimal zeroScaled; - - SetScale(0, zeroScaled); - - return zeroScaled.magnitude.ToInt64(); - } - - int32_t Decimal::GetScale() const - { - return scale; - } - - void Decimal::SetScale(int32_t newScale, Decimal& res) const - { - if (scale == newScale) - return; - - int32_t diff = scale - newScale; - - BigInteger adjustment; - - if (diff > 0) - { - BigInteger::GetPowerOfTen(diff, adjustment); - - magnitude.Divide(adjustment, res.magnitude); - } - else - { - BigInteger::GetPowerOfTen(-diff, adjustment); - - magnitude.Multiply(adjustment, res.magnitude); - } - - res.scale = newScale; - } - - int32_t Decimal::GetPrecision() const - { - return magnitude.GetPrecision(); - } - - const BigInteger& Decimal::GetUnscaledValue() const - { - return magnitude; - } - - void Decimal::Swap(Decimal& second) - { - using std::swap; - - swap(scale, second.scale); - magnitude.Swap(second.magnitude); - } - - int32_t Decimal::GetMagnitudeLength() const - { - return magnitude.mag.GetSize(); - } - - void Decimal::AssignString(const char* val, int32_t len) - { - std::stringstream converter; - - converter.write(val, len); - - converter >> *this; - } - - void Decimal::AssignInt64(int64_t val) - { - magnitude.AssignInt64(val); - - scale = 0; - } - - void Decimal::AssignDouble(double val) - { - std::stringstream converter; - - converter.precision(16); - - converter << val; - converter >> *this; - } - - void Decimal::AssignUint64(uint64_t val) - { - magnitude.AssignUint64(val); - - scale = 0; - } - - int32_t Decimal::Compare(const Decimal& other) const - { - if (IsZero() && other.IsZero()) - return 0; - - if (scale == other.scale) - return magnitude.Compare(other.magnitude); - else if (scale > other.scale) - { - Decimal scaled; - - other.SetScale(scale, scaled); - - return magnitude.Compare(scaled.magnitude); - } - else - { - Decimal scaled; - - SetScale(other.scale, scaled); - - return scaled.magnitude.Compare(other.magnitude); - } - } - - bool Decimal::IsNegative() const - { - return magnitude.IsNegative(); - } - - bool Decimal::IsZero() const - { - return magnitude.IsZero(); - } - - bool Decimal::IsPositive() const - { - return magnitude.IsPositive(); - } - - bool operator==(const Decimal& val1, const Decimal& val2) - { - return val1.Compare(val2) == 0; - } - - bool operator!=(const Decimal& val1, const Decimal& val2) - { - return val1.Compare(val2) != 0; - } - - bool operator<(const Decimal& val1, const Decimal& val2) - { - return val1.Compare(val2) < 0; - } - - bool operator<=(const Decimal& val1, const Decimal& val2) - { - return val1.Compare(val2) <= 0; - } - - bool operator>(const Decimal& val1, const Decimal& val2) - { - return val1.Compare(val2) > 0; - } - - bool operator>=(const Decimal& val1, const Decimal& val2) - { - return val1.Compare(val2) >= 0; - } - } - } -} diff --git a/src/odbc/src/common/utils.cpp b/src/odbc/src/common/utils.cpp deleted file mode 100644 index 5dc44111f..000000000 --- a/src/odbc/src/common/utils.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include - -namespace ignite -{ - namespace odbc - { - namespace common - { - /** - * Check if string ends with the given ending. - * - * @param str String to check. - * @param ending Ending. - * @return Result. - */ - inline bool StringEndsWith(const std::string& str, const std::string& ending) - { - if (str.length() > ending.length()) - return str.compare(str.length() - ending.length(), ending.length(), ending) == 0; - - return false; - } - - void StripSurroundingWhitespaces(std::string& str) - { - std::string::size_type newBegin = 0; - while (newBegin < str.size() && ::isspace(str[newBegin])) - ++newBegin; - - if (newBegin == str.size()) - { - str.clear(); - - return; - } - - std::string::size_type newEnd = str.size() - 1; - while (::isspace(str[newEnd])) - --newEnd; - - str.assign(str, newBegin, (newEnd - newBegin) + 1); - } - - char* CopyChars(const char* val) - { - if (val) { - size_t len = strlen(val); - char* dest = new char[len + 1]; - strcpy(dest, val); - *(dest + len) = 0; - return dest; - } - - return 0; - } - - void ReleaseChars(char* val) - { - // Its OK to delete null-pointer. - delete[] val; - } - - uint32_t ToBigEndian(uint32_t value) - { - // The answer is 42 - static const int num = 42; - static const bool isLittleEndian = (*reinterpret_cast(&num) == num); - - if (isLittleEndian) - return ((value & 0xFF) << 24) | (((value >> 8) & 0xFF) << 16) | (((value >> 16) & 0xFF) << 8) | ((value >> 24) & 0xFF); - - return value; - } - - IGNITE_FRIEND_EXPORT Date MakeDateGmt(int year, int month, int day, int hour, - int min, int sec) - { - tm date; - - std::memset(&date, 0, sizeof(date)); - - date.tm_year = year - 1900; - date.tm_mon = month - 1; - date.tm_mday = day; - date.tm_hour = hour; - date.tm_min = min; - date.tm_sec = sec; - - return CTmToDate(date); - } - - IGNITE_FRIEND_EXPORT Date MakeDateLocal(int year, int month, int day, int hour, - int min, int sec) - { - tm date; - - std::memset(&date, 0, sizeof(date)); - - date.tm_year = year - 1900; - date.tm_mon = month - 1; - date.tm_mday = day; - date.tm_hour = hour; - date.tm_min = min; - date.tm_sec = sec; - - time_t localTime = common::IgniteTimeLocal(date); - - return CTimeToDate(localTime); - } - - IGNITE_FRIEND_EXPORT Time MakeTimeGmt(int hour, int min, int sec) - { - tm date; - - std::memset(&date, 0, sizeof(date)); - - date.tm_year = 70; - date.tm_mon = 0; - date.tm_mday = 1; - date.tm_hour = hour; - date.tm_min = min; - date.tm_sec = sec; - - return CTmToTime(date); - } - - IGNITE_FRIEND_EXPORT Time MakeTimeLocal(int hour, int min, int sec) - { - tm date; - - std::memset(&date, 0, sizeof(date)); - - date.tm_year = 70; - date.tm_mon = 0; - date.tm_mday = 1; - date.tm_hour = hour; - date.tm_min = min; - date.tm_sec = sec; - - time_t localTime = common::IgniteTimeLocal(date); - - return CTimeToTime(localTime); - } - - IGNITE_FRIEND_EXPORT Timestamp MakeTimestampGmt(int year, int month, int day, - int hour, int min, int sec, long ns) - { - tm date; - - std::memset(&date, 0, sizeof(date)); - - date.tm_year = year - 1900; - date.tm_mon = month - 1; - date.tm_mday = day; - date.tm_hour = hour; - date.tm_min = min; - date.tm_sec = sec; - - return CTmToTimestamp(date, ns); - } - - IGNITE_FRIEND_EXPORT Timestamp MakeTimestampLocal(int year, int month, int day, - int hour, int min, int sec, long ns) - { - tm date; - - std::memset(&date, 0, sizeof(date)); - - date.tm_year = year - 1900; - date.tm_mon = month - 1; - date.tm_mday = day; - date.tm_hour = hour; - date.tm_min = min; - date.tm_sec = sec; - - time_t localTime = common::IgniteTimeLocal(date); - - return CTimeToTimestamp(localTime, ns); - } - - IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const char* name) - { - std::stringstream libNameBuffer; - - libNameBuffer << name << Dle; - - return libNameBuffer.str(); - } - - IGNITE_IMPORT_EXPORT bool AllDigits(const std::string &val) - { - std::string::const_iterator i = val.begin(); - - while (i != val.end() && isdigit(*i)) - ++i; - - return i == val.end(); - } - - } - } -} diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index 09b0c0f71..b347c5035 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -21,7 +21,8 @@ #include #include -#include +#include + #include #include "ignite/odbc/log.h" @@ -35,10 +36,6 @@ #include "ignite/odbc/config/configuration.h" #include "ignite/odbc/config/connection_string_parser.h" #include "ignite/odbc/system/system_dsn.h" -#include "ignite/odbc/jni/java.h" -#include "ignite/odbc/jni/utils.h" -#include "ignite/odbc/common/concurrent.h" -#include "ignite/odbc/common/utils.h" // Uncomment for per-byte debug. //#define PER_BYTE_DEBUG @@ -60,16 +57,16 @@ namespace ignite { Connection::Connection(Environment* env) : env(env), + socket(), timeout(0), loginTimeout(DEFAULT_CONNECT_TIMEOUT), autoCommit(true), parser(), config(), info(config), - connection(), - opts() + streamingContext() { - // No-op + streamingContext.SetConnection(*this); } Connection::~Connection() @@ -146,15 +143,47 @@ namespace ignite IGNITE_ODBC_API_CALL(InternalEstablish(cfg)); } + SqlResult::Type Connection::InitSocket() + { + // Removed SSL Mode in DSN. Replaced this with REQUIRE for now. + ssl::SslMode::Type sslMode = ssl::SslMode::REQUIRE; + + if (sslMode == ssl::SslMode::DISABLE) + { + socket.reset(network::ssl::MakeTcpSocketClient()); + + return SqlResult::AI_SUCCESS; + } + + try + { + network::ssl::EnsureSslLoaded(); + } + catch (const IgniteError &err) + { + LOG_MSG("Can not load OpenSSL library: " << err.GetText()); + + AddStatusRecord("Can not load OpenSSL library (did you set OPENSSL_HOME environment variable?)"); + + return SqlResult::AI_ERROR; + } + + // Removed SSL key and cert files from DSN. Replaced with empty string for now. + socket.reset(network::ssl::MakeSecureSocketClient( + "", "", config.GetTlsCaFile())); + + return SqlResult::AI_SUCCESS; + } + SqlResult::Type Connection::InternalEstablish(const config::Configuration& cfg) { using ssl::SslMode; config = cfg; - if (connection) { - AddStatusRecord(SqlState::S08002_ALREADY_CONNECTED, - "Already connected."); + if (socket.get() != 0) + { + AddStatusRecord(SqlState::S08002_ALREADY_CONNECTED, "Already connected."); return SqlResult::AI_ERROR; } @@ -166,15 +195,11 @@ namespace ignite return SqlResult::AI_ERROR; } - odbc::IgniteError err; - bool connected = TryRestoreConnection(err); + bool connected = TryRestoreConnection(); if (!connected) { - std::string errMessage = "Failed to establish connection with the host.\n"; - errMessage.append(err.GetText()); - AddStatusRecord( - SqlState::S08001_CANNOT_CONNECT, errMessage); + AddStatusRecord(SqlState::S08001_CANNOT_CONNECT, "Failed to establish connection with the host."); return SqlResult::AI_ERROR; } @@ -196,7 +221,7 @@ namespace ignite SqlResult::Type Connection::InternalRelease() { - if (!connection) + if (socket.get() == 0) { AddStatusRecord(SqlState::S08003_NOT_CONNECTED, "Connection is not open."); @@ -212,19 +237,12 @@ namespace ignite void Connection::Close() { - if (connection) { - using namespace jni::java; - using namespace common::concurrent; - SharedPointer< JniContext > ctx(JniContext::Create(&opts[0], static_cast(opts.size()), JniHandlers())); - JniErrorInfo errInfo; - // NOTE: DocumentDbDisconnect will notify JNI connection is no longer used - must set to nullptr. - ctx.Get()->DocumentDbDisconnect(connection, &errInfo); - if (errInfo.code != java::IGNITE_JNI_ERR_SUCCESS) { - // TODO: Determine if we need to error check the close. - } - connection = nullptr; + if (socket.get() != 0) + { + socket->Close(); + + socket.reset(); } - Deinit(); } Statement* Connection::CreateStatement() @@ -252,26 +270,125 @@ namespace ignite bool Connection::Send(const int8_t* data, size_t len, int32_t timeout) { - // TODO: Remove if unnecessary + if (socket.get() == 0) + throw OdbcError(SqlState::S08003_NOT_CONNECTED, "Connection is not established"); + + int32_t newLen = static_cast(len + sizeof(OdbcProtocolHeader)); + + common::FixedSizeArray msg(newLen); + + OdbcProtocolHeader *hdr = reinterpret_cast(msg.GetData()); + + hdr->len = static_cast(len); + + memcpy(msg.GetData() + sizeof(OdbcProtocolHeader), data, len); + + OperationResult::T res = SendAll(msg.GetData(), msg.GetSize(), timeout); + + if (res == OperationResult::TIMEOUT) + return false; + + if (res == OperationResult::FAIL) + throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not send message due to connection failure"); + +#ifdef PER_BYTE_DEBUG + LOG_MSG("message sent: (" << msg.GetSize() << " bytes)" << utility::HexDump(msg.GetData(), msg.GetSize())); +#endif //PER_BYTE_DEBUG + return true; } Connection::OperationResult::T Connection::SendAll(const int8_t* data, size_t len, int32_t timeout) { - // TODO: Remove if unnecessary. - // No-op + int sent = 0; + + while (sent != static_cast(len)) + { + int res = socket->Send(data + sent, len - sent, timeout); + + LOG_MSG("Sent: " << res); + + if (res < 0 || res == network::SocketClient::WaitResult::TIMEOUT) + { + Close(); + + return res < 0 ? OperationResult::FAIL : OperationResult::TIMEOUT; + } + + sent += res; + } + + assert(static_cast(sent) == len); + return OperationResult::SUCCESS; } bool Connection::Receive(std::vector& msg, int32_t timeout) { - // TODO: Remove if unnecessary. + if (socket.get() == 0) + throw OdbcError(SqlState::S08003_NOT_CONNECTED, "Connection is not established"); + + msg.clear(); + + OdbcProtocolHeader hdr; + + OperationResult::T res = ReceiveAll(reinterpret_cast(&hdr), sizeof(hdr), timeout); + + if (res == OperationResult::TIMEOUT) + return false; + + if (res == OperationResult::FAIL) + throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not receive message header"); + + if (hdr.len < 0) + { + Close(); + + throw OdbcError(SqlState::SHY000_GENERAL_ERROR, "Protocol error: Message length is negative"); + } + + if (hdr.len == 0) + return false; + + msg.resize(hdr.len); + + res = ReceiveAll(&msg[0], hdr.len, timeout); + + if (res == OperationResult::TIMEOUT) + return false; + + if (res == OperationResult::FAIL) + throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not receive message body"); + +#ifdef PER_BYTE_DEBUG + LOG_MSG("Message received: " << utility::HexDump(&msg[0], msg.size())); +#endif //PER_BYTE_DEBUG + return true; } Connection::OperationResult::T Connection::ReceiveAll(void* dst, size_t len, int32_t timeout) { - // TODO: Remove if unnecessary. + size_t remain = len; + int8_t* buffer = reinterpret_cast(dst); + + while (remain) + { + size_t received = len - remain; + + int res = socket->Receive(buffer + received, remain, timeout); + LOG_MSG("Receive res: " << res << " remain: " << remain); + + if (res < 0 || res == network::SocketClient::WaitResult::TIMEOUT) + { + Close(); + + return res < 0 ? OperationResult::FAIL : OperationResult::TIMEOUT; + } + + remain -= static_cast(res); + } + return OperationResult::SUCCESS; } @@ -327,7 +444,7 @@ namespace ignite return SqlResult::AI_ERROR; } - catch (const odbc::IgniteError& err) + catch (const IgniteError& err) { AddStatusRecord(err.GetText()); @@ -368,7 +485,7 @@ namespace ignite return SqlResult::AI_ERROR; } - catch (const odbc::IgniteError& err) + catch (const IgniteError& err) { AddStatusRecord(err.GetText()); @@ -398,7 +515,7 @@ namespace ignite { SQLUINTEGER *val = reinterpret_cast(buf); - *val = connection ? SQL_CD_FALSE : SQL_CD_TRUE; + *val = socket.get() != 0 ? SQL_CD_FALSE : SQL_CD_TRUE; if (valueLen) *valueLen = SQL_IS_INTEGER; @@ -563,7 +680,7 @@ namespace ignite return SqlResult::AI_ERROR; } - catch (const odbc::IgniteError& err) + catch (const IgniteError& err) { AddStatusRecord(SqlState::S08004_CONNECTION_REJECTED, err.GetText()); @@ -598,177 +715,67 @@ namespace ignite void Connection::EnsureConnected() { - if (connection) + if (socket.get() != 0) return; - odbc::IgniteError err; - bool success = TryRestoreConnection(err); + bool success = TryRestoreConnection(); if (!success) throw OdbcError(SqlState::S08001_CANNOT_CONNECT, "Failed to establish connection with any provided hosts"); } - bool Connection::TryRestoreConnection(odbc::IgniteError& err) + bool Connection::TryRestoreConnection() { - bool connected = false; + std::vector addrs; - using namespace jni::java; - using namespace common::concurrent; + CollectAddresses(config, addrs); + + if (socket.get() == 0) + { + SqlResult::Type res = InitSocket(); - if (connection) { - return true; + if (res != SqlResult::AI_SUCCESS) + return false; } - std::string connectionString = FormatJdbcConnectionString(); - JniErrorInfo errInfo; + bool connected = false; - std::string docdb_home = common::GetEnv("DOCUMENTDB_HOME") - + "\\documentdb-jdbc-1.1.0-all.jar"; - - // 2. Resolve DOCUMENTDB_HOME. - std::string home = jni::ResolveDocumentDbHome(); + while (!addrs.empty() && !connected) + { + const EndPoint& addr = addrs.back(); - // 3. Create classpath. - std::string cp = jni::CreateDocumentDbClasspath(std::string(), home); + for (uint16_t port = addr.port; port <= addr.port + addr.range; ++port) + { + try + { + connected = socket->Connect(addr.host.c_str(), port, loginTimeout); + } + catch (const IgniteError& err) + { + LOG_MSG("Error while trying connect to " << addr.host << ":" << addr.port <<", " << err.GetText()); + } - if (cp.empty()) { - err = - odbc::IgniteError(odbc::IgniteError::IGNITE_ERR_JVM_NO_CLASSPATH, - "Java classpath is empty (did you set " - "DOCUMENTDB_HOME environment variable?)"); + if (connected) + { + SqlResult::Type res = MakeRequestHandshake(); - return false; - } + connected = res != SqlResult::AI_ERROR; - SetJvmOptions(cp); - - SharedPointer< JniContext > ctx(JniContext::Create(&opts[0], static_cast(opts.size()), JniHandlers(), &errInfo)); - if (ctx.Get()) { - jobject result = ctx.Get()->DocumentDbConnect( - connectionString.c_str(), &errInfo); - connected = (result && errInfo.code == java::IGNITE_JNI_ERR_SUCCESS); - if (!connected) { - err = odbc::IgniteError( - odbc::IgniteError::IGNITE_ERR_SECURE_CONNECTION_FAILURE, - errInfo.errMsg); - Close(); + if (connected) + break; + } } - connection = result; - } else { - err = odbc::IgniteError(odbc::IgniteError::IGNITE_ERR_JVM_INIT, "Unable to get initialized JVM."); - connection = nullptr; + + addrs.pop_back(); } + if (!connected) + Close(); + return connected; } - std::string Connection::FormatJdbcConnectionString() const { - std::string host = "localhost"; - std::string port = "27017"; - if (!config.GetAddresses().empty()) { - host = config.GetAddresses()[0].host; - port = std::to_string(config.GetAddresses()[0].port); - } - std::string jdbConnectionString; - - jdbConnectionString = "jdbc:documentdb:"; - jdbConnectionString.append("//" + config.GetUser()); - jdbConnectionString.append(":" + config.GetPassword()); - jdbConnectionString.append("@" + host); - jdbConnectionString.append(":" + port); - jdbConnectionString.append("/" + config.GetSchema()); - jdbConnectionString.append("?tlsAllowInvalidHostnames=true"); - - // Check if internal SSH tunnel should be enabled. - // TODO: Remove use of environment variables and use DSN properties - std::string sshUserAtHost = common::GetEnv("DOC_DB_USER", ""); - std::string sshRemoteHost = common::GetEnv("DOC_DB_HOST", ""); - std::string sshPrivKeyFile = common::GetEnv("DOC_DB_PRIV_KEY_FILE", ""); - std::string sshUser; - std::string sshTunnelHost; - size_t indexOfAt = sshUserAtHost.find_first_of('@'); - if (indexOfAt >= 0 && sshUserAtHost.size() > (indexOfAt + 1)) { - sshUser = sshUserAtHost.substr(0, indexOfAt); - sshTunnelHost = sshUserAtHost.substr(indexOfAt + 1); - } - if (!sshUserAtHost.empty() - && !sshRemoteHost.empty() - && !sshPrivKeyFile.empty() - && !sshUser.empty() - && !sshTunnelHost.empty()) { - jdbConnectionString.append("&sshUser=" + sshUser); - jdbConnectionString.append("&sshHost=" + sshTunnelHost); - jdbConnectionString.append("&sshPrivateKeyFile=" + sshPrivKeyFile); - jdbConnectionString.append("&sshStrictHostKeyChecking=false"); - } - - return jdbConnectionString; - } - - /** - * Create JVM options from configuration. - * - * @param cfg Configuration. - * @param home Optional GG home. - * @param cp Classpath. - */ - void Connection::SetJvmOptions(const std::string& cp) { - using namespace common; - Deinit(); - - const size_t REQ_OPTS_CNT = 4; - const size_t JAVA9_OPTS_CNT = 6; - - opts.reserve(REQ_OPTS_CNT + JAVA9_OPTS_CNT); - - // 1. Set classpath. - std::string cpFull = "-Djava.class.path=" + cp; - - opts.push_back(CopyChars(cpFull.c_str())); - - // 3. Set Xms, Xmx. - std::string xmsStr = "-Xms" + std::to_string(256) + "m"; - std::string xmxStr = "-Xmx" + std::to_string(1024) + "m"; - - opts.push_back(CopyChars(xmsStr.c_str())); - opts.push_back(CopyChars(xmxStr.c_str())); - - // 4. Optional debug arguments - //std::string debugStr = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"; - //opts.push_back(CopyChars(debugStr.c_str())); - - // 5. Set file.encoding. - std::string fileEncParam = "-Dfile.encoding="; - std::string fileEncFull = fileEncParam + "UTF-8"; - opts.push_back(CopyChars(fileEncFull.c_str())); - - // Adding options for Java 9 or later - if (jni::java::IsJava9OrLater()) { - opts.push_back(CopyChars( - "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED")); - opts.push_back(CopyChars( - "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED")); - opts.push_back(CopyChars( - "--add-exports=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED")); - opts.push_back(CopyChars( - "--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED")); - opts.push_back(CopyChars( - "--add-exports=java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED")); - opts.push_back(CopyChars( - "--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED")); - } - } - - /** - * Deallocates all allocated data. - */ - void Connection::Deinit() { - using namespace common; - std::for_each(opts.begin(), opts.end(), ReleaseChars); - opts.clear(); - } - void Connection::CollectAddresses(const config::Configuration& cfg, std::vector& endPoints) { endPoints.clear(); @@ -798,6 +805,14 @@ namespace ignite { SQLUINTEGER uTimeout = static_cast(reinterpret_cast(value)); + if (uTimeout != 0 && socket.get() != 0 && socket->IsBlocking()) + { + AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, "Can not set timeout, because can not " + "enable non-blocking mode on TCP connection. Setting to 0."); + + return 0; + } + if (uTimeout > INT32_MAX) { std::stringstream ss; diff --git a/src/odbc/src/ignite_error.cpp b/src/odbc/src/ignite_error.cpp deleted file mode 100644 index 23841d413..000000000 --- a/src/odbc/src/ignite_error.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include - -#include -#include - -using namespace ignite::odbc::common; -using namespace ignite::odbc::java; - -namespace ignite -{ - namespace odbc - { - void IgniteError::ThrowIfNeeded(const IgniteError& err) - { - if (err.code != IGNITE_SUCCESS) - throw err; - } - - IgniteError::IgniteError() : - code(IGNITE_SUCCESS), - msg(NULL) - { - // No-op. - } - - IgniteError::IgniteError(int32_t code) : - code(code), - msg(NULL) - { - } - - IgniteError::IgniteError(int32_t code, const char* msg) : - code(code), - msg(CopyChars(msg)) - { - // No-op. - } - - IgniteError::IgniteError(const IgniteError& other) : - code(other.code), - msg(CopyChars(other.msg)) - { - // No-op. - } - - IgniteError& IgniteError::operator=(const IgniteError& other) - { - if (this != &other) - { - IgniteError tmp(other); - - std::swap(code, tmp.code); - std::swap(msg, tmp.msg); - } - - return *this; - } - - IgniteError::~IgniteError() IGNITE_NO_THROW - { - ReleaseChars(msg); - } - - int32_t IgniteError::GetCode() const - { - return code; - } - - const char* IgniteError::GetText() const IGNITE_NO_THROW - { - if (code == IGNITE_SUCCESS) - return "Operation completed successfully."; - else if (msg) - return msg; - else - return "No additional information available."; - } - - const char* IgniteError::what() const IGNITE_NO_THROW - { - return GetText(); - } - - void IgniteError::SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError& err) - { - if (jniCode == IGNITE_JNI_ERR_SUCCESS) - err = IgniteError(); - else if (jniCode == IGNITE_JNI_ERR_GENERIC) - { - // The most common case when we have Java exception "in hands" and must map it to respective code. - if (jniCls) - { - std::string jniCls0 = jniCls; - - if (jniCls0.compare("java.lang.NoClassDefFoundError") == 0) - { - std::stringstream stream; - - stream << "Java class is not found (did you set DOCUMENTDB_HOME environment variable?)"; - - if (jniMsg) - stream << ": " << jniMsg; - - err = IgniteError(IGNITE_ERR_JVM_NO_CLASS_DEF_FOUND, stream.str().c_str()); - } - else if (jniCls0.compare("java.lang.NoSuchMethodError") == 0) - { - std::stringstream stream; - - stream << "Java method is not found (did you set DOCUMENTDB_HOME environment variable?)"; - - if (jniMsg) - stream << ": " << jniMsg; - - err = IgniteError(IGNITE_ERR_JVM_NO_SUCH_METHOD, stream.str().c_str()); - } - else if (jniCls0.compare("java.lang.IllegalArgumentException") == 0) - err = IgniteError(IGNITE_ERR_ILLEGAL_ARGUMENT, jniMsg); - else if (jniCls0.compare("java.lang.IllegalStateException") == 0) - err = IgniteError(IGNITE_ERR_ILLEGAL_STATE, jniMsg); - else if (jniCls0.compare("java.lang.UnsupportedOperationException") == 0) - err = IgniteError(IGNITE_ERR_UNSUPPORTED_OPERATION, jniMsg); - else if (jniCls0.compare("java.lang.InterruptedException") == 0) - err = IgniteError(IGNITE_ERR_INTERRUPTED, jniMsg); - else if (jniCls0.compare("org.apache.ignite.cluster.ClusterGroupEmptyException") == 0) - err = IgniteError(IGNITE_ERR_CLUSTER_GROUP_EMPTY, jniMsg); - else if (jniCls0.compare("org.apache.ignite.cluster.ClusterTopologyException") == 0) - err = IgniteError(IGNITE_ERR_CLUSTER_TOPOLOGY, jniMsg); - else if (jniCls0.compare("org.apache.ignite.compute.ComputeExecutionRejectedException") == 0) - err = IgniteError(IGNITE_ERR_COMPUTE_EXECUTION_REJECTED, jniMsg); - else if (jniCls0.compare("org.apache.ignite.compute.ComputeJobFailoverException") == 0) - err = IgniteError(IGNITE_ERR_COMPUTE_JOB_FAILOVER, jniMsg); - else if (jniCls0.compare("org.apache.ignite.compute.ComputeTaskCancelledException") == 0) - err = IgniteError(IGNITE_ERR_COMPUTE_TASK_CANCELLED, jniMsg); - else if (jniCls0.compare("org.apache.ignite.compute.ComputeTaskTimeoutException") == 0) - err = IgniteError(IGNITE_ERR_COMPUTE_TASK_TIMEOUT, jniMsg); - else if (jniCls0.compare("org.apache.ignite.compute.ComputeUserUndeclaredException") == 0) - err = IgniteError(IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, jniMsg); - else if (jniCls0.compare("javax.cache.CacheException") == 0) - err = IgniteError(IGNITE_ERR_CACHE, jniMsg); - else if (jniCls0.compare("javax.cache.integration.CacheLoaderException") == 0) - err = IgniteError(IGNITE_ERR_CACHE_LOADER, jniMsg); - else if (jniCls0.compare("javax.cache.integration.CacheWriterException") == 0) - err = IgniteError(IGNITE_ERR_CACHE_WRITER, jniMsg); - else if (jniCls0.compare("javax.cache.processor.EntryProcessorException") == 0) - err = IgniteError(IGNITE_ERR_ENTRY_PROCESSOR, jniMsg); - else if (jniCls0.compare("org.apache.ignite.cache.CachePartialUpdateException") == 0) - err = IgniteError(IGNITE_ERR_CACHE_PARTIAL_UPDATE, jniMsg); - else if (jniCls0.compare("org.apache.ignite.transactions.TransactionOptimisticException") == 0) - err = IgniteError(IGNITE_ERR_TX_OPTIMISTIC, jniMsg); - else if (jniCls0.compare("org.apache.ignite.transactions.TransactionTimeoutException") == 0) - err = IgniteError(IGNITE_ERR_TX_TIMEOUT, jniMsg); - else if (jniCls0.compare("org.apache.ignite.transactions.TransactionRollbackException") == 0) - err = IgniteError(IGNITE_ERR_TX_ROLLBACK, jniMsg); - else if (jniCls0.compare("org.apache.ignite.transactions.TransactionHeuristicException") == 0) - err = IgniteError(IGNITE_ERR_TX_HEURISTIC, jniMsg); - else if (jniCls0.compare("org.apache.ignite.IgniteAuthenticationException") == 0) - err = IgniteError(IGNITE_ERR_AUTHENTICATION, jniMsg); - else if (jniCls0.compare("org.apache.ignite.plugin.security.GridSecurityException") == 0) - err = IgniteError(IGNITE_ERR_SECURITY, jniMsg); - else if (jniCls0.compare("org.apache.ignite.IgniteException") == 0) - err = IgniteError(IGNITE_ERR_GENERIC, jniMsg); - else if (jniCls0.compare("org.apache.ignite.IgniteCheckedException") == 0) - err = IgniteError(IGNITE_ERR_GENERIC, jniMsg); - else - { - std::stringstream stream; - - stream << "Java exception occurred [cls=" << jniCls0; - - if (jniMsg) - stream << ", msg=" << jniMsg; - - stream << "]"; - - err = IgniteError(IGNITE_ERR_UNKNOWN, stream.str().c_str()); - } - } - else - { - // JNI class name is not available. Something really weird. - err = IgniteError(IGNITE_ERR_UNKNOWN); - } - } - else if (jniCode == IGNITE_JNI_ERR_JVM_INIT) - { - std::stringstream stream; - - stream << "Failed to initialize JVM [errCls="; - - if (jniCls) - stream << jniCls; - else - stream << "N/A"; - - stream << ", errMsg="; - - if (jniMsg) - stream << jniMsg; - else - stream << "N/A"; - - stream << "]"; - - err = IgniteError(IGNITE_ERR_JVM_INIT, stream.str().c_str()); - } - else if (jniCode == IGNITE_JNI_ERR_JVM_ATTACH) - err = IgniteError(IGNITE_ERR_JVM_ATTACH, "Failed to attach to JVM."); - } - } -} diff --git a/src/odbc/src/jni/java.cpp b/src/odbc/src/jni/java.cpp deleted file mode 100644 index dcd21b0b3..000000000 --- a/src/odbc/src/jni/java.cpp +++ /dev/null @@ -1,1102 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// ReSharper disable once CppUnusedIncludeDirective -#include // needed only on linux -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#ifndef JNI_VERSION_9 -#define JNI_VERSION_9 0x00090000 -#endif // JNI_VERSION_9 - -#define IGNITE_SAFE_PROC_NO_ARG(jniEnv, envPtr, type, field) { \ - JniHandlers* hnds = reinterpret_cast(envPtr); \ - type hnd = hnds->field; \ - if (hnd) \ - { \ - try \ - { \ - hnd(hnds->target); \ - } \ - catch (std::exception& err) \ - { \ - ThrowToJava(jniEnv, err.what()); \ - } \ - } \ - else \ - ThrowOnMissingHandler(jniEnv); \ -} - -#define IGNITE_SAFE_PROC(jniEnv, envPtr, type, field, ...) { \ - JniHandlers* hnds = reinterpret_cast(envPtr); \ - type hnd = hnds->field; \ - if (hnd) \ - { \ - try \ - { \ - hnd(hnds->target, __VA_ARGS__); \ - } \ - catch (std::exception& err) \ - { \ - ThrowToJava(jniEnv, err.what()); \ - } \ - } \ - else \ - ThrowOnMissingHandler(jniEnv); \ -} - -#define IGNITE_SAFE_FUNC(jniEnv, envPtr, type, field, ...) { \ - JniHandlers* hnds = reinterpret_cast(envPtr); \ - type hnd = hnds->field; \ - if (hnd) \ - { \ - try \ - { \ - return hnd(hnds->target, __VA_ARGS__); \ - } \ - catch (std::exception& err) \ - { \ - ThrowToJava(jniEnv, err.what()); \ - return 0; \ - } \ - } \ - else \ - { \ - ThrowOnMissingHandler(jniEnv); \ - return 0; \ - }\ -} - -using namespace ignite::odbc::java; - -namespace ignite -{ - namespace odbc - { - namespace jni - { - namespace java - { - namespace iocc = ignite::odbc::common::concurrent; - - bool IGNITE_IMPORT_EXPORT IsJava9OrLater() - { - JavaVMInitArgs args; - - memset(&args, 0, sizeof(args)); - - args.version = JNI_VERSION_9; - - return JNI_GetDefaultJavaVMInitArgs(&args) == JNI_OK; - } - - /* --- Startup exception. --- */ - class JvmException : public std::exception { - // No-op. - }; - - /* --- JNI method definitions. --- */ - struct JniMethod { - char* name; - char* sign; - bool isStatic; - - JniMethod(const char* name, const char* sign, bool isStatic) - : name(const_cast< char* >(name)), - sign(const_cast< char* >(sign)), - isStatic(isStatic) { - } - }; - - JniErrorInfo::JniErrorInfo() : code(IGNITE_JNI_ERR_SUCCESS) - { - // No-op. - } - - JniErrorInfo::JniErrorInfo(int code, const char* errCls, const char* errMsg) : code(code) - { - this->errCls = common::CopyChars(errCls); - this->errMsg = common::CopyChars(errMsg); - } - - JniErrorInfo::JniErrorInfo(const JniErrorInfo& other) : code(other.code) - { - this->errCls = common::CopyChars(other.errCls); - this->errMsg = common::CopyChars(other.errMsg); - } - - JniErrorInfo& JniErrorInfo::operator=(const JniErrorInfo& other) - { - if (this != &other) - { - // 1. Create new instance, exception could occur at this point. - JniErrorInfo tmp(other); - - // 2. Swap with temp. - std::swap(code, tmp.code); - std::swap(errCls, tmp.errCls); - std::swap(errMsg, tmp.errMsg); - } - - return *this; - } - - JniErrorInfo::~JniErrorInfo() - { - delete[] errCls; - delete[] errMsg; - } - - /** - * Guard to ensure global reference cleanup. - */ - class JniGlobalRefGuard - { - public: - JniGlobalRefGuard(JNIEnv *e, jobject obj) : env(e), ref(obj) - { - // No-op. - } - - ~JniGlobalRefGuard() - { - env->DeleteGlobalRef(ref); - } - - private: - /** Environment. */ - JNIEnv* env; - - /** Target reference. */ - jobject ref; - - IGNITE_NO_COPY_ASSIGNMENT(JniGlobalRefGuard); - }; - - const char* C_THROWABLE = "java/lang/Throwable"; - JniMethod M_THROWABLE_GET_MESSAGE = JniMethod("getMessage", "()Ljava/lang/String;", false); - JniMethod M_THROWABLE_PRINT_STACK_TRACE = JniMethod("printStackTrace", "()V", false); - - const char* C_CLASS = "java/lang/Class"; - JniMethod M_CLASS_GET_NAME = JniMethod("getName", "()Ljava/lang/String;", false); - - const char* C_DOCUMENTDB_CONNECTION_PROPERTIES = - "software/amazon/documentdb/jdbc/DocumentDbConnectionProperties"; - JniMethod M_DOCUMENTDB_CONNECTION_PROPERTIES_GET_PROPERTIES_FROM_CONNECTION_STRING = - JniMethod( - "getPropertiesFromConnectionString", - "(Ljava/lang/String;)Lsoftware/amazon/documentdb/jdbc/DocumentDbConnectionProperties;", - true); - - const char* C_DOCUMENTDB_CONNECTION = "software/amazon/documentdb/jdbc/DocumentDbConnectionProperties"; - - const char* C_DRIVERMANAGER = "java/sql/DriverManager"; - JniMethod M_DRIVERMANAGER_GET_CONNECTION = - JniMethod("getConnection", "(Ljava/lang/String;)Ljava/sql/Connection;", true); - - const char* C_JAVA_SQL_CONNECTION = "java/sql/Connection"; - JniMethod M_JAVA_SQL_CONNECTION_CLOSE = JniMethod("close", "()V", false); - - // TODO: Provide a "getFullStackTrace" from DocumentDB - //JniMethod M_PLATFORM_UTILS_GET_FULL_STACK_TRACE = JniMethod("getFullStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;", true); - - - /* STATIC STATE. */ - iocc::CriticalSection JVM_LOCK; - iocc::CriticalSection CONSOLE_LOCK; - JniJvm JVM; - bool PRINT_EXCEPTION = false; - std::vector consoleWriteHandlers; - - /* HELPER METHODS. */ - - /** - * Throw exception to Java in case of missing callback pointer. It means that callback is not implemented in - * native platform and Java -> platform operation cannot proceede further. As JniContext is not available at - * this point, we have to obtain exception details from scratch. This is not critical from performance - * perspective because missing handler usually denotes fatal condition. - * - * @param env JNI environment. - */ - int ThrowOnMissingHandler(JNIEnv* env) - { - //jclass cls = env->FindClass(C_PLATFORM_NO_CALLBACK_EXCEPTION); - - //env->ThrowNew(cls, "Callback handler is not set in native platform."); - - return 0; - } - - /** - * Throw generic exception to Java in case of native exception. As JniContext is not available at - * this point, we have to obtain exception details from scratch. This is not critical from performance - * perspective because such exception is usually denotes fatal condition. - * - * @param env JNI environment. - * @param msg Message. - */ - void ThrowToJava(JNIEnv* env, const char* msg) - { - //jclass cls = env->FindClass(C_IGNITE_EXCEPTION); - - //env->ThrowNew(cls, msg); - } - - char* StringToChars(JNIEnv* env, jstring str, int* len) { - if (!str) { - *len = 0; - return NULL; - } - - const char* strChars = env->GetStringUTFChars(str, 0); - const int strCharsLen = env->GetStringUTFLength(str); - - char* strChars0 = new char[strCharsLen + 1]; - std::strcpy(strChars0, strChars); - *(strChars0 + strCharsLen) = 0; - - env->ReleaseStringUTFChars(str, strChars); - - if (len) - *len = strCharsLen; - - return strChars0; - } - - std::string JavaStringToCString(JNIEnv* env, jstring str, int* len) - { - char* resChars = StringToChars(env, str, len); - - if (resChars) - { - std::string res = std::string(resChars, *len); - - delete[] resChars; - - return res; - } - else - return std::string(); - } - - jclass FindClass(JNIEnv* env, const char *name) { - jclass res = env->FindClass(name); - - if (!res) - throw JvmException(); - - jclass res0 = static_cast(env->NewGlobalRef(res)); - - env->DeleteLocalRef(res); - - return res0; - } - - void DeleteClass(JNIEnv* env, jclass cls) { - if (cls) - env->DeleteGlobalRef(cls); - } - - void CheckClass(JNIEnv* env, const char *name) - { - jclass res = env->FindClass(name); - - if (!res) - throw JvmException(); - } - - jmethodID FindMethod(JNIEnv* env, jclass cls, JniMethod mthd) { - jmethodID mthd0 = mthd.isStatic - ? env->GetStaticMethodID(cls, mthd.name, mthd.sign) - : env->GetMethodID(cls, mthd.name, mthd.sign); - - if (!mthd0) - throw JvmException(); - - return mthd0; - } - - jobject NewObject(JNIEnv* env, jclass clazz, jmethodID constructor, ...) { - va_list args; - va_start(args, constructor); - jobject result = env->NewObject(clazz, constructor, args); - va_end(args); - - if (!result) - throw JvmException(); - - return result; - } - - void AddNativeMethod(JNINativeMethod* mthd, JniMethod jniMthd, void* fnPtr) { - mthd->name = jniMthd.name; - mthd->signature = jniMthd.sign; - mthd->fnPtr = fnPtr; - } - - void JniJavaMembers::Initialize(JNIEnv* env) { - c_Class = FindClass(env, C_CLASS); - m_Class_getName = FindMethod(env, c_Class, M_CLASS_GET_NAME); - - c_Throwable = FindClass(env, C_THROWABLE); - m_Throwable_getMessage = FindMethod(env, c_Throwable, M_THROWABLE_GET_MESSAGE); - m_Throwable_printStackTrace = FindMethod(env, c_Throwable, M_THROWABLE_PRINT_STACK_TRACE); - - // TODO: Provide "getFullStackTrace" in DocumentDB - //m_PlatformUtils_getFullStackTrace = FindMethod(env, c_PlatformUtils, M_PLATFORM_UTILS_GET_FULL_STACK_TRACE); - } - - void JniJavaMembers::Destroy(JNIEnv* env) { - DeleteClass(env, c_Class); - DeleteClass(env, c_Throwable); - DeleteClass(env, c_PlatformUtils); - } - - bool JniJavaMembers::WriteErrorInfo(JNIEnv* env, char** errClsName, int* errClsNameLen, char** errMsg, - int* errMsgLen, char** stackTrace, int* stackTraceLen) { - if (env && env->ExceptionCheck()) { - if (m_Class_getName && m_Throwable_getMessage) { - jthrowable err = env->ExceptionOccurred(); - - env->ExceptionClear(); - - jclass errCls = env->GetObjectClass(err); - - jstring clsName = static_cast(env->CallObjectMethod(errCls, m_Class_getName)); - *errClsName = StringToChars(env, clsName, errClsNameLen); - - jstring msg = static_cast(env->CallObjectMethod(err, m_Throwable_getMessage)); - *errMsg = StringToChars(env, msg, errMsgLen); - - jstring trace = NULL; - - if (c_PlatformUtils && m_PlatformUtils_getFullStackTrace) { - trace = static_cast(env->CallStaticObjectMethod(c_PlatformUtils, m_PlatformUtils_getFullStackTrace, err)); - *stackTrace = StringToChars(env, trace, stackTraceLen); - } - - if (errCls) - env->DeleteLocalRef(errCls); - - if (clsName) - env->DeleteLocalRef(clsName); - - if (msg) - env->DeleteLocalRef(msg); - - if (trace) - env->DeleteLocalRef(trace); - - return true; - } - else { - env->ExceptionClear(); - } - } - - return false; - } - - void JniMembers::Initialize(JNIEnv* env) { - c_DocumentDbConnectionProperties = FindClass(env, C_DOCUMENTDB_CONNECTION_PROPERTIES); - m_DocumentDbConnectionPropertiesGetPropertiesFromConnectionString = - FindMethod(env, c_DocumentDbConnectionProperties, M_DOCUMENTDB_CONNECTION_PROPERTIES_GET_PROPERTIES_FROM_CONNECTION_STRING); - - c_DocumentDbConnection = FindClass(env, C_DOCUMENTDB_CONNECTION); - //m_DocumentDbConnectionInit = FindMethod(env, c_DocumentDbConnection, M_DOCUMENTDB_CONNECTION_PROPERTIES_INIT); - - c_DriverManager = FindClass(env, C_DRIVERMANAGER); - m_DriverManagerGetConnection = FindMethod(env, c_DriverManager, M_DRIVERMANAGER_GET_CONNECTION); - - c_JavaSqlConnection = FindClass(env, C_JAVA_SQL_CONNECTION); - m_JavaSqlConnectionClose = FindMethod(env, c_JavaSqlConnection, M_JAVA_SQL_CONNECTION_CLOSE); - } - - void JniMembers::Destroy(JNIEnv* env) { - DeleteClass(env, c_IgniteException); - DeleteClass(env, c_PlatformIgnition); - DeleteClass(env, c_PlatformTarget); - DeleteClass(env, c_PlatformUtils); - } - - JniJvm::JniJvm() : jvm(NULL), javaMembers(JniJavaMembers()), members(JniMembers()) - { - // No-op. - } - - JniJvm::JniJvm(JavaVM* jvm, JniJavaMembers javaMembers, JniMembers members) : - jvm(jvm), javaMembers(javaMembers), members(members) - { - // No-op. - } - - JavaVM* JniJvm::GetJvm() - { - return jvm; - } - - JniJavaMembers& JniJvm::GetJavaMembers() - { - return javaMembers; - } - - JniMembers& JniJvm::GetMembers() - { - return members; - } - - /** - * Create JVM. - */ - jint GetOrCreateJvm(char** opts, int optsLen, JavaVM** jvm, JNIEnv** env) { - // Check to see if a VM is already created - const jsize nJvms = 1; - jsize nJvmsAvailable = 0; - JavaVM* availableJvms[nJvms]{}; - jint res = JNI_GetCreatedJavaVMs(&availableJvms[0], nJvms, - &nJvmsAvailable); - if (res == JNI_OK && nJvmsAvailable >= 1) { - *jvm = availableJvms[0]; - res = (*jvm)->GetEnv(reinterpret_cast< void** >(env), - JNI_VERSION_1_8); - if (res == JNI_OK) { - return res; - } - } - - // Otherwise, create a VM - JavaVMOption* opts0 = new JavaVMOption[optsLen]; - - for (int i = 0; i < optsLen; i++) - opts0[i].optionString = *(opts + i); - - JavaVMInitArgs args{}; - args.version = JNI_VERSION_1_8; - args.nOptions = optsLen; - args.options = opts0; - args.ignoreUnrecognized = 0; - - res = JNI_CreateJavaVM(jvm, reinterpret_cast(env), &args); - - delete[] opts0; - - return res; - } - - void RegisterNatives(JNIEnv* env) { - { - JNINativeMethod methods[5]; - - int idx = 0; - - // TODO: Investigate registering callbacks to get console and logging streams. - - //AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_CONSOLE_WRITE, reinterpret_cast(JniConsoleWrite)); - - //AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_LOGGER_LOG, reinterpret_cast(JniLoggerLog)); - //AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_LOGGER_IS_LEVEL_ENABLED, reinterpret_cast(JniLoggerIsLevelEnabled)); - - //jint res = env->RegisterNatives(FindClass(env, C_PLATFORM_CALLBACK_UTILS), methods, idx); - - //if (res != JNI_OK) - // throw JvmException(); - } - } - - JniContext::JniContext(JniJvm* jvm, JniHandlers hnds) : jvm(jvm), hnds(hnds) { - // No-op. - } - - JniContext* JniContext::Create(char** opts, int optsLen, JniHandlers hnds) { - return Create(opts, optsLen, hnds, NULL); - } - - void GetJniErrorMessage(std::string& errMsg, jint res) - { - switch (res) - { - case JNI_ERR: - errMsg = "Unknown error (JNI_ERR)."; - break; - - case JNI_EDETACHED: - errMsg = "Thread detached from the JVM."; - break; - - case JNI_EVERSION: - errMsg = "JNI version error."; - break; - - case JNI_ENOMEM: - errMsg = "Could not reserve enough space for object heap. Check Xmx option."; - break; - - case JNI_EEXIST: - errMsg = "JVM already created."; - break; - - case JNI_EINVAL: - errMsg = "Invalid JVM arguments."; - break; - - default: - errMsg = "Unexpected JNI_CreateJavaVM result."; - break; - } - } - - JniContext* JniContext::Create(char** opts, int optsLen, JniHandlers hnds, JniErrorInfo* errInfo) - { - // Acquire global lock to instantiate the JVM. - JVM_LOCK.Enter(); - - // Define local variables. - JavaVM* jvm = NULL; - JNIEnv* env = NULL; - - JniJavaMembers javaMembers; - memset(&javaMembers, 0, sizeof(javaMembers)); - - JniMembers members; - memset(&members, 0, sizeof(members)); - - JniContext* ctx = NULL; - - std::string errClsName; - int errClsNameLen = 0; - std::string errMsg; - int errMsgLen = 0; - std::string stackTrace; - int stackTraceLen = 0; - - try { - if (!JVM.GetJvm()) - { - // 1. Create JVM itself. - jint res = GetOrCreateJvm(opts, optsLen, &jvm, &env); - - if (res == JNI_OK) - { - // 2. Populate members; - javaMembers.Initialize(env); - members.Initialize(env); - - // 3. Register native functions. - RegisterNatives(env); - - // 4. Create JNI JVM. - JVM = JniJvm(jvm, javaMembers, members); - - char* printStack = getenv("IGNITE_CPP_PRINT_STACK"); - PRINT_EXCEPTION = printStack && strcmp("true", printStack) == 0; - } - else - { - GetJniErrorMessage(errMsg, res); - - errMsgLen = static_cast(errMsg.length()); - } - } - - if (JVM.GetJvm()) - ctx = new JniContext(&JVM, hnds); - } - catch (const JvmException&) - { - char* errClsNameChars = NULL; - char* errMsgChars = NULL; - char* stackTraceChars = NULL; - - // Read error info if possible. - javaMembers.WriteErrorInfo(env, &errClsNameChars, &errClsNameLen, &errMsgChars, &errMsgLen, - &stackTraceChars, &stackTraceLen); - - if (errClsNameChars) { - errClsName = errClsNameChars; - - delete[] errClsNameChars; - } - - if (errMsgChars) - { - errMsg = errMsgChars; - - delete[] errMsgChars; - } - - if (stackTraceChars) - { - stackTrace = stackTraceChars; - - delete[] stackTraceChars; - } - - // Destroy mmebers. - if (env) { - members.Destroy(env); - javaMembers.Destroy(env); - } - - // Destroy faulty JVM. - if (jvm) - jvm->DestroyJavaVM(); - } - - // It safe to release the lock at this point. - JVM_LOCK.Leave(); - - // Notify err callback if needed. - if (!ctx) { - if (errInfo) { - JniErrorInfo errInfo0(IGNITE_JNI_ERR_JVM_INIT, errClsName.c_str(), errMsg.c_str()); - - *errInfo = errInfo0; - } - - if (hnds.error) - hnds.error(hnds.target, IGNITE_JNI_ERR_JVM_INIT, errClsName.c_str(), errClsNameLen, - errMsg.c_str(), errMsgLen, stackTrace.c_str(), stackTraceLen, NULL, 0); - } - - return ctx; - } - - int JniContext::Reallocate(int64_t memPtr, int cap) { - JavaVM* jvm = JVM.GetJvm(); - - JNIEnv* env; - - int attachRes = jvm->AttachCurrentThread(reinterpret_cast(&env), NULL); - - if (attachRes == JNI_OK) - AttachHelper::OnThreadAttach(); - else - return -1; - - env->CallStaticVoidMethod(JVM.GetMembers().c_PlatformUtils, JVM.GetMembers().m_PlatformUtils_reallocate, memPtr, cap); - - if (env->ExceptionCheck()) { - env->ExceptionClear(); - - return -1; - } - - return 0; - } - - void JniContext::Detach() { - iocc::Memory::Fence(); - - if (JVM.GetJvm()) { - JNIEnv* env; - - JVM.GetJvm()->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); - - if (env) - JVM.GetJvm()->DetachCurrentThread(); - } - } - - jobject JniContext::DocumentDbConnect(const char* connectionString, - JniErrorInfo* errInfo) { - JNIEnv* env = Attach(); - jstring jConnectionString = - env->NewStringUTF(connectionString); - jobject connection = env->CallStaticObjectMethod( - jvm->GetMembers().c_DriverManager, - jvm->GetMembers().m_DriverManagerGetConnection, jConnectionString); - ExceptionCheck(env, errInfo); - return connection; - } - - void JniContext::DocumentDbDisconnect(const jobject connection, JniErrorInfo* errInfo) { - if (!connection) { - return; - } - JNIEnv* env = Attach(); - env->CallVoidMethod(connection, jvm->GetMembers().m_JavaSqlConnectionClose); - ExceptionCheck(env, errInfo); - env->DeleteLocalRef(connection); - } - - int64_t JniContext::TargetInLongOutLong(jobject obj, int opType, int64_t val, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - int64_t res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformTarget_inLongOutLong, opType, val); - - ExceptionCheck(env, err); - - return res; - } - - int64_t JniContext::TargetInStreamOutLong(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - int64_t res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutLong, opType, memPtr); - - ExceptionCheck(env, err); - - return res; - } - - void JniContext::TargetInStreamOutStream(jobject obj, int opType, int64_t inMemPtr, int64_t outMemPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutStream, opType, inMemPtr, outMemPtr); - - ExceptionCheck(env, err); - } - - jobject JniContext::TargetInStreamOutObject(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, opType, memPtr); - - ExceptionCheck(env, err); - - return LocalToGlobal(env, res); - } - - jobject JniContext::TargetInObjectStreamOutObjectStream(jobject obj, int opType, void* arg, int64_t inMemPtr, int64_t outMemPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inObjectStreamOutObjectStream, opType, arg, inMemPtr, outMemPtr); - - ExceptionCheck(env, err); - - return LocalToGlobal(env, res); - } - - void JniContext::TargetOutStream(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_outStream, opType, memPtr); - - ExceptionCheck(env, err); - } - - jobject JniContext::TargetOutObject(jobject obj, int opType, JniErrorInfo* err) - { - JNIEnv* env = Attach(); - - jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_outObject, opType); - - ExceptionCheck(env, err); - - return LocalToGlobal(env, res); - } - - void JniContext::TargetInStreamAsync(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamAsync, opType, memPtr); - - ExceptionCheck(env, err); - } - - jobject JniContext::TargetInStreamOutObjectAsync(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObjectAsync, opType, memPtr); - - ExceptionCheck(env, err); - - return LocalToGlobal(env, res); - } - - jobject JniContext::CacheOutOpQueryCursor(jobject obj, int type, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - jobject res = env->CallObjectMethod( - obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, type, memPtr); - - ExceptionCheck(env, err); - - return LocalToGlobal(env, res); - } - - jobject JniContext::CacheOutOpContinuousQuery(jobject obj, int type, int64_t memPtr, JniErrorInfo* err) { - JNIEnv* env = Attach(); - - jobject res = env->CallObjectMethod( - obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, type, memPtr); - - ExceptionCheck(env, err); - - return LocalToGlobal(env, res); - } - - jobject JniContext::Acquire(jobject obj) - { - if (obj) { - - JNIEnv* env = Attach(); - - jobject obj0 = env->NewGlobalRef(obj); - - ExceptionCheck(env); - - return obj0; - } - - return NULL; - } - - void JniContext::Release(jobject obj) { - if (obj) - { - JavaVM* jvm = JVM.GetJvm(); - - if (jvm) - { - JNIEnv* env; - - jint attachRes = jvm->AttachCurrentThread(reinterpret_cast(&env), NULL); - - if (attachRes == JNI_OK) - { - AttachHelper::OnThreadAttach(); - - env->DeleteGlobalRef(obj); - } - } - } - } - - void JniContext::SetConsoleHandler(ConsoleWriteHandler consoleHandler) { - if (!consoleHandler) - throw std::invalid_argument("consoleHandler can not be null"); - - CONSOLE_LOCK.Enter(); - - consoleWriteHandlers.push_back(consoleHandler); - - CONSOLE_LOCK.Leave(); - } - - int JniContext::RemoveConsoleHandler(ConsoleWriteHandler consoleHandler) { - if (!consoleHandler) - throw std::invalid_argument("consoleHandler can not be null"); - - CONSOLE_LOCK.Enter(); - - int oldSize = static_cast(consoleWriteHandlers.size()); - - consoleWriteHandlers.erase(remove(consoleWriteHandlers.begin(), consoleWriteHandlers.end(), - consoleHandler), consoleWriteHandlers.end()); - - int removedCnt = oldSize - static_cast(consoleWriteHandlers.size()); - - CONSOLE_LOCK.Leave(); - - return removedCnt; - } - - void JniContext::ThrowToJava(char* msg) { - JNIEnv* env = Attach(); - - env->ThrowNew(jvm->GetMembers().c_IgniteException, msg); - } - - void JniContext::DestroyJvm() { - jvm->GetJvm()->DestroyJavaVM(); - } - - /** - * Attach thread to JVM. - */ - JNIEnv* JniContext::Attach() { - JNIEnv* env; - - jint attachRes = jvm->GetJvm()->AttachCurrentThread(reinterpret_cast(&env), NULL); - - if (attachRes == JNI_OK) - AttachHelper::OnThreadAttach(); - else { - if (hnds.error) - hnds.error(hnds.target, IGNITE_JNI_ERR_JVM_ATTACH, NULL, 0, NULL, 0, NULL, 0, NULL, 0); - } - - return env; - } - - void JniContext::ExceptionCheck(JNIEnv* env) { - ExceptionCheck(env, NULL); - } - - void JniContext::ExceptionCheck(JNIEnv* env, JniErrorInfo* errInfo) - { - if (env->ExceptionCheck()) { - jthrowable err = env->ExceptionOccurred(); - - if (PRINT_EXCEPTION) - env->CallVoidMethod(err, jvm->GetJavaMembers().m_Throwable_printStackTrace); - - env->ExceptionClear(); - - // Get error class name and message. - jclass cls = env->GetObjectClass(err); - - jstring clsName = static_cast(env->CallObjectMethod(cls, jvm->GetJavaMembers().m_Class_getName)); - jstring msg = static_cast(env->CallObjectMethod(err, jvm->GetJavaMembers().m_Throwable_getMessage)); - int traceLen = 0; - std::string trace0 = ""; - if (jvm->GetJavaMembers().c_PlatformUtils - && jvm->GetJavaMembers() - .m_PlatformUtils_getFullStackTrace) { - jstring trace = static_cast< jstring >( - env->CallStaticObjectMethod( - jvm->GetJavaMembers().c_PlatformUtils, - jvm->GetJavaMembers() - .m_PlatformUtils_getFullStackTrace, - err)); - - trace0 = - JavaStringToCString(env, trace, &traceLen); - } - - env->DeleteLocalRef(cls); - - int clsNameLen; - std::string clsName0 = JavaStringToCString(env, clsName, &clsNameLen); - - int msgLen; - std::string msg0 = JavaStringToCString(env, msg, &msgLen); - - if (errInfo) - { - JniErrorInfo errInfo0(IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), msg0.c_str()); - - *errInfo = errInfo0; - } - - // Get error additional data (if any). - jbyteArray errData = nullptr; - if (jvm->GetMembers().c_PlatformUtils - && jvm->GetMembers().m_PlatformUtils_errData) { - errData = static_cast< jbyteArray >( - env->CallStaticObjectMethod( - jvm->GetMembers().c_PlatformUtils, - jvm->GetMembers().m_PlatformUtils_errData, - err)); - } - - if (errData) - { - jbyte* errBytesNative = env->GetByteArrayElements(errData, NULL); - - int errBytesLen = env->GetArrayLength(errData); - - if (hnds.error) - hnds.error(hnds.target, IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), clsNameLen, msg0.c_str(), - msgLen, trace0.c_str(), traceLen, errBytesNative, errBytesLen); - - env->ReleaseByteArrayElements(errData, errBytesNative, JNI_ABORT); - } - else - { - if (hnds.error) - hnds.error(hnds.target, IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), clsNameLen, msg0.c_str(), - msgLen, trace0.c_str(), traceLen, NULL, 0); - } - - env->DeleteLocalRef(err); - } - } - - /** - * Convert local reference to global. - */ - jobject JniContext::LocalToGlobal(JNIEnv* env, jobject localRef) { - if (localRef) { - jobject globalRef = env->NewGlobalRef(localRef); - - env->DeleteLocalRef(localRef); // Clear local ref irrespective of result. - - if (!globalRef) - ExceptionCheck(env); - - return globalRef; - } - else - return NULL; - } - - JNIEXPORT void JNICALL JniConsoleWrite(JNIEnv *env, jclass, jstring str, jboolean isErr) { - CONSOLE_LOCK.Enter(); - - if (consoleWriteHandlers.size() > 0) { - ConsoleWriteHandler consoleWrite = consoleWriteHandlers.at(0); - - const char* strChars = env->GetStringUTFChars(str, 0); - const int strCharsLen = env->GetStringUTFLength(str); - - consoleWrite(strChars, strCharsLen, isErr); - - env->ReleaseStringUTFChars(str, strChars); - } - - CONSOLE_LOCK.Leave(); - } - - JNIEXPORT void JNICALL JniLoggerLog(JNIEnv *env, jclass, jlong envPtr, jint level, jstring message, jstring category, jstring errorInfo, jlong memPtr) { - int messageLen; - char* messageChars = StringToChars(env, message, &messageLen); - - int categoryLen; - char* categoryChars = StringToChars(env, category, &categoryLen); - - int errorInfoLen; - char* errorInfoChars = StringToChars(env, errorInfo, &errorInfoLen); - - IGNITE_SAFE_PROC(env, envPtr, LoggerLogHandler, loggerLog, level, messageChars, messageLen, categoryChars, categoryLen, errorInfoChars, errorInfoLen, memPtr); - - if (messageChars) - delete[] messageChars; - - if (categoryChars) - delete[] categoryChars; - - if (errorInfoChars) - delete[] errorInfoChars; - } - - JNIEXPORT jboolean JNICALL JniLoggerIsLevelEnabled(JNIEnv *env, jclass, jlong envPtr, jint level) { - IGNITE_SAFE_FUNC(env, envPtr, LoggerIsLevelEnabledHandler, loggerIsLevelEnabled, level); - } - - JNIEXPORT jlong JNICALL JniInLongOutLong(JNIEnv *env, jclass, jlong envPtr, jint type, jlong val) { - IGNITE_SAFE_FUNC(env, envPtr, InLongOutLongHandler, inLongOutLong, type, val); - } - - JNIEXPORT jlong JNICALL JniInLongLongLongObjectOutLong(JNIEnv *env, jclass, jlong envPtr, jint type, jlong val1, jlong val2, jlong val3, jobject arg) { - IGNITE_SAFE_FUNC(env, envPtr, InLongLongLongObjectOutLongHandler, inLongLongLongObjectOutLong, type, val1, val2, val3, arg); - } - } // namespace java - } // namespace jni - } // namespace odbc -} // namespace ignite diff --git a/src/odbc/src/jni/os/linux/utils.cpp b/src/odbc/src/jni/os/linux/utils.cpp deleted file mode 100644 index 6fd4d6e7a..000000000 --- a/src/odbc/src/jni/os/linux/utils.cpp +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include - -#include - -#include -#include -#include -#include -#include - -#include "ignite/common/utils.h" -#include "ignite/common/fixed_size_array.h" - -#include "ignite/odbc/jni/utils.h" -#include "ignite/odbc/jni/java.h" - -using namespace ignite::common; -using namespace ignite::odbc::jni::java; - -namespace ignite -{ - namespace odbc { - namespace jni { - const char* JAVA_HOME = "JAVA_HOME"; - const char* JAVA_DLL1 = "/jre/lib/amd64/server/libjvm.so"; - const char* JAVA_DLL2 = "/lib/server/libjvm.so"; - const char* JAVA_DLL_DARWIN = "libjvm.dylib"; - - const char* DOCUMENTDB_HOME = "DOCUMENTDB_HOME"; - - const char* IGNITE_NATIVE_TEST_CLASSPATH = "IGNITE_NATIVE_TEST_CLASSPATH"; - - /** Excluded modules from test classpath. */ - const char* TEST_EXCLUDED_MODULES[] = {"rest-http"}; - - /** Key indicating that the thread is attached. */ - static pthread_key_t attachKey; - - /** Helper to ensure that attach key is allocated only once. */ - static pthread_once_t attachKeyInit = PTHREAD_ONCE_INIT; - - void DestroyAttachKey(void* key) { - delete reinterpret_cast< AttachHelper* >(key); - } - - void AllocateAttachKey() { - pthread_key_create(&attachKey, DestroyAttachKey); - } - - AttachHelper::~AttachHelper() { - JniContext::Detach(); - } - - void AttachHelper::OnThreadAttach() { - pthread_once(&attachKeyInit, AllocateAttachKey); - - void* val = pthread_getspecific(attachKey); - - if (!val) - pthread_setspecific(attachKey, new AttachHelper()); - } - - /** - * Checks if the path looks like binary release home directory. - * Internally checks for presence of some directories, that are - * @return @c true if the path looks like binary release home directory. - */ - bool LooksLikeBinaryReleaseHome(const std::string& path) { - static const char* PROBE_CORE_LIB = "/libs/ignite-core*.jar"; - - std::string coreLibProbe = path + PROBE_CORE_LIB; - - return FileExists(coreLibProbe); - } - - /** - * Checks if the path looks like source release home directory. - * Internally checks for presence of core source directory. - * @return @c true if the path looks like binary release home directory. - */ - bool LooksLikeSourceReleaseHome(const std::string& path) { - static const char* PROBE_CORE_SOURCE = - "/modules/core/src/main/java/org/apache/ignite"; - - std::string coreSourcePath = path + PROBE_CORE_SOURCE; - - return IsValidDirectory(coreSourcePath); - } - - /** - * Helper function for Ignite home resolution. - * Goes upwards in directory hierarchy and checks whether certain - * folders exist in the path. - * - * @param path Path to evaluate. - * @return res Resolved directory. Empty string if not found. - */ - std::string ResolveIgniteHome0(const std::string& path) { - if (!IsValidDirectory(path)) - return std::string(); - - // Remove trailing slashes, otherwise we will have an infinite loop. - size_t last = path.find_last_not_of("/ "); - - if (last == std::string::npos) - return std::string(); - - std::string path0(path, 0, last + 1); - - if (LooksLikeBinaryReleaseHome(path0) || LooksLikeSourceReleaseHome(path0)) - return path0; - - // Evaluate parent directory. - size_t slashPos = path0.find_last_of("/"); - - if (slashPos == std::string::npos) - return std::string(); - - std::string parent(path0, 0, slashPos); - - return ResolveIgniteHome0(parent); - } - - /** - * Create classpath picking JARs from the given path. - * - * @path Path. - * @return Classpath; - */ - std::string ClasspathJars(const std::string& path) { - std::string res; - - DIR* dir = opendir(path.c_str()); - - if (dir) { - struct dirent* entry; - - while ((entry = readdir(dir)) != NULL) { - char* dot = strrchr(entry->d_name, '.'); - if (dot && !strcmp(dot, ".jar")) { - res.append(path); - res.append("/"); - res.append(entry->d_name); - res.append(":"); - } - } - - closedir(dir); - } - - return res; - } - - /** - * Check if path corresponds to excluded module. - * - * @path Path. - * @return True if path should be excluded. - */ - bool IsExcludedModule(const std::string& path) { - std::string lower_path = path; - std::transform(path.begin(), path.end(), lower_path.begin(), ::tolower); - - for (size_t i = 0; i < sizeof(TEST_EXCLUDED_MODULES) / sizeof(char*); i++) { - if (lower_path.find(TEST_EXCLUDED_MODULES[i]) != std::string::npos) - return true; - } - - return false; - } - - /** - * Create classpath picking compiled classes from the given path. - * - * @path Path. - * @return Classpath; - */ - std::string ClasspathExploded(const std::string& path, bool down) { - std::string res; - - if (FileExists(path) && !IsExcludedModule(path)) { - // 1. Append "target\classes". - std::string classesPath = path + "/target/classes"; - - if (FileExists(classesPath)) { - res += classesPath; - res += ":"; - } - - // 2. Append "target\test-classes" - std::string testClassesPath = path + "/target/test-classes"; - - if (FileExists(testClassesPath)) { - res += testClassesPath; - res += ":"; - } - - // 3. Append "target\libs" - std::string libsPath = path + "/target/libs"; - - if (FileExists(libsPath)) { - std::string libsCp = ClasspathJars(libsPath); - res += libsCp; - } - - // 4. Do the same for child if needed. - if (down) { - DIR* dir = opendir(path.c_str()); - - if (dir) { - struct dirent* entry; - - while ((entry = readdir(dir)) != NULL) { - std::string entryPath = entry->d_name; - - if (entryPath.compare(".") != 0 - && entryPath.compare("..") != 0) { - std::string entryFullPath = path + "/" + entryPath; - - struct stat entryFullStat; - - if (stat(entryFullPath.c_str(), &entryFullStat) != -1 - && S_ISDIR(entryFullStat.st_mode)) { - std::string childCp = - ClasspathExploded(entryFullPath, false); - - res += childCp; - } - } - } - - closedir(dir); - } - } - } - - return res; - } - - std::string CreateDocumentDbHomeClasspath(const std::string& home, bool forceTest) { - std::string res = std::string(); - - // 1. Add exploded test directories. - if (forceTest) { - std::string examplesPath = home + "/examples"; - std::string examplesCp = ClasspathExploded(examplesPath, true); - res.append(examplesCp); - - std::string modulesPath = home + "/modules"; - std::string modulesCp = ClasspathExploded(modulesPath, true); - res.append(modulesCp); - } - - // 2. Add regular jars from "libs" folder excluding "optional". - std::string libsPath = home + "/libs"; - - if (FileExists(libsPath)) { - res.append(ClasspathJars(libsPath)); - - // Append inner directories. - DIR* dir = opendir(libsPath.c_str()); - - if (dir) { - struct dirent* entry; - - while ((entry = readdir(dir)) != NULL) { - std::string entryPath = entry->d_name; - - if (entryPath.compare(".") != 0 && entryPath.compare("..") != 0 - && entryPath.compare("optional") != 0) { - std::string entryFullPath = libsPath; - - entryFullPath.append("/"); - entryFullPath.append(entryPath); - - struct stat entryFullStat; - - if (stat(entryFullPath.c_str(), &entryFullStat) != -1 - && S_ISDIR(entryFullStat.st_mode)) - res.append(ClasspathJars(entryFullPath)); - } - } - - closedir(dir); - } - } - - // 3. Return. - return res; - } - - std::string FindJvmLibrary(const std::string& path) { - #ifdef __APPLE__ - return JAVA_DLL_DARWIN; - #else - // If path is provided explicitly, then check only it. - if (!path.empty() && FileExists(path)) - return path; - - std::string javaEnv = GetEnv(JAVA_HOME); - - if (!javaEnv.empty()) { - std::string javaDll = javaEnv + JAVA_DLL1; - - if (FileExists(javaDll)) - return javaDll; - - javaDll = javaEnv + JAVA_DLL2; - - if (FileExists(javaDll)) - return javaDll; - } - - return std::string(); - #endif - } - - bool LoadJvmLibrary(const std::string& path) { - #ifdef __APPLE__ - return RTLD_DEFAULT; - #else - void* hnd = dlopen(path.c_str(), RTLD_LAZY); - - return hnd != NULL; - #endif - } - - /** - * Create Ignite classpath based on user input and home directory. - * - * @param usrCp User's classpath. - * @param home Ignite home directory. - * @param forceTest Whether test classpath must be used. - * @return Classpath. - */ - std::string CreateIgniteClasspath(const std::string& usrCp, - const std::string* home, bool forceTest) { - // 1. Append user classpath if it exists. - std::string cp; - - if (!usrCp.empty()) { - cp.append(usrCp); - - if (*cp.rbegin() != ';') - cp.push_back(';'); - } - - // 2. Append home classpath if home is defined. - if (home) { - std::string homeCp = CreateDocumentDbHomeClasspath(*home, forceTest); - - cp.append(homeCp); - } - - // 3. Return. - return cp; - } - - /** - * Adds semicolon at the end of the path if needed. - * @param usrCp Classpath provided by user. - * @return Normalized classpath. - */ - std::string NormalizeClasspath(const std::string& usrCp) { - if (usrCp.empty() || *usrCp.rbegin() == ';') - return usrCp; - - return usrCp + ';'; - } - - std::string CreateDocumentDbClasspath(const std::string& usrCp, - const std::string& home) { - // 1. Append user classpath if it exists. - std::string cp = NormalizeClasspath(usrCp); - - // 2. Append home classpath - if (!home.empty()) { - std::string env = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, "false"); - - bool forceTest = ToLower(env) == "true"; - - std::string homeCp = CreateDocumentDbHomeClasspath(home, forceTest); - - cp.append(homeCp); - } - - // 3. Return. - return cp; - } - - std::string ResolveDocumentDbHome(const std::string& path) { - // 1. Check passed argument. - if (IsValidDirectory(path)) - return path; - - // 2. Check environment variable. - std::string home = GetEnv(DOCUMENTDB_HOME); - - if (IsValidDirectory(home)) - return home; - - // 3. Check current work dir. - FixedSizeArray< char > curDir(1024 * 16); - - char* res = getcwd(curDir.GetData(), curDir.GetSize()); - - if (!res) - return std::string(); - - std::string curDirStr(curDir.GetData()); - - return ResolveIgniteHome0(curDirStr); - } - } // namespace jni - } // namespace odbc -} diff --git a/src/odbc/src/jni/os/win/utils.cpp b/src/odbc/src/jni/os/win/utils.cpp deleted file mode 100644 index e41fb56af..000000000 --- a/src/odbc/src/jni/os/win/utils.cpp +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include - -#include "ignite/common/concurrent.h" -#include "ignite/common/utils.h" -#include "ignite/common/fixed_size_array.h" - -#include "ignite/odbc/jni/utils.h" -#include "ignite/odbc/jni/java.h" - -using namespace ignite::common; -using namespace ignite::common::concurrent; - -using namespace ignite::odbc::jni::java; - -namespace ignite -{ - namespace odbc - { - namespace jni - { - const char* JAVA_HOME = "JAVA_HOME"; - const char* JAVA_DLL1 = "\\jre\\bin\\server\\jvm.dll"; - const char* JAVA_DLL2 = "\\bin\\server\\jvm.dll"; - - const char* DOCUMENTDB_HOME = "DOCUMENTDB_HOME"; - - const char* IGNITE_NATIVE_TEST_CLASSPATH = "IGNITE_NATIVE_TEST_CLASSPATH"; - - /** Excluded modules from test classpath. */ - const char* TEST_EXCLUDED_MODULES[] = { "rest-http" }; - - AttachHelper::~AttachHelper() - { - // No-op. - } - - void AttachHelper::OnThreadAttach() - { - // No-op. - } - - /** - * Checks if the path looks like binary release home directory. - * Internally checks for presence of core library. - * @return @c true if the path looks like binary release home directory. - */ - bool LooksLikeBinaryReleaseHome(const std::string& path) - { - static const char* PROBE_CORE_LIB = "\\libs\\ignite-core*.jar"; - - std::string coreLibProbe = path + PROBE_CORE_LIB; - - return FileExists(coreLibProbe); - } - - /** - * Checks if the path looks like source release home directory. - * Internally checks for presence of core source directory. - * @return @c true if the path looks like binary release home directory. - */ - bool LooksLikeSourceReleaseHome(const std::string& path) - { - static const char* PROBE_CORE_SOURCE = "\\modules\\core\\src\\main\\java\\org\\apache\\ignite"; - - std::string coreSourcePath = path + PROBE_CORE_SOURCE; - - return IsValidDirectory(coreSourcePath); - } - - /** - * Helper function for Ignite home resolution. - * Goes upwards in directory hierarchy and checks whether certain - * folders exist in the path. - * - * @param path Path to evaluate. - * @return res Resolved directory. Empty string if not found. - */ - std::string ResolveIgniteHome0(const std::string& path) - { - if (!IsValidDirectory(path)) - return std::string(); - - // Remove trailing slashes, otherwise we will have an infinite loop. - size_t last = path.find_last_not_of("/\\ "); - - if (last == std::string::npos) - return std::string(); - - std::string path0(path, 0, last + 1); - - if (LooksLikeBinaryReleaseHome(path0) || LooksLikeSourceReleaseHome(path0)) - return path0; - - // Evaluate parent directory. - size_t slashPos = path0.find_last_of("/\\"); - - if (slashPos == std::string::npos) - return std::string(); - - std::string parent(path0, 0, slashPos); - - return ResolveIgniteHome0(parent); - } - - /** - * Create classpath picking JARs from the given path. - * - * @path Path. - * @return Classpath; - */ - std::string ClasspathJars(const std::string& path) - { - std::string searchPath = path + "\\*.jar"; - - WIN32_FIND_DATAA findData; - - HANDLE hnd = FindFirstFileA(searchPath.c_str(), &findData); - - if (hnd == INVALID_HANDLE_VALUE) - return std::string(); - - std::string res; - - do - { - res.append(path); - res.append("\\"); - res.append(findData.cFileName); - res.append(";"); - } while (FindNextFileA(hnd, &findData) != 0); - - FindClose(hnd); - - return res; - } - - /** - * Check if path corresponds to excluded module. - * - * @path Path. - * @return True if path should be excluded. - */ - bool IsExcludedModule(const std::string& path) { - std::string lower_path = path; - std::transform(path.begin(), path.end(), lower_path.begin(), ::tolower); - - for (size_t i = 0; i < sizeof(TEST_EXCLUDED_MODULES) / sizeof(char*); i++) { - if (lower_path.find(TEST_EXCLUDED_MODULES[i]) != std::string::npos) - return true; - } - - return false; - } - - /** - * Create classpath picking compiled classes from the given path. - * - * @path Path. - * @return Classpath; - */ - std::string ClasspathExploded(const std::string& path, bool down) - { - std::string res; - - if (FileExists(path) && !IsExcludedModule(path)) - { - // 1. Append "target\classes". - std::string classesPath = path + "\\target\\classes"; - - if (FileExists(classesPath)) { - res.append(classesPath); - res.append(";"); - } - - // 2. Append "target\test-classes" - std::string testClassesPath = path + "\\target\\test-classes"; - - if (FileExists(testClassesPath)) { - res.append(testClassesPath); - res.append(";"); - } - - // 3. Append "target\libs" - std::string libsPath = path + "\\target\\libs"; - - if (FileExists(libsPath)) { - std::string libsCp = ClasspathJars(libsPath); - res.append(libsCp); - } - - // 4. Do the same for child if needed. - if (down) - { - std::string searchPath = path + "\\*"; - - WIN32_FIND_DATAA findData; - - HANDLE hnd = FindFirstFileA(searchPath.c_str(), &findData); - - if (hnd != INVALID_HANDLE_VALUE) - { - do - { - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - std::string childPath = findData.cFileName; - - if (childPath.compare(".") != 0 && - childPath.compare("..") != 0) - { - std::string childCp = - ClasspathExploded(path + "\\" + childPath, false); - - res.append(childCp); - } - } - } while (FindNextFileA(hnd, &findData) != 0); - - FindClose(hnd); - } - } - } - - return res; - } - - std::string CreateDocumentDbHomeClasspath(const std::string& home, bool forceTest) - { - std::string res; - - // 1. Add exploded test directories. - if (forceTest) - { - std::string examplesPath = home + "\\examples"; - std::string examplesCp = ClasspathExploded(examplesPath, true); - res.append(examplesCp); - - std::string modulesPath = home + "\\modules"; - std::string modulesCp = ClasspathExploded(modulesPath, true); - res.append(modulesCp); - } - - // 2. Add regular jars from "libs" folder excluding "optional". - std::string libsPath = home + "\\libs"; - - if (FileExists(libsPath)) - { - res.append(ClasspathJars(libsPath)); - - // Append inner directories. - std::string libsSearchPath = libsPath + "\\*"; - - WIN32_FIND_DATAA libsFindData; - - HANDLE libsHnd = FindFirstFileA(libsSearchPath.c_str(), &libsFindData); - - if (libsHnd != INVALID_HANDLE_VALUE) - { - do - { - if (libsFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - { - std::string libsChildPath = libsFindData.cFileName; - - if (libsChildPath.compare(".") != 0 && - libsChildPath.compare("..") != 0 && - libsChildPath.compare("optional") != 0) { - std::string libsFolder = libsPath + "\\" + libsChildPath; - - res.append(ClasspathJars(libsFolder)); - } - } - } while (FindNextFileA(libsHnd, &libsFindData) != 0); - - FindClose(libsHnd); - } - } - - // 3. Return. - return res; - } - - std::string FindJvmLibrary(const std::string& path) - { - // If path is provided explicitly, then check only it. - if (!path.empty() && FileExists(path)) - return path; - - std::string javaEnv = GetEnv(JAVA_HOME); - - if (!javaEnv.empty()) - { - std::string javaDll = javaEnv + JAVA_DLL1; - - if (FileExists(javaDll)) - return javaDll; - - javaDll = javaEnv + JAVA_DLL2; - - if (FileExists(javaDll)) - return javaDll; - } - - return std::string(); - } - - bool LoadJvmLibrary(const std::string& path) - { - HMODULE mod = LoadLibraryA(path.c_str()); - - return mod != NULL; - } - - /** - * Create Ignite classpath based on user input and home directory. - * - * @param usrCp User's classpath. - * @param home Ignite home directory. - * @param forceTest Whether test classpath must be used. - * @return Classpath. - */ - std::string CreateIgniteClasspath(const std::string& usrCp, const std::string* home, bool forceTest) - { - // 1. Append user classpath if it exists. - std::string cp; - - if (!usrCp.empty()) - { - cp.append(usrCp); - - if (*cp.rbegin() != ';') - cp.push_back(';'); - } - - // 2. Append home classpath if home is defined. - if (home) - { - std::string homeCp = CreateDocumentDbHomeClasspath(*home, forceTest); - - cp.append(homeCp); - } - - // 3. Return. - return cp; - } - - /** - * Adds semicolon at the end of the path if needed. - * @param usrCp Classpath provided by user. - * @return Normalized classpath. - */ - std::string NormalizeClasspath(const std::string& usrCp) - { - if (usrCp.empty() || *usrCp.rbegin() == ';') - return usrCp; - - return usrCp + ';'; - } - - std::string CreateDocumentDbClasspath(const std::string& usrCp, const std::string& home) - { - // 1. Append user classpath if it exists. - std::string cp = NormalizeClasspath(usrCp); - - // 2. Append home classpath - if (!home.empty()) - { - std::string env = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, "false"); - - bool forceTest = ToLower(env) == "true"; - - std::string homeCp = CreateDocumentDbHomeClasspath(home, forceTest); - - cp.append(homeCp); - } - - // 3. Return. - return cp; - } - - std::string ResolveDocumentDbHome(const std::string& path) - { - // 1. Check passed argument. - if (IsValidDirectory(path)) - return path; - - // 2. Check environment variable. - std::string home = GetEnv(DOCUMENTDB_HOME); - - if (IsValidDirectory(home)) - return home; - - // 3. Check current work dir. - DWORD curDirLen = GetCurrentDirectoryA(0, NULL); - - if (!curDirLen) - return std::string(); - - FixedSizeArray curDir(curDirLen); - - curDirLen = GetCurrentDirectoryA(curDir.GetSize(), curDir.GetData()); - - if (!curDirLen) - return std::string(); - - std::string curDirStr(curDir.GetData()); - - return ResolveIgniteHome0(curDirStr); - } - } // jni - } // odbc -} // ignite - -BOOL WINAPI DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) -{ - switch (fdwReason) - { - case DLL_PROCESS_ATTACH: - if (!ThreadLocal::OnProcessAttach()) - return FALSE; - - break; - - case DLL_THREAD_DETACH: - ThreadLocal::OnThreadDetach(); - - JniContext::Detach(); - - break; - - case DLL_PROCESS_DETACH: - ThreadLocal::OnProcessDetach(); - - break; - - default: - break; - } - - return TRUE; -} \ No newline at end of file diff --git a/src/odbc/src/log.cpp b/src/odbc/src/log.cpp index 80f0b8b88..755798f48 100644 --- a/src/odbc/src/log.cpp +++ b/src/odbc/src/log.cpp @@ -67,7 +67,7 @@ namespace ignite { if (IsEnabled()) { - common::concurrent::CsLockGuard guard(mutex); + ignite::common::concurrent::CsLockGuard guard(mutex); stream << message << std::endl; } } diff --git a/src/odbc/src/protocol_version.cpp b/src/odbc/src/protocol_version.cpp index f196b33e7..a073ab26c 100644 --- a/src/odbc/src/protocol_version.cpp +++ b/src/odbc/src/protocol_version.cpp @@ -17,7 +17,7 @@ #include -#include +#include #include "ignite/odbc/protocol_version.h" #include "ignite/odbc/utility.h" diff --git a/src/odbc/src/ssl_mode.cpp b/src/odbc/src/ssl_mode.cpp index 0f5aba861..70fd05891 100644 --- a/src/odbc/src/ssl_mode.cpp +++ b/src/odbc/src/ssl_mode.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -#include +#include #include "ignite/odbc/ssl_mode.h" diff --git a/src/odbc/src/utility.cpp b/src/odbc/src/utility.cpp index 8ac9221f7..c060a0ada 100644 --- a/src/odbc/src/utility.cpp +++ b/src/odbc/src/utility.cpp @@ -67,7 +67,7 @@ namespace ignite writer.WriteString(str.data(), static_cast(str.size())); } - void ReadDecimal(ignite::impl::binary::BinaryReaderImpl& reader, odbc::common::Decimal& decimal) + void ReadDecimal(ignite::impl::binary::BinaryReaderImpl& reader, common::Decimal& decimal) { int8_t hdr = reader.ReadInt8(); @@ -94,20 +94,20 @@ namespace ignite sign = -1; } - odbc::common::Decimal res(mag.data(), static_cast(mag.size()), scale, sign); + common::Decimal res(mag.data(), static_cast(mag.size()), scale, sign); decimal.Swap(res); } - void WriteDecimal(ignite::impl::binary::BinaryWriterImpl& writer, const odbc::common::Decimal& decimal) + void WriteDecimal(ignite::impl::binary::BinaryWriterImpl& writer, const common::Decimal& decimal) { writer.WriteInt8(ignite::impl::binary::IGNITE_TYPE_DECIMAL); - const odbc::common::BigInteger &unscaled = decimal.GetUnscaledValue(); + const common::BigInteger &unscaled = decimal.GetUnscaledValue(); writer.WriteInt32(decimal.GetScale()); - odbc::common::FixedSizeArray magnitude; + common::FixedSizeArray magnitude; unscaled.MagnitudeToBytes(magnitude); From 4d704df11a5d29eddce6e35e47f4572ff111d2ad Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 26 Jan 2022 12:00:20 -0800 Subject: [PATCH 086/100] [AD-522] keyboard user interface design + disable DSN empty strimg warning dialog * make cursor go to checkboxes on the Config window and not skip them when tab key is pressed * when DSN field is empty, Ok Button is disabled * make default replicaSet value empty string (default is disable repliaSet) * refactor - removed unneeded comments --- .../os/win/src/system/ui/custom_window.cpp | 4 +- .../system/ui/dsn_configuration_window.cpp | 69 ++++++------------- src/odbc/src/config/configuration.cpp | 2 +- 3 files changed, 24 insertions(+), 51 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/custom_window.cpp b/src/odbc/os/win/src/system/ui/custom_window.cpp index 57690a3a4..ebc569efa 100644 --- a/src/odbc/os/win/src/system/ui/custom_window.cpp +++ b/src/odbc/os/win/src/system/ui/custom_window.cpp @@ -162,7 +162,7 @@ namespace ignite { std::auto_ptr child(new Window(this, "Button", title)); - child->Create(WS_CHILD | WS_VISIBLE | BS_CHECKBOX, posX, posY, sizeX, sizeY, id); + child->Create(WS_CHILD | WS_VISIBLE | BS_CHECKBOX | WS_TABSTOP, posX, posY, sizeX, sizeY, id); child->SetChecked(state); @@ -174,7 +174,7 @@ namespace ignite { std::auto_ptr child(new Window(this, "Combobox", title)); - child->Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST, posX, posY, sizeX, sizeY, id); + child->Create(WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_TABSTOP, posX, posY, sizeX, sizeY, id); return child; } diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index b3a35c843..06b77c3b3 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -24,7 +24,6 @@ #include "ignite/odbc/system/ui/dsn_configuration_window.h" #include "ignite/odbc/config/config_tools.h" -#include "ignite/odbc/diagnostic/diagnosable_adapter.h" namespace ignite { @@ -36,10 +35,7 @@ namespace ignite { DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config): CustomWindow(parent, "IgniteConfigureDsn", "Configure Amazon DocumentDB DSN Latest"), - //width(360), // original width:360. - //height(600), // original height:600 - width(730), // double the original width - //width(360), + width(730), height(515), connectionSettingsGroupBox(), tlsSettingsGroupBox(), @@ -130,26 +126,17 @@ namespace ignite void DsnConfigurationWindow::OnCreate() { int groupPosYLeft = MARGIN; - //int groupSizeY = width - 2 * MARGIN; // original int groupSizeY = width / 2 - 2 * MARGIN; int posXRight = width / 2 + MARGIN; - //int posXRight = MARGIN + (width - MARGIN) / 2; - //int posXRight = MARGIN + groupSizeY; - //int posXRight = 2 * MARGIN + groupSizeY; int groupPosYRight = MARGIN; // create left column group settings groupPosYLeft += INTERVAL + CreateConnectionSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); - //groupPosYLeft += INTERVAL + CreateAuthSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); groupPosYLeft += INTERVAL + CreateTlsSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); groupPosYLeft += INTERVAL + CreateSchemaSettingsGroup(MARGIN, groupPosYLeft, groupSizeY); // create right column group settings groupPosYRight += INTERVAL + CreateSshSettingsGroup(posXRight, groupPosYRight, groupSizeY); groupPosYRight += INTERVAL + CreateAdditionalSettingsGroup(posXRight, groupPosYRight, groupSizeY); - //groupPosY += INTERVAL + CreateSslSettingsGroup(MARGIN, groupPosY, groupSizeY); - //groupPosY += INTERVAL + CreateAdditionalSettingsGroup(MARGIN, groupPosY, groupSizeY); - // test: if above code is commented out, additional settings shouldn't appear in config window. Result: Yes test success. - // what happens here is the height of each subgroup is calculated and appended to the y position of the buttons int cancelPosX = width - MARGIN - BUTTON_WIDTH; int okPosX = cancelPosX - INTERVAL - BUTTON_WIDTH; @@ -161,14 +148,9 @@ namespace ignite // check whether the required fields are filled. If not, Ok button is disabled. created = true; okButton->SetEnabled( - userEdit->HasText() && passwordEdit->HasText() - && databaseEdit->HasText() && hostnameEdit->HasText() - && portEdit->HasText()); - - // original code by Ignite - //okButton = CreateButton(okPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, "Ok", ChildId::OK_BUTTON); - //cancelButton = CreateButton(cancelPosX, groupPosY, BUTTON_WIDTH, BUTTON_HEIGHT, - // "Cancel", ChildId::CANCEL_BUTTON); + nameEdit->HasText() && userEdit->HasText() + && passwordEdit->HasText() && databaseEdit->HasText() + && hostnameEdit->HasText() && portEdit->HasText()); } int DsnConfigurationWindow::CreateConnectionSettingsGroup(int posX, int posY, int sizeX) @@ -184,14 +166,14 @@ namespace ignite const char* val = config.GetDsn().c_str(); nameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Data Source Name:", ChildId::NAME_LABEL); + "Data Source Name*:", ChildId::NAME_LABEL); nameEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::NAME_EDIT); rowPos += INTERVAL + ROW_HEIGHT; val = config.GetHostname().c_str(); hostnameLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Hostname :", ChildId::HOST_NAME_LABEL); + "Hostname*:", ChildId::HOST_NAME_LABEL); hostnameEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::HOST_NAME_EDIT); @@ -201,7 +183,7 @@ namespace ignite val = tmp.c_str(); portLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Port:", ChildId::PORT_LABEL); + "Port*:", ChildId::PORT_LABEL); portEdit = CreateEdit( editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::PORT_EDIT, ES_NUMBER); @@ -211,21 +193,21 @@ namespace ignite val = config.GetDatabase().c_str(); databaseLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Database :", ChildId::DATABASE_LABEL); + "Database*:", ChildId::DATABASE_LABEL); databaseEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::DATABASE_EDIT); rowPos += INTERVAL + ROW_HEIGHT; val = config.GetUser().c_str(); - userLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "User :", ChildId::USER_LABEL); + userLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "User* :", ChildId::USER_LABEL); userEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::USER_EDIT); rowPos += INTERVAL + ROW_HEIGHT; val = config.GetPassword().c_str(); passwordLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "Password:", ChildId::PASSWORD_LABEL); + "Password*:", ChildId::PASSWORD_LABEL); passwordEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::USER_EDIT, ES_PASSWORD); @@ -257,14 +239,14 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; const char* val = config.GetSshUser().c_str(); - sshUserLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSH User :", ChildId::SSH_USER_LABEL); + sshUserLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "SSH User:", ChildId::SSH_USER_LABEL); sshUserEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_USER_EDIT); rowPos += INTERVAL + ROW_HEIGHT; val = config.GetSshHost().c_str(); sshHostLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSH Hostname :", ChildId::SSH_HOST_LABEL); + "SSH Hostname:", ChildId::SSH_HOST_LABEL); sshHostEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_HOST_EDIT); @@ -272,7 +254,7 @@ namespace ignite val = config.GetSshPrivateKeyFile().c_str(); sshPrivateKeyFileLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, - "SSH Private Key File :", ChildId::SSH_PRIVATE_KEY_FILE_LABEL); + "SSH Private Key File:", ChildId::SSH_PRIVATE_KEY_FILE_LABEL); sshPrivateKeyFileEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_PRIVATE_KEY_FILE_EDIT); @@ -281,7 +263,7 @@ namespace ignite val = config.GetSshPrivateKeyPassphrase().c_str(); // ssh private key passphrase label requires double the row height due to the long label. sshPrivateKeyPassphraseLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT * 2, - "SSH Private Key Passphrase :", ChildId::SSH_PRIVATE_KEY_PASSPHRASE_LABEL); + "SSH Private Key Passphrase:", ChildId::SSH_PRIVATE_KEY_PASSPHRASE_LABEL); sshPrivateKeyPassphraseEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT * 2, val, ChildId::SSH_PRIVATE_KEY_PASSPHRASE_EDIT); @@ -561,6 +543,7 @@ namespace ignite break; } + case ChildId::NAME_EDIT: case ChildId::HOST_NAME_EDIT: case ChildId::PORT_EDIT: case ChildId::DATABASE_EDIT: @@ -570,11 +553,12 @@ namespace ignite // if window has been created. Check if (created) { okButton->SetEnabled( - userEdit->HasText() - && passwordEdit->HasText() - && databaseEdit->HasText() - && hostnameEdit->HasText() - && portEdit->HasText()); + nameEdit->HasText() + && userEdit->HasText() + && passwordEdit->HasText() + && databaseEdit->HasText() + && hostnameEdit->HasText() + && portEdit->HasText()); } break; } @@ -721,17 +705,6 @@ namespace ignite // username and password intentionally not logged for security reasons - if (dsnStr.empty()) - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "DSN name can not be empty."); - - diagnostic::DiagnosticRecordStorage diag; - - if (diag.GetStatusRecordsNumber() > 0) - { - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, - diag.GetStatusRecord(1).GetMessageText().c_str()); - } - cfg.SetDsn(dsnStr); cfg.SetTcpPort(port); cfg.SetHostname(hostnameStr); diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 1d025d4e6..0d120b27b 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -64,7 +64,7 @@ namespace ignite const std::string Configuration::DefaultValue::appName = "Amazon DocumentDB ODBC Driver"; const int32_t Configuration::DefaultValue::loginTimeoutSec = 0; const ReadPreference::Type Configuration::DefaultValue::readPreference = ReadPreference::Type::PRIMARY; - const std::string Configuration::DefaultValue::replicaSet = "rs0"; + const std::string Configuration::DefaultValue::replicaSet = ""; const bool Configuration::DefaultValue::retryReads = true; const int32_t Configuration::DefaultValue::defaultFetchSize = 2000; From 124142934f3c5ede9309ca691434c1bb16653376 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Wed, 26 Jan 2022 17:03:02 -0800 Subject: [PATCH 087/100] [AD-522] add end_point header to resolve build errors end_point related code still exist in connection.cpp, so I readded the header for end_point --- src/odbc/src/connection.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index b347c5035..066ffab76 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -28,6 +28,7 @@ #include "ignite/odbc/log.h" #include "ignite/odbc/utility.h" #include "ignite/odbc/environment.h" +#include "ignite/odbc/end_point.h" #include "ignite/odbc/statement.h" #include "ignite/odbc/connection.h" #include "ignite/odbc/message.h" From c66e84d4264595e146d7fab7d3ec52942bd7f85a Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 27 Jan 2022 10:58:54 -0800 Subject: [PATCH 088/100] Revert "Revert "Merge branch 'develop' into alinaliBQ/AD-522/config_window"" This reverts commit df0cad5490612c695ca28cc8ee44c73dbb1b68bd. --- .github/workflows/checks.yml | 1 - .github/workflows/mac-build.yml | 26 +- .github/workflows/mac-debug-build.yml | 1 + .github/workflows/win-build.yml | 79 +- README.md | 10 +- build_mac_debug64.sh | 21 + build_mac_release64.sh | 26 +- scripts/build_windows.ps1 | 15 + scripts/register_driver_macos.sh | 27 + .../include/ignite/common/big_integer.h | 2 +- src/common/include/ignite/common/decimal.h | 6 +- src/odbc-test/CMakeLists.txt | 43 +- src/odbc-test/config/ssh_config | 2 + src/odbc-test/include/odbc_test_suite.h | 12 +- src/odbc-test/include/test_utils.h | 47 +- src/odbc-test/src/connection_test.cpp | 86 +- src/odbc-test/src/odbc_test_suite.cpp | 27 +- src/odbc-test/src/test_utils.cpp | 95 +- src/odbc/CMakeLists.txt | 35 +- .../ignite/odbc/app/application_data_buffer.h | 2 +- .../include/ignite/odbc/common/big_integer.h | 526 ++++++++ src/odbc/include/ignite/odbc/common/bits.h | 221 ++++ .../include/ignite/odbc/common/concurrent.h | 605 +++++++++ src/odbc/include/ignite/odbc/common/decimal.h | 530 ++++++++ .../ignite/odbc/common/default_allocator.h | 92 ++ .../ignite/odbc/common/dynamic_size_array.h | 418 +++++++ .../include/ignite/odbc/common/expected.h | 303 +++++ .../ignite/odbc/common/fixed_size_array.h | 262 ++++ .../ignite/odbc/common/platform_utils.h | 126 ++ src/odbc/include/ignite/odbc/common/utils.h | 664 ++++++++++ src/odbc/include/ignite/odbc/connection.h | 31 +- src/odbc/include/ignite/odbc/ignite_error.h | 316 +++++ src/odbc/include/ignite/odbc/jni/java.h | 641 ++++++++++ src/odbc/include/ignite/odbc/jni/utils.h | 193 +++ src/odbc/include/ignite/odbc/log.h | 6 +- .../include/ignite/odbc/meta/column_meta.h | 2 +- .../ignite/odbc/meta/primary_key_meta.h | 2 +- src/odbc/include/ignite/odbc/odbc_error.h | 6 +- src/odbc/include/ignite/odbc/utility.h | 8 +- src/odbc/install/install_amd64.cmd | 3 +- .../linux/include/ignite/odbc/common/common.h | 56 + .../ignite/odbc/common/concurrent_os.h | 701 +++++++++++ .../os/linux/src/common/concurrent_os.cpp | 211 ++++ .../os/linux/src/common/platform_utils.cpp | 143 +++ .../win/include/ignite/odbc/common/common.h | 46 + .../ignite/odbc/common/concurrent_os.h | 610 +++++++++ src/odbc/os/win/src/common/concurrent_os.cpp | 208 ++++ src/odbc/os/win/src/common/platform_utils.cpp | 140 +++ src/odbc/os/win/src/system/ui/window.cpp | 8 +- src/odbc/src/app/application_data_buffer.cpp | 2 +- src/odbc/src/common/big_integer.cpp | 866 +++++++++++++ src/odbc/src/common/bits.cpp | 236 ++++ src/odbc/src/common/concurrent.cpp | 108 ++ src/odbc/src/common/decimal.cpp | 278 +++++ src/odbc/src/common/utils.cpp | 219 ++++ src/odbc/src/connection.cpp | 387 +++--- src/odbc/src/ignite_error.cpp | 227 ++++ src/odbc/src/jni/java.cpp | 1102 +++++++++++++++++ src/odbc/src/jni/os/linux/utils.cpp | 432 +++++++ src/odbc/src/jni/os/win/utils.cpp | 459 +++++++ src/odbc/src/log.cpp | 2 +- src/odbc/src/protocol_version.cpp | 2 +- src/odbc/src/ssl_mode.cpp | 2 +- src/odbc/src/utility.cpp | 10 +- 64 files changed, 11498 insertions(+), 475 deletions(-) create mode 100644 scripts/register_driver_macos.sh create mode 100644 src/odbc-test/config/ssh_config create mode 100644 src/odbc/include/ignite/odbc/common/big_integer.h create mode 100644 src/odbc/include/ignite/odbc/common/bits.h create mode 100644 src/odbc/include/ignite/odbc/common/concurrent.h create mode 100644 src/odbc/include/ignite/odbc/common/decimal.h create mode 100644 src/odbc/include/ignite/odbc/common/default_allocator.h create mode 100644 src/odbc/include/ignite/odbc/common/dynamic_size_array.h create mode 100644 src/odbc/include/ignite/odbc/common/expected.h create mode 100644 src/odbc/include/ignite/odbc/common/fixed_size_array.h create mode 100644 src/odbc/include/ignite/odbc/common/platform_utils.h create mode 100644 src/odbc/include/ignite/odbc/common/utils.h create mode 100644 src/odbc/include/ignite/odbc/ignite_error.h create mode 100644 src/odbc/include/ignite/odbc/jni/java.h create mode 100644 src/odbc/include/ignite/odbc/jni/utils.h create mode 100644 src/odbc/os/linux/include/ignite/odbc/common/common.h create mode 100644 src/odbc/os/linux/include/ignite/odbc/common/concurrent_os.h create mode 100644 src/odbc/os/linux/src/common/concurrent_os.cpp create mode 100644 src/odbc/os/linux/src/common/platform_utils.cpp create mode 100644 src/odbc/os/win/include/ignite/odbc/common/common.h create mode 100644 src/odbc/os/win/include/ignite/odbc/common/concurrent_os.h create mode 100644 src/odbc/os/win/src/common/concurrent_os.cpp create mode 100644 src/odbc/os/win/src/common/platform_utils.cpp create mode 100644 src/odbc/src/common/big_integer.cpp create mode 100644 src/odbc/src/common/bits.cpp create mode 100644 src/odbc/src/common/concurrent.cpp create mode 100644 src/odbc/src/common/decimal.cpp create mode 100644 src/odbc/src/common/utils.cpp create mode 100644 src/odbc/src/ignite_error.cpp create mode 100644 src/odbc/src/jni/java.cpp create mode 100644 src/odbc/src/jni/os/linux/utils.cpp create mode 100644 src/odbc/src/jni/os/win/utils.cpp diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index d3fec3b10..ac7484567 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -11,4 +11,3 @@ jobs: - uses: ZedThree/clang-tidy-review@v0.7.0 id: review continue-on-error: true - diff --git a/.github/workflows/mac-build.yml b/.github/workflows/mac-build.yml index 870a2b257..29368f323 100644 --- a/.github/workflows/mac-build.yml +++ b/.github/workflows/mac-build.yml @@ -12,9 +12,19 @@ on: env: CI_OUTPUT_PATH: "ci-output" - ODBC_LIB_PATH: "./build/odbc/lib" - ODBC_BIN_PATH: "./build/odbc/bin" - ODBC_BUILD_PATH: "./build/odbc/build" + ODBC_LIB_PATH: "${{github.workspace}}/build/odbc/lib" + ODBC_BIN_PATH: "${{github.workspace}}/build/odbc/bin" + ODBC_BUILD_PATH: "${{github.workspace}}/build/odbc/build" + DOCUMENTDB_HOME: "${{github.workspace}}/build/odbc/bin" + DOC_DB_KEYPAIR: ${{secrets.DOC_DB_KEYPAIR}} + DOC_DB_USER_NAME: ${{secrets.DOC_DB_USER_NAME}} + DOC_DB_PASSWORD: ${{secrets.DOC_DB_PASSWORD}} + DOC_DB_USER: ${{secrets.DOC_DB_USER}} + DOC_DB_HOST: ${{secrets.DOC_DB_HOST}} + DOC_DB_LOCAL_PORT: 27019 + DOC_DB_REMOTE_PORT: 27017 + DOC_DB_PRIV_KEY_FILE: ~/certs/docdb-sshtunnel.pem + JDBC_DRIVER_VERSION: "1.1.0" jobs: build-mac: @@ -37,6 +47,12 @@ jobs: # with: # name: cppcheck-results # path: cppcheck-results.log + - name: Extract key-pair into file + run: | + mkdir ~/certs + echo "${{env.DOC_DB_KEYPAIR}}" > ${{env.DOC_DB_PRIV_KEY_FILE}} + chmod 400 ${{env.DOC_DB_PRIV_KEY_FILE}} + - name: get-dependencies run: | brew install unixodbc @@ -54,6 +70,10 @@ jobs: # sudo cp ./src/Tests/Tests/odbc-mac.ini /Library/ODBC/odbc.ini # sudo cp ./src/Tests/Tests/odbcinst-mac.ini /Library/ODBC/odbcinst.ini # mkdir ${{ github.workspace }}/odbc-logs + - name: register-odbc-driver + run: | + chmod +x scripts/register_driver_macos.sh + ./scripts/register_driver_macos.sh - name: run-tests run: | ./build/odbc/bin/ignite-odbc-tests diff --git a/.github/workflows/mac-debug-build.yml b/.github/workflows/mac-debug-build.yml index 85468cd26..8d41ff8fb 100644 --- a/.github/workflows/mac-debug-build.yml +++ b/.github/workflows/mac-debug-build.yml @@ -8,6 +8,7 @@ env: ODBC_LIB_PATH: "./build/odbc/lib" ODBC_BIN_PATH: "./build/odbc/bin" ODBC_BUILD_PATH: "./build/odbc/build" + DOCUMENTDB_HOME: "./build/odbc/bin" jobs: build-mac: diff --git a/.github/workflows/win-build.yml b/.github/workflows/win-build.yml index ee0506351..b02b4b8f5 100644 --- a/.github/workflows/win-build.yml +++ b/.github/workflows/win-build.yml @@ -16,45 +16,75 @@ env: ODBC_BIN_PATH: "./build/odbc/bin/Release" ODBC_BUILD_PATH: "./build/odbc/cmake" VCPKG_ROOT: "c:/vcpkg" + DOCUMENTDB_HOME: "./build/odbc/bin/Release" + DOC_DB_KEYPAIR: ${{secrets.DOC_DB_KEYPAIR}} + DOC_DB_USER_NAME: ${{secrets.DOC_DB_USER_NAME}} + DOC_DB_PASSWORD: ${{secrets.DOC_DB_PASSWORD}} + DOC_DB_USER: ${{secrets.DOC_DB_USER}} + DOC_DB_HOST: ${{secrets.DOC_DB_HOST}} + RUN_REMOTE_INTEGRATION_TESTS: ${{ github.event.inputs.testWithoutDocumnetDb && 'false' || 'true' }} + DOC_DB_LOCAL_PORT: 27019 + DOC_DB_REMOTE_PORT: 27017 + DOC_DB_PRIV_KEY_FILE: ~/certs/docdb-sshtunnel.pem + JDBC_DRIVER_VERSION: "1.1.0" jobs: build-windows32: runs-on: windows-latest steps: - uses: actions/checkout@v2 + - name: Get Java distribution uses: actions/setup-java@v2 with: distribution: 'temurin' java-version: '17' architecture: x86 + - name: "Update path for Java" run: | echo "${{ env.JAVA_HOME }}\bin\server" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + - name: "Update path for WIX Toolset" run: | echo "C:\Program Files (x86)\WiX Toolset v3.11\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + - name: Get specific version CMake, v3.20.1 uses: lukka/get-cmake@v3.20.1 + - name: add-msbuild-to-path uses: microsoft/setup-msbuild@v1.0.2 + + - name: Extract key-pair into file + run: | + mkdir -p ~/certs + echo "${{env.DOC_DB_KEYPAIR}}" > ~/certs/docdb-sshtunnel.pem + chmod 400 ~/certs/docdb-sshtunnel.pem + mkdir -p ~/.ssh + copy ./src/odbc-test/config/ssh_config ~/.ssh/config + + #- name: Run SSH tunnel to DocumentDB server + # run: | + # ssh.exe -f -N -i ~/certs/docdb-sshtunnel.pem -L ${{env.DOC_DB_LOCAL_PORT}}:${{secrets.DOC_DB_HOST}}:${{env.DOC_DB_REMOTE_PORT}} ${{secrets.DOC_DB_USER}} + - name: Install dependencies Windows run: vcpkg integrate install; vcpkg install openssl:x86-windows boost-test:x86-windows boost-asio:x86-windows boost-chrono:x86-windows boost-interprocess:x86-windows boost-regex:x86-windows boost-system:x86-windows boost-thread:x86-windows env: VCPKG_ROOT: ${{ env.VCPKG_ROOT }} + - name: configure-and-build-driver run: | .\build_win_release32.ps1 env: OPENSSL_ROOT_DIR: '${{ env.VCPKG_ROOT }}/packages/openssl_x86-windows' - # - name: import-registry - # run: | - # reg import .\src\Tests\Tests\AWSProfileRegistry_Win32.reg - # reg import .\src\Tests\Tests\IAMRegistry_Win32.reg - # mkdir ${{ github.workspace }}\odbc-logs + + - name: register-driver + run: | + .\src\odbc\install\install_amd64.cmd ${{env.ODBC_BIN_PATH}}\ignite.odbc.dll ${{env.ODBC_BIN_PATH}}\ignite.odbc.dll + - name: run-tests run: | - ${{ env.ODBC_BIN_PATH }}/ignite-odbc-tests.exe + ${{env.ODBC_BIN_PATH}}/ignite-odbc-tests.exe # - name: upload-test-report # if: failure() # uses: actions/upload-artifact@v2 @@ -91,39 +121,58 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v2 + - name: Get Java distribution uses: actions/setup-java@v2 with: distribution: 'temurin' java-version: '17' architecture: x64 + - name: "Update path for Java" run: | - echo "${{ env.JAVA_HOME }}\bin\server" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + echo "${{env.JAVA_HOME}}\bin\server" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + - name: "Update path for WIX Toolset" run: | echo "C:\Program Files (x86)\WiX Toolset v3.11\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + - name: Get specific version CMake, v3.20.1 uses: lukka/get-cmake@v3.20.1 + - name: add-msbuild-to-path uses: microsoft/setup-msbuild@v1.0.2 + + - name: Extract key-pair into file + run: | + mkdir -p ~/certs + echo "${{env.DOC_DB_KEYPAIR}}" > ~/certs/docdb-sshtunnel.pem + chmod 400 ~/certs/docdb-sshtunnel.pem + mkdir -p ~/.ssh + copy ./src/odbc-test/config/ssh_config ~/.ssh/config + + #- name: Run SSH tunnel to DocumentDB server + # run: | + # ssh.exe -f -N -i ~/certs/docdb-sshtunnel.pem -L ${{env.DOC_DB_LOCAL_PORT}}:${{secrets.DOC_DB_HOST}}:${{env.DOC_DB_REMOTE_PORT}} ${{secrets.DOC_DB_USER}} + - name: Install dependencies Windows run: vcpkg integrate install; vcpkg install openssl:x64-windows boost-test:x64-windows boost-asio:x64-windows boost-chrono:x64-windows boost-interprocess:x64-windows boost-regex:x64-windows boost-system:x64-windows boost-thread:x64-windows env: - VCPKG_ROOT: ${{ env.VCPKG_ROOT }} + VCPKG_ROOT: ${{env.VCPKG_ROOT}} + - name: configure-and-build-driver run: | .\build_win_release64.ps1 env: - OPENSSL_ROOT_DIR: '${{ env.VCPKG_ROOT }}/packages/openssl_x64-windows' - # - name: import-registry - # run: | - # reg import .\src\Tests\Tests\AWSProfileRegistry.reg - # reg import .\src\Tests\Tests\IAMRegistry.reg - # mkdir ${{ github.workspace }}\odbc-logs + OPENSSL_ROOT_DIR: '${{env.VCPKG_ROOT}}/packages/openssl_x64-windows' + + - name: register-driver + run: | + .\src\odbc\install\install_amd64.cmd ${{env.ODBC_BIN_PATH}}\ignite.odbc.dll + - name: run-tests run: | - ${{ env.ODBC_BIN_PATH }}/ignite-odbc-tests.exe + ${{env.ODBC_BIN_PATH}}/ignite-odbc-tests.exe # - name: upload-test-report # if: failure() # uses: actions/upload-artifact@v2 diff --git a/README.md b/README.md index cb1308e83..7db369e0d 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,13 @@ 1. E.g.: `.\build_win_debug64.ps1` 2. Navigate to the `build\odbc\cmake` folder to use the generated solution file, `Ignite.C++.sln` to work on source code development and testing. -7. More details in `src\DEVNOTES.txt`. +7. Set the environment variable `DOCUMENTDB_HOME`. On a developer's machine, set it to `\build\odbc\bin\Debug`. The + build script run above, downloads it to the `\build\odbc\bin\Debug\libs` folder. +8. Open a **64-bit** command shell or **64-bit** PowerShell window, **as Administrator**, run the + ``` + \src\odbc\src\install\install_amd64.cmd \buildbuild\odbc\cmake\Debug\ignite.odbc.dll + ``` +8. More details in [`src\DEVNOTES.txt`](src/DEVNOTES.txt). ### MacOS @@ -44,7 +50,7 @@ 2. Run one of the build scripts to create an initial compilation. 1. E.g.: `./build_mac_release64.sh` 2. Navigate to the `build/odbc/lib` folder to use the generated files. -3. More details in `src\DEVNOTES.txt`. +3. More details in [`src\DEVNOTES.txt`](src/DEVNOTES.txt). ### Linux diff --git a/build_mac_debug64.sh b/build_mac_debug64.sh index 98222f20f..1118a04b9 100755 --- a/build_mac_debug64.sh +++ b/build_mac_debug64.sh @@ -1,5 +1,26 @@ + +BUILD_DIR=cmake-build64 +BUILD_TYPE=Debug +PROJECT_DIR=$(pwd) +DRIVER_BIN_DIR="$PROJECT_DIR/build/odbc/bin" + mkdir cmake-build64 cd cmake-build64 cmake ../src -DCMAKE_BUILD_TYPE="Debug" -DCODE_COVERAGE="ON" -DBUILD_SHARED_LIBS="OFF" -DWITH_TESTS="ON" -DWITH_CORE="OFF" -DWITH_ODBC="ON" +cd .. + +# Download the DocumentDB JDBC Driver +JDBC_DRIVER_VERSION="${JDBC_DRIVER_VERSION-1.1.0}" +JDBC_DRIVER_FILENAME="documentdb-jdbc-$JDBC_DRIVER_VERSION-all.jar" +JDBC_DRIVER_FULLPATH="$DRIVER_BIN_DIR/libs/$JDBC_DRIVER_FILENAME" +export DOCUMENTDB_HOME="$DRIVER_BIN_DIR" +if [ ! -f "$JDBC_DRIVER_FULLPATH" ]; then + mkdir "$DRIVER_BIN_DIR/libs" + echo "Downloading version $JDBC_DRIVER_VERSION of JDBC driver..." + curl -o "$DRIVER_BIN_DIR/libs/$JDBC_DRIVER_FILENAME" -L https://github.com/aws/amazon-documentdb-jdbc-driver/releases/download/v$JDBC_DRIVER_VERSION/$JDBC_DRIVER_FILENAME + echo "Download complete." +fi + +cd cmake-build64 make ccov-all -j 4 cd .. diff --git a/build_mac_release64.sh b/build_mac_release64.sh index b2f6bb36f..ca42d942e 100755 --- a/build_mac_release64.sh +++ b/build_mac_release64.sh @@ -1,5 +1,25 @@ -mkdir cmake-build64 -cd cmake-build64 -cmake ../src -DCMAKE_BUILD_TYPE="Release" -DCODE_COVERAGE="OFF" -DBUILD_SHARED_LIBS="OFF" -DWITH_TESTS="ON" -DWITH_CORE="OFF" -DWITH_ODBC="ON" + +BUILD_DIR=cmake-build64 +BUILD_TYPE=Release +PROJECT_DIR=$(pwd) +DRIVER_BIN_DIR="$PROJECT_DIR/build/odbc/bin" + +set -e +mkdir $BUILD_DIR +cd $BUILD_DIR +cmake ../src -DCMAKE_BUILD_TYPE="$BUILD_TYPE" -DCODE_COVERAGE="OFF" -DBUILD_SHARED_LIBS="OFF" -DWITH_TESTS="ON" -DWITH_CORE="OFF" -DWITH_ODBC="ON" make -j 4 + +# Download the DocumentDB JDBC Driver +JDBC_DRIVER_VERSION="${JDBC_DRIVER_VERSION-1.1.0}" +JDBC_DRIVER_FILENAME="documentdb-jdbc-$JDBC_DRIVER_VERSION-all.jar" +JDBC_DRIVER_FULLPATH="$DRIVER_BIN_DIR/libs/$JDBC_DRIVER_FILENAME" +export DOCUMENTDB_HOME="$DRIVER_BIN_DIR" +if [ ! -f "$JDBC_DRIVER_FULLPATH" ]; then + mkdir "$DRIVER_BIN_DIR/libs" + echo "Downloading version $JDBC_DRIVER_VERSION of JDBC driver..." + curl -o "$DRIVER_BIN_DIR/libs/$JDBC_DRIVER_FILENAME" -L https://github.com/aws/amazon-documentdb-jdbc-driver/releases/download/v$JDBC_DRIVER_VERSION/$JDBC_DRIVER_FILENAME + echo "Download complete." +fi + cd .. diff --git a/scripts/build_windows.ps1 b/scripts/build_windows.ps1 index 3e3d72988..3118170cf 100644 --- a/scripts/build_windows.ps1 +++ b/scripts/build_windows.ps1 @@ -28,6 +28,21 @@ Set-Location $CURRENT_DIR $DRIVER_BIN_DIR = "$DRIVER_BUILD_DIR\..\bin\$CONFIGURATION" New-Item -Path $DRIVER_BIN_DIR -ItemType Directory -Force | Out-Null +# Download the JDBC driver +$JDBC_DRIVER_VERSION = if ($JDBC_DRIVER_VERSION -eq $null) { "1.1.0" } else { $JDBC_DRIVER_VERSION } +$JDBC_DRIVER_FILENAME = "documentdb-jdbc-$JDBC_DRIVER_VERSION-all.jar" +$JDBC_DRIVER_FULLPATH = "$DRIVER_BIN_DIR\libs\$JDBC_DRIVER_FILENAME" +if (-not (Test-Path -Path $JDBC_DRIVER_FULLPATH -PathType Leaf)) { + New-Item -Path "$DRIVER_BIN_DIR\libs" -ItemType Directory -Force | Out-Null + Write-Output "Downloading version $JDBC_DRIVER_VERSION of JDBC driver..." + $progresspreference = 'silentlyContinue' + Invoke-WebRequest ` + https://github.com/aws/amazon-documentdb-jdbc-driver/releases/download/v$JDBC_DRIVER_VERSION/$JDBC_DRIVER_FILENAME ` + -o $JDBC_DRIVER_FULLPATH + $progressPreference = 'Continue' + Write-Output "Download complete." +} + if (Test-Path -Path $DRIVER_BUILD_DIR\$CONFIGURATION) { Copy-Item $DRIVER_BUILD_DIR\$CONFIGURATION\* $DRIVER_BIN_DIR } diff --git a/scripts/register_driver_macos.sh b/scripts/register_driver_macos.sh new file mode 100644 index 000000000..a5f4f6005 --- /dev/null +++ b/scripts/register_driver_macos.sh @@ -0,0 +1,27 @@ + +SOURCE="${BASH_SOURCE[0]}" +while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink + DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" + SOURCE="$(readlink "$SOURCE")" + [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located +done + +SCRIPT_DIR="$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )" + +PROJECT_DIR="$SCRIPT_DIR/.." +ODBC_LIB_PATH="$PROJECT_DIR/build/odbc/lib" +ODBC_LIB_FILENAME="$ODBC_LIB_PATH/libignite-odbc.dylib" + +if [ ! -f "$ODBC_LIB_FILENAME" ] +then + echo "Cannot find ODBC library file: $ODBC_LIB_FILENAME" + exit 1 +fi + +echo "[Apache Ignite]" > "$ODBC_LIB_PATH/ignite-odbc-install.ini" +echo "Description=Apache Ignite" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" +echo "Driver=$ODBC_LIB_FILENAME" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" +echo "Setup=$ODBC_LIB_FILENAME" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" +echo "DriverODBCVer=03.00" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" +echo "FileUsage=0" >> "$ODBC_LIB_PATH/ignite-odbc-install.ini" +odbcinst -i -d -f "$ODBC_LIB_PATH/ignite-odbc-install.ini" diff --git a/src/common/include/ignite/common/big_integer.h b/src/common/include/ignite/common/big_integer.h index 699f59e38..66aef6db0 100644 --- a/src/common/include/ignite/common/big_integer.h +++ b/src/common/include/ignite/common/big_integer.h @@ -383,7 +383,7 @@ namespace ignite // Reading number itself. while (is && isdigit(c)) { - part = part * 10 + (c - '0'); + part = part * 10 + (static_cast(c) - '0'); ++partDigits; if (part >= 1000000000000000000U) diff --git a/src/common/include/ignite/common/decimal.h b/src/common/include/ignite/common/decimal.h index d45297a29..39287264e 100644 --- a/src/common/include/ignite/common/decimal.h +++ b/src/common/include/ignite/common/decimal.h @@ -326,7 +326,7 @@ namespace ignite os << '0'; } - os.write(&magStr[magBegin], lastNonZero - magBegin + 1); + os.write(&magStr[magBegin], static_cast(lastNonZero) - magBegin + 1); } else { @@ -340,7 +340,7 @@ namespace ignite { os << '.'; - os.write(&magStr[magBegin + dotPos], afterDot); + os.write(&magStr[static_cast< std::basic_string< char, std::char_traits< char >, std::allocator< char > >::size_type >(magBegin) + dotPos], afterDot); } } @@ -395,7 +395,7 @@ namespace ignite { if (isdigit(c)) { - part = part * 10 + (c - '0'); + part = part * 10 + (static_cast(c) - '0'); ++partDigits; } else if (c == '.' && scale < 0) diff --git a/src/odbc-test/CMakeLists.txt b/src/odbc-test/CMakeLists.txt index f81e1a103..77294465b 100644 --- a/src/odbc-test/CMakeLists.txt +++ b/src/odbc-test/CMakeLists.txt @@ -29,29 +29,27 @@ find_package(ODBC REQUIRED) include_directories(SYSTEM ${ODBC_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${JNI_INCLUDE_DIRS}) include_directories(include ../odbc/include ../network/include) +if (WIN32) + include_directories(../odbc/os/win/include) +else () + # TODO: Ensure MacOS is portable. https://bitquill.atlassian.net/browse/AD-525 + include_directories(../odbc/os/linux/include) +endif() set(SOURCES + src/connection_test.cpp src/dummy_test.cpp - src/configuration_test.cpp - ../odbc/src/config/config_tools.cpp - ../odbc/src/config/configuration.cpp - ../odbc/src/config/connection_info.cpp - ../odbc/src/config/connection_string_parser.cpp - ../odbc/src/scan_method.cpp - ../odbc/src/read_preference.cpp - ../odbc/src/diagnostic/diagnostic_record.cpp - ../odbc/src/diagnostic/diagnostic_record_storage.cpp - ../odbc/src/utility.cpp - ../odbc/src/common_types.cpp - ../odbc/src/app/application_data_buffer.cpp - ../odbc/src/log.cpp + src/odbc_test_suite.cpp + src/test_utils.cpp + ../odbc/src/common/concurrent.cpp + ../odbc/src/common/utils.cpp + ../odbc/src/jni/java.cpp # TODO uncomment/rework the tests after get some connectivity and functionalities working. # src/teamcity/teamcity_boost.cpp # src/teamcity/teamcity_messages.cpp # src/parser_test.cpp # src/cursor_test.cpp # src/connection_info_test.cpp -# src/connection_test.cpp # src/application_data_buffer_test.cpp # src/column_test.cpp # src/configuration_test.cpp @@ -60,7 +58,6 @@ set(SOURCES # src/utility_test.cpp # src/queries_test.cpp # src/queries_ssl_test.cpp -# src/test_utils.cpp # src/sql_test_suite_fixture.cpp # src/sql_string_functions_test.cpp # src/sql_numeric_functions_test.cpp @@ -76,7 +73,6 @@ set(SOURCES # src/api_robustness_test.cpp # src/attributes_test.cpp # src/errors_test.cpp -# src/odbc_test_suite.cpp # src/types_test.cpp # src/transaction_test.cpp # src/authentication_test.cpp @@ -107,6 +103,21 @@ set(SOURCES # ../odbc/src/nested_tx_mode.cpp ) +if (WIN32) + list(APPEND SOURCES + ../odbc/os/win/src/common/concurrent_os.cpp + ../odbc/os/win/src/common/platform_utils.cpp + ../odbc/src/jni/os/win/utils.cpp + ) +else() + # TODO: Ensure MacOS is portable. https://bitquill.atlassian.net/browse/AD-525 + list(APPEND SOURCES + ../odbc/os/linux/src/common/concurrent_os.cpp + ../odbc/os/linux/src/common/platform_utils.cpp + ../odbc/src/jni/os/linux/utils.cpp + ) +endif() + add_executable(${TARGET} ${SOURCES}) target_link_libraries(${TARGET} ${Boost_LIBRARIES} ignite ${ODBC_LIBRARY}) diff --git a/src/odbc-test/config/ssh_config b/src/odbc-test/config/ssh_config new file mode 100644 index 000000000..6318ba0a5 --- /dev/null +++ b/src/odbc-test/config/ssh_config @@ -0,0 +1,2 @@ +Host * + StrictHostKeyChecking no diff --git a/src/odbc-test/include/odbc_test_suite.h b/src/odbc-test/include/odbc_test_suite.h index 1bdd3b077..6bd00a63a 100644 --- a/src/odbc-test/include/odbc_test_suite.h +++ b/src/odbc-test/include/odbc_test_suite.h @@ -75,7 +75,9 @@ namespace ignite * @param connectStr Connection string. * @return SQL State. */ - std::string ExpectConnectionReject(const std::string& connectStr); + std::string ExpectConnectionReject( + const std::string& connectStr, + const std::string& expectedError = "08001: Failed to establish connection with the host."); /** * Disconnect. @@ -87,14 +89,6 @@ namespace ignite */ void CleanUp(); - /** - * Start additional with the specified name and config. - * - * @param cfg Config path. - * @param name Instance name. - */ - static Ignite StartTestNode(const char* cfg, const char* name); - /** * Constructor. */ diff --git a/src/odbc-test/include/test_utils.h b/src/odbc-test/include/test_utils.h index f83b23b0c..dc7b01a80 100644 --- a/src/odbc-test/include/test_utils.h +++ b/src/odbc-test/include/test_utils.h @@ -27,7 +27,7 @@ #include -#include "ignite/ignition.h" +#include "ignite/odbc/common/utils.h" #define ODBC_THROW_ON_ERROR(ret, type, handle) \ if (!SQL_SUCCEEDED(ret)) \ @@ -160,51 +160,6 @@ namespace ignite_test */ std::string GetTestConfigDir(); - /** - * Initialize configuration for a node. - * - * Inits Ignite node configuration from specified config file. - * Config file is searched in path specified by IGNITE_NATIVE_TEST_CPP_CONFIG_PATH - * environmental variable. - * - * @param cfg Ignite config. - * @param cfgFile Ignite node config file name without path. - */ - void InitConfig(ignite::IgniteConfiguration& cfg, const char* cfgFile); - - /** - * Start Ignite node. - * - * Starts new Ignite node from specified config file. - * Config file is searched in path specified by IGNITE_NATIVE_TEST_CPP_CONFIG_PATH - * environmental variable. - * - * @param cfgFile Ignite node config file name without path. - * @return New node. - */ - ignite::Ignite StartNode(const char* cfgFile); - - /** - * Start Ignite node. - * - * Starts new Ignite node with the specified name and from specified config file. - * Config file is searched in path specified by IGNITE_NATIVE_TEST_CPP_CONFIG_PATH - * environmental variable. - * - * @param cfgFile Ignite node config file name without path. - * @param name Node name. - * @return New node. - */ - ignite::Ignite StartNode(const char* cfgFile, const char* name); - - /** - * Start node with the config for the current platform. - * - * @param cfg Basic config path. Changed to platform config if needed. - * @param name Instance name. - */ - ignite::Ignite StartPlatformNode(const char* cfg, const char* name); - /** * Remove all the LFS artifacts. */ diff --git a/src/odbc-test/src/connection_test.cpp b/src/odbc-test/src/connection_test.cpp index 6d4ed9a8e..28714a040 100644 --- a/src/odbc-test/src/connection_test.cpp +++ b/src/odbc-test/src/connection_test.cpp @@ -15,7 +15,6 @@ * limitations under the License. */ -#include "test_server.h" #ifdef _WIN32 # include #endif @@ -27,14 +26,10 @@ #include -#include "ignite/ignite.h" -#include "ignite/ignition.h" - #include "test_utils.h" #include "odbc_test_suite.h" using namespace ignite; -using namespace ignite::common; using namespace ignite_test; using namespace boost::unit_test; @@ -53,14 +48,6 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite // No-op. } - /** - * Start a node. - */ - void StartNode() - { - StartTestNode("queries-test.xml", "NodeMain"); - } - /** * Execute the query and return an error code. */ @@ -96,6 +83,25 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite return code; } + static void SetConnectionString(std::string& connectionString, + const std::string& username = std::string()) { + // NOTE: Assuming we are using internal SSH tunnel + std::string user = common::GetEnv("DOC_DB_USER_NAME", "documentdb"); + std::string password = common::GetEnv("DOC_DB_PASSWORD", ""); + std::string host = common::GetEnv("DOC_DB_HOST", ""); + std::string port = "27017"; + if (!username.empty()) { + user = username; + } + + connectionString = + "DRIVER={Apache Ignite};" + "ADDRESS=" + host + ":" + port + ";" + "SCHEMA=test;" + "USER=" + user + ";" + "PASSWORD=" + password + ";"; + } + /** * Destructor. */ @@ -105,44 +111,60 @@ struct ConnectionTestSuiteFixture: odbc::OdbcTestSuite } }; + BOOST_FIXTURE_TEST_SUITE(ConnectionTestSuite, ConnectionTestSuiteFixture) BOOST_AUTO_TEST_CASE(TestConnectionRestore) { - StartNode(); + std::string connectionString; + SetConnectionString(connectionString); - Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;SCHEMA=cache"); + Connect(connectionString); + Disconnect(); - // Check that query was successfully executed. - BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), ""); + // TODO: [AD-507] Re-enable when querying is supported. + // https://bitquill.atlassian.net/browse/AD-507 - // Stop node. - Ignition::StopAll(true); + //// Check that query was successfully executed. + //BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), ""); - // Query execution should throw ODBC error. - BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08S01"); + //// Query execution should throw ODBC error. + //BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08S01"); - // Reusing a closed connection should not crash an application. - BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08001"); + //// Reusing a closed connection should not crash an application. + //BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), "08001"); - StartNode(); + //// Check that connection was restored. + //BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), ""); - // Check that connection was restored. - BOOST_CHECK_EQUAL(ExecQueryAndReturnError(), ""); } BOOST_AUTO_TEST_CASE(TestConnectionMemoryLeak) { - TestServer testServer(11100); + std::string connectionString; + SetConnectionString(connectionString); - testServer.PushHandshakeResponse(true); - testServer.Start(); + Connect(connectionString); - Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11100;SCHEMA=cache"); - - ExecQuery("Select * from Test"); + // TODO: [AD-507] Re-enable when querying is supported. + // https://bitquill.atlassian.net/browse/AD-507 + // ExecQuery("Select * from Test"); Disconnect(); +} + +BOOST_AUTO_TEST_CASE(TestConnectionInvalidUser) { + std::string connectionString; + SetConnectionString(connectionString, "invaliduser"); + + ExpectConnectionReject(connectionString, "08001: Failed to establish connection with the host.\n" + "Invalid username or password or user is not authorized on database 'test'. " + "Please check your settings. Authorization failed for user 'invaliduser' on database 'admin' with mechanism"); + + // TODO: [AD-507] Re-enable when querying is supported. + // https://bitquill.atlassian.net/browse/AD-507 + // ExecQuery("Select * from Test"); + Disconnect(); } diff --git a/src/odbc-test/src/odbc_test_suite.cpp b/src/odbc-test/src/odbc_test_suite.cpp index bef4639e1..1b2ece743 100644 --- a/src/odbc-test/src/odbc_test_suite.cpp +++ b/src/odbc-test/src/odbc_test_suite.cpp @@ -24,10 +24,9 @@ #include -#include "ignite/ignition.h" - #include "test_utils.h" #include "odbc_test_suite.h" +#include using namespace ignite_test; using namespace boost::unit_test; @@ -103,7 +102,9 @@ namespace ignite BOOST_REQUIRE(stmt != NULL); } - std::string OdbcTestSuite::ExpectConnectionReject(const std::string& connectStr) + std::string OdbcTestSuite::ExpectConnectionReject( + const std::string& connectStr, + const std::string& expectedError) { Prepare(); @@ -118,6 +119,9 @@ namespace ignite outstr, sizeof(outstr), &outstrlen, SQL_DRIVER_COMPLETE); BOOST_REQUIRE_EQUAL(ret, SQL_ERROR); + BOOST_REQUIRE_EQUAL(expectedError, + GetOdbcErrorMessage(SQL_HANDLE_DBC, dbc) + .substr(0, expectedError.size())); return GetOdbcErrorState(SQL_HANDLE_DBC, dbc); } @@ -154,19 +158,6 @@ namespace ignite } } - Ignite OdbcTestSuite::StartTestNode(const char* cfg, const char* name) - { - std::string config(cfg); - -#ifdef IGNITE_TESTS_32 - // Cutting off the ".xml" part. - config.resize(config.size() - 4); - config += "-32.xml"; -#endif //IGNITE_TESTS_32 - - return StartNode(config.c_str(), name); - } - OdbcTestSuite::OdbcTestSuite(): env(NULL), dbc(NULL), @@ -178,8 +169,6 @@ namespace ignite OdbcTestSuite::~OdbcTestSuite() { CleanUp(); - - Ignition::StopAll(true); } int8_t OdbcTestSuite::GetTestI8Field(int64_t idx) @@ -347,7 +336,7 @@ namespace ignite { BOOST_TEST_CONTEXT("Test index: " << idx) { - common::FixedSizeArray expected(static_cast(valLen)); + odbc::common::FixedSizeArray expected(static_cast(valLen)); GetTestI8ArrayField(idx, expected.GetData(), expected.GetSize()); for (size_t j = 0; j < valLen; ++j) diff --git a/src/odbc-test/src/test_utils.cpp b/src/odbc-test/src/test_utils.cpp index bdd32d8af..aa4e654b5 100644 --- a/src/odbc-test/src/test_utils.cpp +++ b/src/odbc-test/src/test_utils.cpp @@ -19,10 +19,13 @@ #include -#include +#include +#include "ignite/odbc/jni/utils.h" + #include "test_utils.h" + namespace ignite_test { OdbcClientError GetOdbcError(SQLSMALLINT handleType, SQLHANDLE handle) @@ -75,14 +78,14 @@ namespace ignite_test std::string GetTestConfigDir() { - using namespace ignite; + using namespace ignite::odbc; std::string cfgPath = common::GetEnv("IGNITE_NATIVE_TEST_ODBC_CONFIG_PATH"); if (!cfgPath.empty()) return cfgPath; - std::string home = jni::ResolveIgniteHome(); + std::string home = jni::ResolveDocumentDbHome(); if (home.empty()) return home; @@ -99,100 +102,20 @@ namespace ignite_test return path.str(); } - void InitConfig(ignite::IgniteConfiguration& cfg, const char* cfgFile) - { - using namespace ignite; - - assert(cfgFile != 0); - - cfg.jvmOpts.push_back("-Xdebug"); - cfg.jvmOpts.push_back("-Xnoagent"); - cfg.jvmOpts.push_back("-Djava.compiler=NONE"); - cfg.jvmOpts.push_back("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"); - cfg.jvmOpts.push_back("-XX:+HeapDumpOnOutOfMemoryError"); - cfg.jvmOpts.push_back("-Duser.timezone=GMT"); - cfg.jvmOpts.push_back("-DIGNITE_QUIET=false"); - cfg.jvmOpts.push_back("-DIGNITE_CONSOLE_APPENDER=false"); - cfg.jvmOpts.push_back("-DIGNITE_UPDATE_NOTIFIER=false"); - cfg.jvmOpts.push_back("-DIGNITE_LOG_CLASSPATH_CONTENT_ON_STARTUP=false"); - cfg.jvmOpts.push_back("-Duser.language=en"); - // Un-comment to debug SSL - //cfg.jvmOpts.push_back("-Djavax.net.debug=ssl"); - - cfg.igniteHome = jni::ResolveIgniteHome(); - cfg.jvmClassPath = jni::CreateIgniteHomeClasspath(cfg.igniteHome, true); - -#ifdef IGNITE_TESTS_32 - cfg.jvmInitMem = 256; - cfg.jvmMaxMem = 768; -#else - cfg.jvmInitMem = 1024; - cfg.jvmMaxMem = 4096; -#endif - - std::string cfgDir = GetTestConfigDir(); - - if (cfgDir.empty()) - throw IgniteError(IgniteError::IGNITE_ERR_GENERIC, "Failed to resolve test config directory"); - - std::stringstream path; - - path << cfgDir << common::Fs << cfgFile; - - cfg.springCfgPath = path.str(); - } - - ignite::Ignite StartNode(const char* cfgFile) - { - using namespace ignite; - - IgniteConfiguration cfg; - - InitConfig(cfg, cfgFile); - - return Ignition::Start(cfg); - } - - ignite::Ignite StartNode(const char* cfgFile, const char* name) - { - using namespace ignite; - - assert(name != 0); - - IgniteConfiguration cfg; - - InitConfig(cfg, cfgFile); - - return Ignition::Start(cfg, name); - } - - ignite::Ignite StartPlatformNode(const char* cfg, const char* name) - { - std::string config(cfg); - -#ifdef IGNITE_TESTS_32 - // Cutting off the ".xml" part. - config.resize(config.size() - 4); - config += "-32.xml"; -#endif //IGNITE_TESTS_32 - - return StartNode(config.c_str(), name); - } - std::string AppendPath(const std::string& base, const std::string& toAdd) { std::stringstream stream; - stream << base << ignite::common::Fs << toAdd; + stream << base << ignite::odbc::common::Fs << toAdd; return stream.str(); } void ClearLfs() { - std::string home = ignite::jni::ResolveIgniteHome(); + std::string home = ignite::odbc::jni::ResolveDocumentDbHome(); std::string workDir = AppendPath(home, "work"); - ignite::common::DeletePath(workDir); + ignite::odbc::common::DeletePath(workDir); } } diff --git a/src/odbc/CMakeLists.txt b/src/odbc/CMakeLists.txt index e2021f3e7..0c6c45caa 100644 --- a/src/odbc/CMakeLists.txt +++ b/src/odbc/CMakeLists.txt @@ -20,14 +20,23 @@ project(ignite-odbc) set(TARGET ${PROJECT_NAME}) find_package(ODBC REQUIRED) +find_package(Java REQUIRED) +find_package(JNI REQUIRED) +include(UseJava) -include_directories(SYSTEM ${ODBC_INCLUDE_DIRS}) +include_directories(SYSTEM ${ODBC_INCLUDE_DIRS} ${JNI_INCLUDE_DIRS}) include_directories(include) set(SOURCES src/app/application_data_buffer.cpp src/app/parameter.cpp src/app/parameter_set.cpp src/common_types.cpp + src/common/big_integer.cpp + src/common/bits.cpp + src/common/concurrent.cpp + src/common/decimal.cpp + src/ignite_error.cpp + src/common/utils.cpp src/config/config_tools.cpp src/config/configuration.cpp src/config/connection_info.cpp @@ -37,6 +46,7 @@ set(SOURCES src/app/application_data_buffer.cpp src/diagnostic/diagnosable_adapter.cpp src/diagnostic/diagnostic_record.cpp src/diagnostic/diagnostic_record_storage.cpp + src/jni/java.cpp src/environment.cpp src/meta/column_meta.cpp src/meta/table_meta.cpp @@ -73,20 +83,37 @@ set(SOURCES src/app/application_data_buffer.cpp src/scan_method.cpp) if (WIN32) - include_directories(os/win/include) + set(OS_INCLUDE os/win/include) - list(APPEND SOURCES os/win/src/system_dsn.cpp + list(APPEND SOURCES + os/win/src/system_dsn.cpp os/win/src/system/ui/custom_window.cpp os/win/src/system/ui/dsn_configuration_window.cpp os/win/src/system/ui/window.cpp - module.def) + os/win/src/common/concurrent_os.cpp + os/win/src/common/platform_utils.cpp + src/jni/os/win/utils.cpp + module.def + ) +else() + set(OS_INCLUDE os/linux/include) + + list(APPEND SOURCES + os/linux/src/common/concurrent_os.cpp + os/linux/src/common/platform_utils.cpp + src/jni/os/linux/utils.cpp + ) endif () +include_directories(${OS_INCLUDE}) + + add_library(${TARGET} SHARED ${SOURCES}) set_target_properties(${TARGET} PROPERTIES VERSION ${CMAKE_PROJECT_VERSION}) target_link_libraries(${TARGET} ${ODBC_LIBRARIES}) +target_link_libraries(${TARGET} ${JNI_LIBRARIES}) if (WIN32) target_link_libraries(${TARGET} ignite-common-objlib ignite-binary-objlib ignite-network-objlib odbccp32 shlwapi) diff --git a/src/odbc/include/ignite/odbc/app/application_data_buffer.h b/src/odbc/include/ignite/odbc/app/application_data_buffer.h index 50d324488..af0231b46 100644 --- a/src/odbc/include/ignite/odbc/app/application_data_buffer.h +++ b/src/odbc/include/ignite/odbc/app/application_data_buffer.h @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include "ignite/odbc/common_types.h" #include "ignite/odbc/type_traits.h" diff --git a/src/odbc/include/ignite/odbc/common/big_integer.h b/src/odbc/include/ignite/odbc/common/big_integer.h new file mode 100644 index 000000000..4e06543a3 --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/big_integer.h @@ -0,0 +1,526 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_ODBC_COMMON_BIG_INTEGER +#define _IGNITE_ODBC_COMMON_BIG_INTEGER + +#include + +#include +#include + +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + /** + * Big integer number implementation. + */ + class IGNITE_IMPORT_EXPORT BigInteger + { + friend class Decimal; + public: + // Magnitude array type. + typedef DynamicSizeArray MagArray; + + /** + * Default constructor. Constructs zero-value big integer. + */ + BigInteger(); + + /** + * Constructs big integer with the specified integer value. + * + * @param val Value. + */ + explicit BigInteger(int64_t val); + + /** + * String constructor. + * + * @param val String to assign. + * @param len String length. + */ + BigInteger(const char* val, int32_t len); + + /** + * String constructor. + * + * @param val String to assign. + */ + explicit BigInteger(const std::string& val) : + sign(1), + mag() + { + AssignString(val); + } + + /** + * Copy constructor. + * + * @param other Other value. + */ + BigInteger(const BigInteger& other); + + /** + * Constructs big integer from the byte array. + * + * @param val Bytes of the integer. Byte order is big-endian. + * @param len Array length. + * @param sign Signum. Can be -1 (negative) or 1 (positive or zero). + * @param bigEndian If true then magnitude is in big-endian. Otherwise + * the byte order of the magnitude considered to be little-endian. + */ + BigInteger(const int8_t* val, int32_t len, int32_t sign, bool bigEndian = true); + + /** + * Constructs big integer with the specified magnitude. + * @warning Magnitude is moved. This mean mag left empty after the call. + * + * @param mag Magnitude. Moved. + * @param sign Sign. Can be 1 or -1. + */ + BigInteger(MagArray& mag, int8_t sign); + + /** + * Assigment operator. + * + * @param other Other value. + * @return *this. + */ + BigInteger& operator=(const BigInteger& other); + + /** + * Assign specified value to this BigInteger. + * + * @param val Value to assign. + */ + void Assign(const BigInteger& val); + + /** + * Assign specified value to this BigInteger. + * + * @param val Value to assign. + */ + void AssignInt64(int64_t val); + + /** + * Assign specified value to this Decimal. + * + * @param val String to assign. + */ + void AssignString(const std::string& val) + { + AssignString(val.data(), static_cast(val.size())); + } + + /** + * Assign specified value to this Decimal. + * + * @param val String to assign. + * @param len String length. + */ + void AssignString(const char* val, int32_t len); + + /** + * Assign specified value to this BigInteger. + * + * @param val Value to assign. + */ + void AssignUint64(uint64_t val); + + /** + * Get number sign. Returns -1 if negative and 1 otherwise. + * + * @return Sign of the number. + */ + int8_t GetSign() const; + + /** + * Swap function for the BigInteger type. + * + * @param other Other instance. + */ + void Swap(BigInteger& other); + + /** + * Get magnitude array. + * + * @return magnitude array. + */ + const MagArray& GetMagnitude() const; + + /** + * Get this number length in bits as if it was positive. + * + * @return Number length in bits. + */ + uint32_t GetBitLength() const; + + /** + * Get precision of the BigInteger. + * + * @return Number of the decimal digits in the decimal representation + * of the value. + */ + int32_t GetPrecision() const; + + /** + * Fills specified buffer with data of this BigInteger converted to + * bytes in big-endian byte order. Sign is not considered when this + * operation is performed. + * + * @param buffer Buffer to fill. + */ + void MagnitudeToBytes(common::FixedSizeArray& buffer) const; + + /** + * Mutates this BigInteger so its value becomes exp power of this. + * + * @param exp Exponent. + */ + void Pow(int32_t exp); + + /** + * Muitiply this to another big integer. + * + * @param other Another instance. Can be *this. + * @param res Result placed there. Can be *this. + */ + void Multiply(const BigInteger& other, BigInteger& res) const; + + /** + * Divide this to another big integer. + * + * @param divisor Divisor. Can be *this. + * @param res Result placed there. Can be *this. + */ + void Divide(const BigInteger& divisor, BigInteger& res) const; + + /** + * Divide this to another big integer. + * + * @param divisor Divisor. Can be *this. + * @param res Result placed there. Can be *this. + * @param rem Remainder placed there. Can be *this. + */ + void Divide(const BigInteger& divisor, BigInteger& res, BigInteger& rem) const; + + /** + * Add unsigned integer number to this BigInteger. + * + * @param x Number to add. + */ + void Add(uint64_t x); + + /** + * Compare this instance to another. + * + * @param other Another instance. + * @param ignoreSign If set to true than only magnitudes are compared. + * @return Comparasion result - 0 if equal, 1 if this is greater, -1 if + * this is less. + */ + int32_t Compare(const BigInteger& other, bool ignoreSign = false) const; + + /** + * Convert to int64_t. + * + * @return int64_t value. + */ + int64_t ToInt64() const; + + /** + * Check whether this value is negative. + * + * @return True if this value is negative and false otherwise. + */ + bool IsNegative() const + { + return sign < 0; + } + + /** + * Check whether this value is zero. + * + * @return True if this value is negative and false otherwise. + */ + bool IsZero() const + { + return mag.GetSize() == 0; + } + + /** + * Check whether this value is positive. + * + * @return True if this value is positive and false otherwise. + */ + bool IsPositive() const + { + return sign > 0 && !IsZero(); + } + + /** + * Rverses sign of this value. + */ + void Negate() + { + if (!IsZero()) + sign = -sign; + } + + /** + * Output operator. + * + * @param os Output stream. + * @param val Value to output. + * @return Reference to the first param. + */ + friend std::ostream& operator<<(std::ostream& os, const BigInteger& val) + { + if (val.IsZero()) + return os << '0'; + + if (val.sign < 0) + os << '-'; + + const int32_t maxResultDigits = 19; + BigInteger maxUintTenPower; + BigInteger res; + BigInteger left; + + maxUintTenPower.AssignUint64(10000000000000000000U); + + std::vector vals; + + val.Divide(maxUintTenPower, left, res); + + if (res.sign < 0) + res.sign = -res.sign; + + if (left.sign < 0) + left.sign = -left.sign; + + vals.push_back(static_cast(res.ToInt64())); + + while (!left.IsZero()) + { + left.Divide(maxUintTenPower, left, res); + + vals.push_back(static_cast(res.ToInt64())); + } + + os << vals.back(); + + for (int32_t i = static_cast(vals.size()) - 2; i >= 0; --i) + { + os.fill('0'); + os.width(maxResultDigits); + + os << vals[i]; + } + + return os; + } + + /** + * Input operator. + * + * @param is Input stream. + * @param val Value to input. + * @return Reference to the first param. + */ + friend std::istream& operator>>(std::istream& is, BigInteger& val) + { + std::istream::sentry sentry(is); + + // Return zero if input failed. + val.AssignInt64(0); + + if (!is) + return is; + + // Current value parts. + uint64_t part = 0; + int32_t partDigits = 0; + int32_t sign = 1; + + BigInteger pow; + BigInteger bigPart; + + // Current char. + int c = is.peek(); + + if (!is) + return is; + + // Checking sign. + if (c == '-' || c == '+') + { + if (c == '-') + sign = -1; + + is.ignore(); + c = is.peek(); + } + + // Reading number itself. + while (is && isdigit(c)) + { + part = part * 10 + (static_cast(c) - '0'); + ++partDigits; + + if (part >= 1000000000000000000U) + { + BigInteger::GetPowerOfTen(partDigits, pow); + val.Multiply(pow, val); + + val.Add(part); + + part = 0; + partDigits = 0; + } + + is.ignore(); + c = is.peek(); + } + + // Adding last part of the number. + if (partDigits) + { + BigInteger::GetPowerOfTen(partDigits, pow); + + val.Multiply(pow, val); + + val.Add(part); + } + + if (sign < 0) + val.Negate(); + + return is; + } + + /** + * Get BigInteger which value is the ten of the specified power. + * + * @param pow Tenth power. + * @param res Result is placed here. + */ + static void GetPowerOfTen(int32_t pow, BigInteger& res); + + private: + /** + * Add magnitude array to current. + * + * @param addend Addend. + * @param len Length of the addend. + */ + void Add(const uint32_t* addend, int32_t len); + + /** + * Get n-th integer of the magnitude. + * + * @param n Index. + * @return Value of the n-th int of the magnitude. + */ + uint32_t GetMagInt(int32_t n) const; + + /** + * Divide this to another big integer. + * + * @param divisor Divisor. Can be *this. + * @param res Result placed there. Can be *this. + * @param rem Remainder placed there if requested. Can be *this. + * Can be null if the remainder is not needed. + */ + void Divide(const BigInteger& divisor, BigInteger& res, BigInteger* rem) const; + + /** + * Normalizes current value removing trailing zeroes from the magnitude. + */ + void Normalize(); + + /** The sign of this BigInteger: -1 for negative and 1 for non-negative. */ + int8_t sign; + + /** The magnitude of this BigInteger. Byte order is little-endian. */ + MagArray mag; + }; + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if equal. + */ + IGNITE_IMPORT_EXPORT bool operator==(const BigInteger& val1, const BigInteger& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if not equal. + */ + IGNITE_IMPORT_EXPORT bool operator!=(const BigInteger& val1, const BigInteger& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if less. + */ + IGNITE_IMPORT_EXPORT bool operator<(const BigInteger& val1, const BigInteger& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if less or equal. + */ + IGNITE_IMPORT_EXPORT bool operator<=(const BigInteger& val1, const BigInteger& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if gretter. + */ + IGNITE_IMPORT_EXPORT bool operator>(const BigInteger& val1, const BigInteger& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if gretter or equal. + */ + IGNITE_IMPORT_EXPORT bool operator>=(const BigInteger& val1, const BigInteger& val2); + } + } +} + +#endif //_IGNITE_ODBC_COMMON_BIG_INTEGER diff --git a/src/odbc/include/ignite/odbc/common/bits.h b/src/odbc/include/ignite/odbc/common/bits.h new file mode 100644 index 000000000..d53a78e37 --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/bits.h @@ -0,0 +1,221 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _IGNITE_ODBC_COMMON_BITS +#define _IGNITE_ODBC_COMMON_BITS + +#include + +#include +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + namespace bits + { + /** + * Maximum number of digits in uint64_t number. + */ + const int32_t UINT64_MAX_PRECISION = 20; + + /** + * Get number of trailing zero bits in the two's complement binary + * representation of the specified 32-bit int value. + * + * @param i The value whose bits are to be counted. + * @return The number of trailing zero bits in the two's complement + * binary representation of the specified 32-bit int value. + */ + IGNITE_IMPORT_EXPORT int32_t NumberOfTrailingZerosI32(int32_t i); + + /** + * Get number of leading zero bits in the two's complement binary + * representation of the specified 32-bit int value. + * + * @param i The value whose bits are to be counted. + * @return The number of leading zero bits in the two's complement + * binary representation of the specified 32-bit int value. + */ + IGNITE_IMPORT_EXPORT int32_t NumberOfLeadingZerosI32(int32_t i); + + /** + * Get number of leading zero bits in the two's complement binary + * representation of the specified 32-bit int value. + * + * @param i The value whose bits are to be counted. + * @return The number of leading zero bits in the two's complement + * binary representation of the specified 32-bit int value. + */ + IGNITE_IMPORT_EXPORT int32_t NumberOfLeadingZerosU32(uint32_t i); + + /** + * Get number of leading zero bits in the two's complement binary + * representation of the specified 64-bit int value. + * + * @param i The value whose bits are to be counted. + * @return The number of leading zero bits in the two's complement + * binary representation of the specified 64-bit int value. + */ + IGNITE_IMPORT_EXPORT int32_t NumberOfLeadingZerosI64(int64_t i); + + /** + * Get number of leading zero bits in the two's complement binary + * representation of the specified 64-bit int value. + * + * @param i The value whose bits are to be counted. + * @return The number of leading zero bits in the two's complement + * binary representation of the specified 64-bit int value. + */ + IGNITE_IMPORT_EXPORT int32_t NumberOfLeadingZerosU64(uint64_t i); + + /** + * Get the number of one-bits in the two's complement binary + * representation of the specified 32-bit int value. + * + * @param i The value whose bits are to be counted. + * @return The number of one-bits in the two's complement binary + * representation of the specified 32-bit int value. + */ + IGNITE_IMPORT_EXPORT int32_t BitCountI32(int32_t i); + + /** + * Get bit length for the specified signed 32-bit int value. + * + * @param i The value to get bit length for. + * @return The number of significant bits in the two's complement binary + * representation of the specified 32-bit int value. + */ + IGNITE_IMPORT_EXPORT int32_t BitLengthI32(int32_t i); + + /** + * Get bit length for the specified unsigned 32-bit int value. + * + * @param i The value to get bit length for. + * @return The number of significant bits in the two's complement binary + * representation of the specified 32-bit int value. + */ + IGNITE_IMPORT_EXPORT int32_t BitLengthU32(uint32_t i); + + /** + * Calcutale capasity for required size. + * Rounds up to the nearest power of two. + * + * @param size Needed capasity. + * @return Recomended capasity to allocate. + */ + IGNITE_IMPORT_EXPORT int32_t GetCapasityForSize(int32_t size); + + /** + * Get the number of decimal digits of the integer value. + * + * @param x The value. + * @return The number of decimal digits of the integer value. + */ + IGNITE_IMPORT_EXPORT int32_t DigitLength(uint64_t x); + + /** + * Get n-th power of ten. + * + * @param n Power. Should be in range [0, UINT64_MAX_PRECISION] + * @return 10 pow n, if n is in range [0, UINT64_MAX_PRECISION]. + * Otherwise, behaviour is undefined. + */ + IGNITE_IMPORT_EXPORT uint64_t TenPowerU64(int32_t n); + + /** + * Get the signum function of the specified 64-bit integer value. + * The return value is -1 if the specified value is negative; 0 if the + * specified value is zero; and 1 if the specified value is positive. + * + * @param i the value whose signum is to be computed + * @return The signum function of the specified value. + */ + inline int32_t Signum64(int64_t i) + { + return (static_cast(-i) >> 63) | (i >> 63); + } + + /** + * Makes single 64-bit integer number out of two 32-bit numbers. + * + * @param higher Higher bits part. + * @param lower Lower bits part. + * @return New 64-bit integer. + */ + inline uint64_t MakeU64(uint32_t higher, uint32_t lower) + { + return (static_cast(higher) << 32) | lower; + } + + /** + * Makes single 64-bit integer number out of two 32-bit numbers. + * + * @param higher Higher bits part. + * @param lower Lower bits part. + * @return New 64-bit integer. + */ + inline int64_t MakeI64(uint32_t higher, uint32_t lower) + { + return static_cast(MakeU64(higher, lower)); + } + + /** + * Makes single 32-bit integer number out of two 32-bit numbers, + * shifted by specified number of bits. First number x is shifted + * to the left. + * x y + * [........][........] + * ^[........] + * n res + * + * @param x First part. + * @param y Second part. + * @param n Number of bits to shift. + * @return New 32-bit integer. + */ + inline uint32_t MakeU32(uint32_t x, uint32_t y, int32_t n) + { + return (x << n) | (y >> (32 - n)); + } + + /** + * Makes single 32-bit integer number out of two 32-bit numbers, + * shifted by specified number of bits. First number x is shifted + * to the left. + * x y + * [........][........] + * ^[........] + * n res + * + * @param x First part. + * @param y Second part. + * @param n Number of bits to shift. + * @return New 32-bit integer. + */ + inline int32_t MakeI32(uint32_t x, uint32_t y, int32_t n) + { + return static_cast(MakeU32(x, y, n)); + } + } + } + } +} + +#endif //_IGNITE_ODBC_COMMON_BITS diff --git a/src/odbc/include/ignite/odbc/common/concurrent.h b/src/odbc/include/ignite/odbc/common/concurrent.h new file mode 100644 index 000000000..c0615f22a --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/concurrent.h @@ -0,0 +1,605 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_ODBC_COMMON_CONCURRENT +#define _IGNITE_ODBC_COMMON_CONCURRENT + +#include +#include + +#include "ignite/odbc/common/concurrent_os.h" + +namespace ignite +{ + namespace odbc + { + namespace common + { + namespace concurrent + { + /** + * Type tag for static pointer cast. + */ + struct StaticTag {}; + + /** + * Default deleter implementation. + * + * @param obj Object to be deleted. + */ + template + IGNITE_IMPORT_EXPORT void SharedPointerDefaultDeleter(T* obj) + { + delete obj; + } + + /** + * Empty deleter implementation. + * + * @param obj Object to be deleted. + */ + template + IGNITE_IMPORT_EXPORT void SharedPointerEmptyDeleter(T*) + { + // No-op. + } + + /** + * Holder of shared pointer data. + */ + class IGNITE_IMPORT_EXPORT SharedPointerImpl + { + public: + typedef void(*DeleterType)(void*); + /** + * Constructor. + * + * @param ptr Raw pointer. + */ + SharedPointerImpl(void* ptr, DeleterType deleter); + + /** + * Get raw pointer. + * + * @return Raw pointer. + */ + void* Pointer(); + + /** + * Get raw pointer. + * + * @return Raw pointer. + */ + const void* Pointer() const; + + /** + * Get raw pointer. + * + * @return Raw pointer. + */ + DeleterType Deleter(); + + /** + * Increment usage counter. + */ + void Increment(); + + /** + * Decrement usage counter. + * + * @return True if counter reached zero. + */ + bool Decrement(); + private: + /** Raw pointer. */ + void* ptr; + + /** Deleter. */ + DeleterType deleter; + + /** Reference count. */ + int32_t refCnt; + + IGNITE_NO_COPY_ASSIGNMENT(SharedPointerImpl); + }; + + /* Forward declaration. */ + template + class IGNITE_IMPORT_EXPORT EnableSharedFromThis; + + /* Forward declaration. */ + template + inline void ImplEnableShared(EnableSharedFromThis* some, SharedPointerImpl* impl); + + // Do nothing if the instance is not derived from EnableSharedFromThis. + inline void ImplEnableShared(const volatile void*, const volatile void*) + { + // No-op. + } + + /** + * Shared pointer. + */ + template + class IGNITE_IMPORT_EXPORT SharedPointer + { + public: + friend class EnableSharedFromThis; + + template + friend class SharedPointer; + + /** + * Constructor. + */ + SharedPointer() : + ptr(0), + impl(0) + { + // No-op. + } + + /** + * Constructor. + * + * @param ptr Raw pointer. + * @param deleter Delete function. + */ + SharedPointer(T* ptr, void(*deleter)(T*) = &SharedPointerDefaultDeleter) : + ptr(ptr), + impl(0) + { + if (ptr) + { + impl = new SharedPointerImpl(ptr, reinterpret_cast(deleter)); + ImplEnableShared(ptr, impl); + } + } + + /** + * Constructor. + * + * @param ptr Raw pointer. + * @param deleter Delete function. + */ + template + SharedPointer(T2* ptr, void(*deleter)(T2*) = &SharedPointerDefaultDeleter) : + ptr(ptr), + impl(0) + { + if (ptr) + { + impl = new SharedPointerImpl(ptr, reinterpret_cast(deleter)); + ImplEnableShared(ptr, impl); + } + } + + /** + * Copy constructor. + * + * @param other Instance to copy. + */ + SharedPointer(const SharedPointer& other) : + ptr(other.ptr), + impl(other.impl) + { + if (impl) + impl->Increment(); + } + + /** + * Copy constructor. + * + * @param other Instance to copy. + */ + template + SharedPointer(const SharedPointer& other) : + ptr(other.ptr), + impl(other.impl) + { + if (impl) + impl->Increment(); + } + + /** + * Static-cast constructor. + * + * @param other Instance to copy. + */ + template + SharedPointer(const SharedPointer& other, StaticTag) : + ptr(static_cast(other.ptr)), + impl(other.impl) + { + if (impl) + impl->Increment(); + } + + /** + * Assignment operator. + * + * @param other Other instance. + */ + SharedPointer& operator=(const SharedPointer& other) + { + if (this != &other) + { + SharedPointer tmp(other); + + Swap(tmp); + } + + return *this; + } + + /** + * Assignment operator. + * + * @param other Other instance. + */ + template + SharedPointer& operator=(const SharedPointer& other) + { + SharedPointer tmp(other); + + Swap(tmp); + + return *this; + } + + /** + * Destructor. + */ + ~SharedPointer() + { + if (impl && impl->Decrement()) + { + void* ptr0 = impl->Pointer(); + + void(*deleter)(void*) = impl->Deleter(); + + deleter(ptr0); + + delete impl; + + ptr = 0; + } + } + + /** + * Get raw pointer. + * + * @return Raw pointer. + */ + T* Get() + { + return ptr; + } + + /** + * Get raw pointer. + * + * @return Raw pointer. + */ + const T* Get() const + { + return ptr; + } + + /** + * Check whether underlying raw pointer is valid. + * + * Invalid instance can be returned if some of the previous + * operations have resulted in a failure. For example invalid + * instance can be returned by not-throwing version of method + * in case of error. Invalid instances also often can be + * created using default constructor. + * + * @return True if valid. + */ + bool IsValid() const + { + return impl != 0; + } + + /** + * Swap pointer content with another instance. + * + * @param other Other instance. + */ + void Swap(SharedPointer& other) + { + if (this != &other) + { + T* ptrTmp = ptr; + SharedPointerImpl* implTmp = impl; + + ptr = other.ptr; + impl = other.impl; + + other.ptr = ptrTmp; + other.impl = implTmp; + } + } + + private: + /* Pointer. */ + T* ptr; + + /** Implementation. */ + SharedPointerImpl* impl; + }; + + /** + * Enables static-cast semantics for SharedPointer. + * + * @param val Value to cast. + */ + template + SharedPointer StaticPointerCast(const SharedPointer& val) + { + return SharedPointer(val, StaticTag()); + } + + /** + * The class provides functionality that allows objects of derived + * classes to create instances of shared_ptr pointing to themselves + * and sharing ownership with existing shared_ptr objects. + */ + template + class IGNITE_IMPORT_EXPORT EnableSharedFromThis + { + public: + /** + * Default constructor. + */ + EnableSharedFromThis() : self(0) + { + // No-op. + } + + /** + * Copy constructor. + */ + EnableSharedFromThis(const EnableSharedFromThis&) : self(0) + { + // No-op. + } + + /** + * Assignment operator. + */ + EnableSharedFromThis& operator=(const EnableSharedFromThis&) + { + return *this; + } + + /** + * Destructor. + */ + virtual ~EnableSharedFromThis() + { + // No-op. + } + + /** + * Create shared pointer for this instance. + * + * Can only be called on already shared object. + * @return New shared pointer instance. + */ + SharedPointer SharedFromThis() + { + assert(self != 0); + + SharedPointer ptr; + + ptr.impl = self; + + self->Increment(); + + return ptr; + } + + private: + template + friend void ImplEnableShared(EnableSharedFromThis*, SharedPointerImpl*); + + /** Shared pointer base. */ + SharedPointerImpl* self; + }; + + // Implementation for instances derived from EnableSharedFromThis. + template + inline void ImplEnableShared(EnableSharedFromThis* some, SharedPointerImpl* impl) + { + if (some) + some->self = impl; + } + + /** + * Lock guard. + */ + template + class LockGuard + { + public: + /** + * Constructor. + * + * @param lock Lockable object. + */ + LockGuard(T& lock) : + lock(&lock) + { + lock.Enter(); + } + + /** + * Destructor. + */ + ~LockGuard() + { + if (lock) + lock->Leave(); + } + + /** + * Releases control over lock without unlocking it. + */ + void Forget() + { + lock = 0; + } + + /** + * Releases control over lock and unlocks it as if it would + * go out of scope. + */ + void Reset() + { + if (lock) + { + lock->Leave(); + + Forget(); + } + } + + private: + T* lock; + }; + + typedef LockGuard CsLockGuard; + + /** + * Shared lock guard. + * Locks guard in shared mode. + */ + template + class SharedLockGuard + { + public: + /** + * Constructor. + * + * @param lock Lockable object. + */ + SharedLockGuard(T& lock) : + lock(&lock) + { + lock.LockShared(); + } + + /** + * Destructor. + */ + ~SharedLockGuard() + { + if (lock) + lock->ReleaseShared(); + } + + /** + * Releases control over lock without unlocking it. + */ + void Forget() + { + lock = 0; + } + + /** + * Releases control over lock and unlocks it as if it would + * go out of scope. + */ + void Reset() + { + if (lock) + { + lock->ReleaseShared(); + + Forget(); + } + } + + private: + T* lock; + }; + + typedef SharedLockGuard RwSharedLockGuard; + + /** + * Exclusive lock guard. + * Locks guard in exclusive mode. + */ + template + class ExclusiveLockGuard + { + public: + /** + * Constructor. + * + * @param lock Lockable object. + */ + ExclusiveLockGuard(T& lock) : + lock(&lock) + { + lock.LockExclusive(); + } + + /** + * Destructor. + */ + ~ExclusiveLockGuard() + { + if (lock) + lock->ReleaseExclusive(); + } + + /** + * Releases control over lock without unlocking it. + */ + void Forget() + { + lock = 0; + } + + /** + * Releases control over lock and unlocks it as if it would + * go out of scope. + */ + void Reset() + { + if (lock) + { + lock->ReleaseExclusive(); + + Forget(); + } + } + + private: + T* lock; + }; + + typedef ExclusiveLockGuard RwExclusiveLockGuard; + } // namespace concurrent + } // namespace common + } // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_COMMON_CONCURRENT diff --git a/src/odbc/include/ignite/odbc/common/decimal.h b/src/odbc/include/ignite/odbc/common/decimal.h new file mode 100644 index 000000000..9728fc845 --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/decimal.h @@ -0,0 +1,530 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_ODBC_COMMON_DECIMAL +#define _IGNITE_ODBC_COMMON_DECIMAL + +#include +#include + +#include +#include + +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + /** + * Big decimal number implementation. + */ + class IGNITE_IMPORT_EXPORT Decimal + { + public: + /** + * Default constructor. + */ + Decimal(); + + /** + * Constructor. + * + * @param mag Bytes of the magnitude. Should be positive, sign is + * passed using separate argument. + * @param len Magnitude length in bytes. + * @param scale Scale. + * @param sign Sign of the decimal. Should be -1 for negative numbers + * and 1 otherwise. + * @param bigEndian If true then magnitude is in big-endian. Otherwise + * the byte order of the magnitude considered to be little-endian. + */ + Decimal(const int8_t* mag, int32_t len, int32_t scale, int32_t sign, bool bigEndian = true); + + /** + * Copy constructor. + * + * @param other Other instance. + */ + Decimal(const Decimal& other); + + /** + * Integer constructor. + * + * @param val Integer value. + */ + explicit Decimal(int64_t val); + + /** + * Integer constructor with scale. + * + * @param val Integer value. + * @param scale Scale. + */ + Decimal(int64_t val, int32_t scale); + + /** + * BigInteger constructor with scale. + * + * @param val BigInteger value. + * @param scale Scale. + */ + Decimal(const common::BigInteger& val, int32_t scale); + + /** + * String constructor. + * + * @param val String to assign. + * @param len String length. + */ + Decimal(const char* val, int32_t len); + + /** + * String constructor. + * + * @param val String to assign. + */ + explicit Decimal(const std::string& val) : + scale(0), + magnitude(0) + { + AssignString(val); + } + + /** + * Destructor. + */ + ~Decimal(); + + /** + * Copy operator. + * + * @param other Other instance. + * @return This. + */ + Decimal& operator=(const Decimal& other); + + /** + * Convert to double. + */ + operator double() const; + + /** + * Convert to int64_t. + */ + operator int64_t() const; + + /** + * Convert to double. + * + * @return Double value. + */ + double ToDouble() const; + + /** + * Convert to int64_t. + * + * @return int64_t value. + */ + int64_t ToInt64() const; + + /** + * Get scale. + * + * @return Scale. + */ + int32_t GetScale() const; + + /** + * Set scale. + * + * @param scale Scale to set. + * @param res Result is placed here. Can be *this. + */ + void SetScale(int32_t scale, Decimal& res) const; + + /** + * Get precision of the Decimal. + * + * @return Number of the decimal digits in the decimal representation + * of the value. + */ + int32_t GetPrecision() const; + + /** + * Get unscaled value. + * + * @return Unscaled value. + */ + const common::BigInteger& GetUnscaledValue() const; + + /** + * Swap function for the Decimal type. + * + * @param other Other instance. + */ + void Swap(Decimal& second); + + /** + * Get length of the magnitude. + * + * @return Length of the magnitude. + */ + int32_t GetMagnitudeLength() const; + + /** + * Assign specified value to this Decimal. + * + * @param val String to assign. + */ + void AssignString(const std::string& val) + { + AssignString(val.data(), static_cast(val.size())); + } + + /** + * Assign specified value to this Decimal. + * + * @param val String to assign. + * @param len String length. + */ + void AssignString(const char* val, int32_t len); + + /** + * Assign specified value to this Decimal. + * + * @param val Value to assign. + */ + void AssignInt64(int64_t val); + + /** + * Assign specified value to this Decimal. + * + * @param val Value to assign. + */ + void AssignDouble(double val); + + /** + * Assign specified value to this Decimal. + * + * @param val Value to assign. + */ + void AssignUint64(uint64_t val); + + /** + * Compare this instance to another. + * + * @param other Another instance. + * @return Comparasion result - 0 if equal, 1 if this is greater, -1 if + * this is less. + */ + int32_t Compare(const Decimal& other) const; + + /** + * Check whether this value is negative. + * + * @return True if this value is negative and false otherwise. + */ + bool IsNegative() const; + + /** + * Check whether this value is zero. + * + * @return True if this value is negative and false otherwise. + */ + bool IsZero() const; + + /** + * Check whether this value is positive. + * + * @return True if this value is positive and false otherwise. + */ + bool IsPositive() const; + + /** + * Output operator. + * + * @param os Output stream. + * @param val Value to output. + * @return Reference to the first param. + */ + friend std::ostream& operator<<(std::ostream& os, const Decimal& val) + { + const common::BigInteger& unscaled = val.GetUnscaledValue(); + + // Zero magnitude case. Scale does not matter. + if (unscaled.GetMagnitude().IsEmpty()) + return os << '0'; + + // Scale is zero or negative. No decimal point here. + if (val.scale <= 0) + { + os << unscaled; + + // Adding zeroes if needed. + for (int32_t i = 0; i < -val.scale; ++i) + os << '0'; + + return os; + } + + // Getting magnitude as a string. + std::stringstream converter; + + converter << unscaled; + + std::string magStr = converter.str(); + + int32_t magLen = static_cast(magStr.size()); + + int32_t magBegin = 0; + + // If value is negative passing minus sign. + if (magStr[magBegin] == '-') + { + os << magStr[magBegin]; + + ++magBegin; + --magLen; + } + + // Finding last non-zero char. There is no sense in trailing zeroes + // beyond the decimal point. + int32_t lastNonZero = static_cast(magStr.size()) - 1; + + while (lastNonZero >= magBegin && magStr[lastNonZero] == '0') + --lastNonZero; + + // This is expected as we already covered zero number case. + assert(lastNonZero >= magBegin); + + int32_t dotPos = magLen - val.scale; + + if (dotPos <= 0) + { + // Means we need to add leading zeroes. + os << '0' << '.'; + + while (dotPos < 0) + { + ++dotPos; + + os << '0'; + } + + os.write(&magStr[magBegin], static_cast(lastNonZero) - magBegin + 1); + } + else + { + // Decimal point is in the middle of the number. + // Just output everything before the decimal point. + os.write(&magStr[magBegin], dotPos); + + int32_t afterDot = lastNonZero - dotPos - magBegin + 1; + + if (afterDot > 0) + { + os << '.'; + + os.write(&magStr[magBegin + dotPos], afterDot); + } + } + + return os; + } + + /** + * Input operator. + * + * @param is Input stream. + * @param val Value to input. + * @return Reference to the first param. + */ + friend std::istream& operator>>(std::istream& is, Decimal& val) + { + std::istream::sentry sentry(is); + + // Return zero if input failed. + val.AssignInt64(0); + + if (!is) + return is; + + // Current char. + int c = is.peek(); + + // Current value parts. + uint64_t part = 0; + int32_t partDigits = 0; + int32_t scale = -1; + int32_t sign = 1; + + common::BigInteger& mag = val.magnitude; + common::BigInteger pow; + common::BigInteger bigPart; + + if (!is) + return is; + + // Checking sign. + if (c == '-' || c == '+') + { + if (c == '-') + sign = -1; + + is.ignore(); + c = is.peek(); + } + + // Reading number itself. + while (is) + { + if (isdigit(c)) + { + part = part * 10 + (c - '0'); + ++partDigits; + } + else if (c == '.' && scale < 0) + { + // We have found decimal point. Starting counting scale. + scale = 0; + } + else + break; + + is.ignore(); + c = is.peek(); + + if (part >= 1000000000000000000U) + { + common::BigInteger::GetPowerOfTen(partDigits, pow); + mag.Multiply(pow, mag); + + mag.Add(part); + + part = 0; + partDigits = 0; + } + + // Counting scale if the decimal point have been encountered. + if (scale >= 0) + ++scale; + } + + // Adding last part of the number. + if (partDigits) + { + common::BigInteger::GetPowerOfTen(partDigits, pow); + + mag.Multiply(pow, mag); + + mag.Add(part); + } + + // Adjusting scale. + if (scale < 0) + scale = 0; + else + --scale; + + // Reading exponent. + if (c == 'e' || c == 'E') + { + is.ignore(); + + int32_t exp = 0; + is >> exp; + + scale -= exp; + } + + val.scale = scale; + + if (sign < 0) + mag.Negate(); + + return is; + } + + private: + /** Scale. */ + int32_t scale; + + /** Magnitude. */ + common::BigInteger magnitude; + }; + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if equal. + */ + IGNITE_IMPORT_EXPORT bool operator==(const Decimal& val1, const Decimal& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if not equal. + */ + IGNITE_IMPORT_EXPORT bool operator!=(const Decimal& val1, const Decimal& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if less. + */ + IGNITE_IMPORT_EXPORT bool operator<(const Decimal& val1, const Decimal& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if less or equal. + */ + IGNITE_IMPORT_EXPORT bool operator<=(const Decimal& val1, const Decimal& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if gretter. + */ + IGNITE_IMPORT_EXPORT bool operator>(const Decimal& val1, const Decimal& val2); + + /** + * Comparison operator. + * + * @param val1 First value. + * @param val2 Second value. + * @return True if gretter or equal. + */ + IGNITE_IMPORT_EXPORT bool operator>=(const Decimal& val1, const Decimal& val2); + } + } +} + +#endif //_IGNITE_ODBC_COMMON_DECIMAL diff --git a/src/odbc/include/ignite/odbc/common/default_allocator.h b/src/odbc/include/ignite/odbc/common/default_allocator.h new file mode 100644 index 000000000..ddf7bdda7 --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/default_allocator.h @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _IGNITE_ODBC_COMMON_DEFAULT_ALLOCATOR +#define _IGNITE_ODBC_COMMON_DEFAULT_ALLOCATOR + +#include +#include + +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + /** + * Allocator. Manages objects construction and destruction as well + * as a memory allocation. + */ + template + class IGNITE_IMPORT_EXPORT DefaultAllocator + { + public: + typedef T ValueType; + typedef T* PointerType; + typedef T& ReferenceType; + typedef const T* ConstPointerType; + typedef const T& ConstReferenceType; + typedef int32_t SizeType; + typedef int32_t DifferenceType; + + template struct Rebind + { + typedef DefaultAllocator other; + }; + + /** + * Default constructor. + */ + DefaultAllocator() + { + // No-op. + } + + /** + * Destructor. + */ + ~DefaultAllocator() + { + // No-op. + } + + PointerType Allocate(SizeType len, void* = 0) + { + return static_cast(::operator new(len * sizeof(ValueType))); + } + + void Deallocate(PointerType ptr, SizeType) + { + ::operator delete(ptr); + } + + void Construct(PointerType p, ConstReferenceType val) + { + new (p) ValueType(val); + } + + void Destruct(PointerType p) + { + p->~ValueType(); + } + }; + } + } +} + +#endif // _IGNITE_ODBC_COMMON_DEFAULT_ALLOCATOR diff --git a/src/odbc/include/ignite/odbc/common/dynamic_size_array.h b/src/odbc/include/ignite/odbc/common/dynamic_size_array.h new file mode 100644 index 000000000..109ccc51c --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/dynamic_size_array.h @@ -0,0 +1,418 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _IGNITE_ODBC_COMMON_DYNAMIC_SIZE_ARRAY +#define _IGNITE_ODBC_COMMON_DYNAMIC_SIZE_ARRAY + +#include +#include +#include + +#include + +#include +#include +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + /** + * Dynamic size array is safe container abstraction with a dynamic size. + * This is the analogue of the standard vector. It is needed to be used + * in exported classes as we can't export standard library classes. + */ + template > + class IGNITE_IMPORT_EXPORT DynamicSizeArray + { + public: + typedef T ValueType; + typedef A AllocatorType; + typedef typename AllocatorType::SizeType SizeType; + typedef typename AllocatorType::PointerType PointerType; + typedef typename AllocatorType::ConstPointerType ConstPointerType; + typedef typename AllocatorType::ReferenceType ReferenceType; + typedef typename AllocatorType::ConstReferenceType ConstReferenceType; + + /** + * Default constructor. + * + * Constructs zero-size and zero-capasity array. + */ + DynamicSizeArray(const AllocatorType& allocator = AllocatorType()) : + alloc(allocator), + size(0), + capasity(0), + data(0) + { + // No-op. + } + + /** + * Constructor. + * Constructs empty array with the specified capacity. + * + * @param len Array length. + * @param alloc Allocator. + */ + DynamicSizeArray(SizeType len, const AllocatorType& allocator = AllocatorType()) : + alloc(allocator), + size(0), + capasity(bits::GetCapasityForSize(len)), + data(alloc.Allocate(capasity)) + { + // No-op. + } + + /** + * Raw array constructor. + * + * @param arr Raw array. + * @param len Array length in elements. + */ + DynamicSizeArray(ConstPointerType arr, SizeType len, + const AllocatorType& allocator = AllocatorType()) : + alloc(allocator), + size(0), + capasity(0), + data(0) + { + Assign(arr, len); + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + DynamicSizeArray(const DynamicSizeArray& other) : + alloc(), + size(0), + capasity(0), + data(0) + { + Assign(other); + } + + /** + * Destructor. + */ + ~DynamicSizeArray() + { + for (PointerType it = data; it != data + size; ++it) + alloc.Destruct(it); + + alloc.Deallocate(data, capasity); + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return Reference to this instance. + */ + DynamicSizeArray& operator=(const DynamicSizeArray& other) + { + Assign(other); + + return *this; + } + + /** + * Assign new value to the array. + * + * @param other Another array instance. + */ + void Assign(const DynamicSizeArray& other) + { + if (this != &other) + { + alloc = other.alloc; + + Assign(other.GetData(), other.GetSize()); + } + } + + /** + * Assign new value to the array. + * + * @param src Raw array. + * @param len Array length in elements. + */ + void Assign(ConstPointerType src, SizeType len) + { + for (PointerType it = data; it != data + size; ++it) + alloc.Destruct(it); + + if (capasity < len) + { + alloc.Deallocate(data, capasity); + + capasity = bits::GetCapasityForSize(len); + data = alloc.Allocate(capasity); + } + + size = len; + + for (SizeType i = 0; i < size; ++i) + alloc.Construct(data + i, src[i]); + } + + /** + * Append several values to the array. + * + * @param src Raw array. + * @param len Array length in elements. + */ + void Append(ConstPointerType src, SizeType len) + { + Reserve(size + len); + + for (SizeType i = 0; i < len; ++i) + alloc.Construct(data + size + i, src[i]); + + size += len; + } + + /** + * Swap contents of the array with another instance. + * + * @param other Instance to swap with. + */ + void Swap(DynamicSizeArray& other) + { + if (this != &other) + { + std::swap(alloc, other.alloc); + std::swap(size, other.size); + std::swap(capasity, other.capasity); + std::swap(data, other.data); + } + } + + /** + * Get data pointer. + * + * @return Data pointer. + */ + PointerType GetData() + { + return data; + } + + /** + * Get data pointer. + * + * @return Data pointer. + */ + ConstPointerType GetData() const + { + return data; + } + + /** + * Get array size. + * + * @return Array size. + */ + SizeType GetSize() const + { + return size; + } + + /** + * Get capasity. + * + * @return Array capasity. + */ + SizeType GetCapasity() const + { + return capasity; + } + + /** + * Element access operator. + * + * @param idx Element index. + * @return Element reference. + */ + ReferenceType operator[](SizeType idx) + { + assert(idx < size); + + return data[idx]; + } + + /** + * Element access operator. + * + * @param idx Element index. + * @return Element reference. + */ + ConstReferenceType operator[](SizeType idx) const + { + assert(idx < size); + + return data[idx]; + } + + /** + * Check if the array is empty. + * + * @return True if the array is empty. + */ + bool IsEmpty() const + { + return size == 0; + } + + /** + * Clears the array. + */ + void Clear() + { + for (PointerType it = data; it != data + size; ++it) + alloc.Destruct(it); + + size = 0; + } + + /** + * Reserves not less than specified elements number so array is not + * going to grow on append. + * + * @param newCapacity Desired capasity. + */ + void Reserve(SizeType newCapacity) + { + if (capasity < newCapacity) + { + DynamicSizeArray tmp(newCapacity); + + tmp.Assign(*this); + + Swap(tmp); + } + } + + /** + * Resizes array. Destructs elements if the specified size is less + * than the array's size. Default-constructs elements if the + * specified size is more than the array's size. + * + * @param newSize Desired size. + */ + void Resize(SizeType newSize) + { + if (capasity < newSize) + Reserve(newSize); + + if (newSize > size) + { + for (PointerType it = data + size; it < data + newSize; ++it) + alloc.Construct(it, ValueType()); + } + else + { + for (PointerType it = data + newSize; it < data + size; ++it) + alloc.Destruct(it); + } + + size = newSize; + } + + /** + * Get last element. + * + * @return Last element reference. + */ + const ValueType& Back() const + { + assert(size > 0); + + return data[size - 1]; + } + + /** + * Get last element. + * + * @return Last element reference. + */ + ValueType& Back() + { + assert(size > 0); + + return data[size - 1]; + } + + /** + * Get first element. + * + * @return First element reference. + */ + const ValueType& Front() const + { + assert(size > 0); + + return data[0]; + } + + /** + * Get first element. + * + * @return First element reference. + */ + ValueType& Front() + { + assert(size > 0); + + return data[0]; + } + + /** + * Pushes new value to the back of the array, effectively increasing + * array size by one. + * + * @param val Value to push. + */ + void PushBack(ConstReferenceType val) + { + Resize(size + 1); + + Back() = val; + } + + private: + /** Allocator */ + AllocatorType alloc; + + /** Array size. */ + SizeType size; + + /** Array capasity. */ + SizeType capasity; + + /** Data. */ + PointerType data; + }; + } + } +} + +#endif // _IGNITE_ODBC_COMMON_DYNAMIC_SIZE_ARRAY diff --git a/src/odbc/include/ignite/odbc/common/expected.h b/src/odbc/include/ignite/odbc/common/expected.h new file mode 100644 index 000000000..800fda179 --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/expected.h @@ -0,0 +1,303 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_ODBC_COMMON_EXPECTED +#define _IGNITE_ODBC_COMMON_EXPECTED + +#include + +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + /** + * Helper class to construct Expected class with error value. + */ + template + struct Unexpected + { + /** Value type. */ + typedef E ValueType; + + /** + * Constructor. + * + * @param e Error value reference. + */ + Unexpected(const ValueType& e) : err(e) + { + // No-op; + } + + /** Error. */ + const ValueType& err; + }; + + /** + * Operation result wrapper. + * + * Represents a type, which can accept one of two value types - expected + * result or error. + * + * @tparam R Result type. + * @tparam E Error type. + * @tparam AR Allocator type used for the Result type. + * @tparam AE Allocator type used for the Error type. + */ + template< + typename R, + typename E, + typename AR = std::allocator, + typename AE = std::allocator > + class Expected + { + public: + /** Result type. */ + typedef R ResultType; + + /** Error type. */ + typedef E ErrorType; + + /** Allocator type used for the ResultType. */ + typedef AR ResultAllocatorType; + + /** Allocator type used for the ErrorType. */ + typedef AE ErrorAllocatorType; + + /** + * Constructor. + * + * Creates new instance, containing expected value. + * @param res Result. + */ + Expected(const ResultType& res) : + ok(true) + { + ResultAllocatorType ral; + + ral.construct(AsResult(), res); + } + + /** + * Constructor. + * + * Creates new instance, containing error. + * @param err Result. + */ + explicit Expected(Unexpected err) : + ok(false) + { + ErrorAllocatorType ral; + + ral.construct(AsError(), err.err); + } + + /** + * Copy constructor. + * + * @param other Other. + */ + Expected(const Expected& other) : + ok(other.ok) + { + if (ok) + { + ResultAllocatorType ral; + + ral.construct(AsResult(), *other.AsResult()); + } + else + { + ErrorAllocatorType ral; + + ral.construct(AsError(), *other.AsError()); + } + } + + /** + * Destructor. + */ + ~Expected() + { + if (ok) + { + ResultAllocatorType ral; + + ral.destroy(AsResult()); + } + else + { + ErrorAllocatorType ral; + + ral.destroy(AsError()); + } + } + + /** + * Check if the value is OK. + * + * @return @c false if the value is an error and @c true otherwise. + */ + bool IsOk() const + { + return ok; + } + + /** + * Get result. Constant accesser. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + const ResultType& GetResult() const + { + if (!ok) + throw *AsError(); + + return *AsResult(); + } + + /** + * Get result. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + ResultType& GetResult() + { + if (!ok) + throw *AsError(); + + return *AsResult(); + } + + /** + * Get result. Constant accesser. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + const ResultType& operator*() const + { + return GetResult(); + } + + /** + * Get result. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + ResultType& operator*() + { + return GetResult(); + } + + /** + * Get result. Constant accesser. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + const ResultType& operator->() const + { + return GetResult(); + } + + /** + * Get result. + * + * @return Result if it was set before. + * @throw ErrorType if there is no result. + */ + ResultType& operator->() + { + return GetResult(); + } + + /** + * Get error. + * + * @return Error if it was set before. If there is no error, default + * constructed error is returned (which is expected to be "No error"). + */ + const ErrorType& GetError() const + { + static ErrorType noError; + + if (ok) + return noError; + + return *AsError(); + } + + private: + /** + * Get storage as an result. + * + * @return Storage pointer as an result pointer. + */ + ResultType* AsResult() + { + return reinterpret_cast(&storage); + } + + /** + * Get storage as an result. + * + * @return Storage pointer as an result pointer. + */ + const ResultType* AsResult() const + { + return reinterpret_cast(&storage); + } + + /** + * Get storage as an error. + * + * @return Storage pointer as an error pointer. + */ + ErrorType* AsError() + { + return reinterpret_cast(&storage); + } + + /** + * Get storage as an error. + * + * @return Storage pointer as an error pointer. + */ + const ErrorType* AsError() const + { + return reinterpret_cast(&storage); + } + + /** Storage. */ + int8_t storage[sizeof(typename Bigger::type)]; + + /** Result flag. Set to @c false if the value is an error. */ + bool ok; + }; + } + } +} + +#endif // _IGNITE_ODBC_COMMON_EXPECTED \ No newline at end of file diff --git a/src/odbc/include/ignite/odbc/common/fixed_size_array.h b/src/odbc/include/ignite/odbc/common/fixed_size_array.h new file mode 100644 index 000000000..a18a60a84 --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/fixed_size_array.h @@ -0,0 +1,262 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _IGNITE_ODBC_COMMON_FIXED_SIZE_ARRAY +#define _IGNITE_ODBC_COMMON_FIXED_SIZE_ARRAY + +#include +#include +#include + +#include +#include + +#include + +namespace ignite +{ + namespace odbc { + namespace common { + /** + * Fixed size array is safe array abstraction with a fixed size. + * The size can be set during runtime though once array is created + * its size can not be changed without resetting arrays content. + */ + template < typename T > + class IGNITE_IMPORT_EXPORT FixedSizeArray { + public: + typedef int32_t SizeType; + + /** + * Default constructor. + * + * Constructs zero-size array. + */ + FixedSizeArray() : size(0), data(0) { + // No-op. + } + + /** + * Constructor. + * Constructs default-initialized array of the specified length. + * Array zeroed if T is a POD type. + * + * @param len Array length. + */ + FixedSizeArray(SizeType len) + : size(len), + // Brackets are here for a purpose - this way allocated + // array is zeroed if T is POD type. + data(new T[size]()) { + // No-op. + } + + /** + * Copy constructor. + * + * @param other Other instance. + */ + FixedSizeArray(const FixedSizeArray< T >& other) + : size(other.size), data(new T[size]) { + Assign(other); + } + + /** + * Raw array constructor. + * + * @param arr Raw array. + * @param len Array length in elements. + */ + FixedSizeArray(const T* arr, SizeType len) : size(len), data(new T[size]) { + Assign(arr, len); + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return Reference to this instance. + */ + FixedSizeArray< T >& operator=(const FixedSizeArray< T >& other) { + Assign(other); + + return *this; + } + + /** + * Assign new value to the array. + * + * @param other Another array instance. + */ + void Assign(const FixedSizeArray< T >& other) { + if (this != &other) + Assign(other.GetData(), other.GetSize()); + } + + /** + * Assign new value to the array. + * + * @param src Raw array. + * @param len Array length in elements. + */ + void Assign(const T* src, SizeType len) { + // In case we would not need to clean anything + // its okay to call delete[] on 0. + T* toClean = 0; + + if (len != size) { + // Do not clean just yet in case the part of the + // array is being assigned to the array. + toClean = data; + + size = len; + data = new T[size]; + } + + for (SizeType i = 0; i < len; ++i) + data[i] = src[i]; + + delete[] toClean; + } + + /** + * Swap contents of the array with another instance. + * + * @param other Instance to swap with. + */ + void Swap(FixedSizeArray< T >& other) { + if (this != &other) { + std::swap(size, other.size); + std::swap(data, other.data); + } + } + + /** + * Destructor. + */ + ~FixedSizeArray() { + // Not a bug. Delete works just fine on null pointers. + delete[] data; + } + + /** + * Get data pointer. + * + * @return Data pointer. + */ + T* GetData() { + return data; + } + + /** + * Get data pointer. + * + * @return Data pointer. + */ + const T* GetData() const { + return data; + } + + /** + * Get array size. + * + * @return Array size. + */ + SizeType GetSize() const { + return size; + } + + /** + * Copy part of the array and place in another array. + * Contents of the provided array gets swapped with the copy of the + * specified array part. + * + * @param pos Start position. + * @param n Number of elements to copy. + * @param result Instance of an array where result should be placed. + */ + void CopyPart(SizeType pos, SizeType n, FixedSizeArray< T >& result) const { + assert(pos < size); + assert(pos + n <= size); + + result.Assign(data + pos, n); + } + + /** + * Element access operator. + * + * @param idx Element index. + * @return Element reference. + */ + T& operator[](SizeType idx) { + assert(idx < size); + + return data[idx]; + } + + /** + * Element access operator. + * + * @param idx Element index. + * @return Element reference. + */ + const T& operator[](SizeType idx) const { + assert(idx < size); + + return data[idx]; + } + + /** + * Check if the array is empty. + * + * @return True if the array is empty. + */ + bool IsEmpty() const { + return size == 0; + } + + /** + * Resets the state of the array setting it to the specified size + * and erasing its content. + * + * @param newSize New array size. + */ + void Reset(SizeType newSize = 0) { + if (size != newSize) { + delete[] data; + + if (newSize) + data = new T[newSize](); + else + data = 0; + + size = newSize; + } else + std::fill(data, data + size, T()); + } + + private: + /** Array size. */ + SizeType size; + + /** Target array. */ + T* data; + }; + } // namespace common + } // namespace odbc +} + +#endif // _IGNITE_ODBC_COMMON_FIXED_SIZE_ARRAY diff --git a/src/odbc/include/ignite/odbc/common/platform_utils.h b/src/odbc/include/ignite/odbc/common/platform_utils.h new file mode 100644 index 000000000..5e430de2c --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/platform_utils.h @@ -0,0 +1,126 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _IGNITE_ODBC_COMMON_PLATFORM_UTILS +#define _IGNITE_ODBC_COMMON_PLATFORM_UTILS + +#include +#include "ignite/odbc/common/common.h" + +namespace ignite +{ + namespace odbc + { + namespace common + { + typedef std::basic_ostream > StdCharOutStream; + + /** + * Convert struct tm to time_t (UTC). + * + * @param time Standard C type struct tm value. + * @return Standard C type time_t value. + */ + IGNITE_IMPORT_EXPORT time_t IgniteTimeGm(const tm& time); + + /** + * Convert struct tm to time_t (Local time). + * + * @param time Standard C type struct tm value. + * @return Standard C type time_t value. + */ + IGNITE_IMPORT_EXPORT time_t IgniteTimeLocal(const tm& time); + + /** + * Convert time_t to struct tm (UTC). + * + * @param in Standard C type time_t value. + * @param out Standard C type struct tm value. + * @return True on success. + */ + IGNITE_IMPORT_EXPORT bool IgniteGmTime(time_t in, tm& out); + + /** + * Convert time_t to struct tm (Local time). + * + * @param in Standard C type time_t value. + * @param out Standard C type struct tm value. + * @return True on success. + */ + IGNITE_IMPORT_EXPORT bool IgniteLocalTime(time_t in, tm& out); + + /** + * Read system environment variable taking thread-safety in count. + * + * @param name Environment variable name. + * @return Environment variable value if found and empty string otherwise. + */ + IGNITE_IMPORT_EXPORT std::string GetEnv(const std::string& name); + + /** + * Read system environment variable taking thread-safety in count. + * + * @param name Environment variable name. + * @param dflt Default value to return on fail. + * @return Environment variable value if found and @c dflt otherwise. + */ + IGNITE_IMPORT_EXPORT std::string GetEnv(const std::string& name, const std::string& dflt); + + /** + * Ensure that file on the given path exists in the system. + * + * @param path Path. + * @return True if file exists, false otherwise. + */ + IGNITE_IMPORT_EXPORT bool FileExists(const std::string& path); + + /** + * Check if the provided path is the valid directory. + * @return @c true if the provided path is the valid directory. + */ + IGNITE_IMPORT_EXPORT bool IsValidDirectory(const std::string& path); + + /** + * Deletes provided filesystem element if exists. + * @return @c true if the provided path exists. + */ + IGNITE_IMPORT_EXPORT bool DeletePath(const std::string& path); + + /** + * Write file separator to a stream. + * @param ostr Stream. + * @return The same stream for chaining. + */ + IGNITE_IMPORT_EXPORT StdCharOutStream& Fs(StdCharOutStream& ostr); + + /** + * Write dynamic library expansion to a stream. + * @param ostr Stream. + * @return The same stream for chaining. + */ + IGNITE_IMPORT_EXPORT StdCharOutStream& Dle(StdCharOutStream& ostr); + + /** + * Get random seed. + * + * @return Random seed. + */ + IGNITE_IMPORT_EXPORT unsigned GetRandSeed(); + } + } +} + +#endif //_IGNITE_ODBC_COMMON_PLATFORM_UTILS diff --git a/src/odbc/include/ignite/odbc/common/utils.h b/src/odbc/include/ignite/odbc/common/utils.h new file mode 100644 index 000000000..accb2fa84 --- /dev/null +++ b/src/odbc/include/ignite/odbc/common/utils.h @@ -0,0 +1,664 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _IGNITE_ODBC_COMMON_UTILS +#define _IGNITE_ODBC_COMMON_UTILS + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include "ignite/time.h" + +#ifdef IGNITE_FRIEND +# define IGNITE_FRIEND_EXPORT IGNITE_EXPORT +#else +# define IGNITE_FRIEND_EXPORT +#endif + +namespace ignite +{ + namespace odbc + { + namespace common + { + /** + * Replace all alphabetic symbols of the string with their lowercase + * versions. + * @param str String to be transformed. + */ + inline void IntoLower(std::string& str) + { + std::transform(str.begin(), str.end(), str.begin(), ::tolower); + } + + /** + * Get lowercase version of the string. + * + * @param str Input string. + * @return Lowercased version of the string. + */ + inline std::string ToLower(const std::string& str) + { + std::string res(str); + IntoLower(res); + return res; + } + + /** + * Strips leading and trailing whitespaces from string. + * + * @param str String to be transformed. + */ + IGNITE_IMPORT_EXPORT void StripSurroundingWhitespaces(std::string& str); + + /** + * Skip leading spaces. + * + * @param begin Iterator to the beginning of the character sequence. + * @param end Iterator to the end of the character sequence. + * @return Iterator to first non-blanc character. + */ + template + Iterator SkipLeadingSpaces(Iterator begin, Iterator end) + { + Iterator res = begin; + + while (isspace(*res) && res != end) + ++res; + + return res; + } + + /** + * Skip trailing spaces. + * + * @param begin Iterator to the beginning of the character sequence. + * @param end Iterator to the end of the character sequence. + * @return Iterator to last non-blanc character. + */ + template + Iterator SkipTrailingSpaces(Iterator begin, Iterator end) + { + Iterator res = end - 1; + + while (isspace(*res) && res != begin - 1) + --res; + + return res + 1; + } + + /** + * Remove leading and trailing spaces. + * + * @param begin Iterator to the beginning of the character sequence. + * @param end Iterator to the end of the character sequence. + * @return String without leading and trailing spaces. + */ + template + std::string StripSurroundingWhitespaces(Iterator begin, Iterator end) + { + std::string res; + + if (begin >= end) + return res; + + Iterator skipped_leading = SkipLeadingSpaces(begin, end); + Iterator skipped_trailing = SkipTrailingSpaces(skipped_leading, end); + + res.reserve(skipped_trailing - skipped_leading); + + std::copy(skipped_leading, skipped_trailing, std::back_inserter(res)); + + return res; + } + + /** + * Get string representation of long in decimal form. + * + * @param val Long value to be converted to string. + * @return String contataining decimal representation of the value. + */ + inline std::string LongToString(long val) + { + std::stringstream tmp; + tmp << val; + return tmp.str(); + } + + /** + * Parse string to try and get int value. + * + * @param str String to be parsed. + * @return String contataining decimal representation of the value. + */ + inline int ParseInt(const std::string& str) + { + return atoi(str.c_str()); + } + + /** + * Copy characters. + * + * @param val Value. + * @return Result. + */ + IGNITE_IMPORT_EXPORT char* CopyChars(const char* val); + + /** + * Release characters. + * + * @param val Value. + */ + IGNITE_IMPORT_EXPORT void ReleaseChars(char* val); + + /** + * Casts value of one type to another type, using stringstream. + * + * @param val Input value. + * @param res Resulted value. + */ + template + void LexicalCast(const T2& val, T1& res) + { + std::stringstream converter; + + converter << val; + converter >> res; + } + + /** + * Casts value of one type to another type, using stringstream. + * + * @param val Input value. + * @return Resulted value. + */ + template + T1 LexicalCast(const T2& val) + { + T1 res; + + LexicalCast(val, res); + + return res; + } + + /** + * Check if all characters are digits. + * + * @param val Value to check. + */ + IGNITE_IMPORT_EXPORT bool AllDigits(const std::string& val); + + /** + * Converts 32-bit integer to big endian format + * + * @param value Input value + * @return Resulting value + */ + IGNITE_IMPORT_EXPORT uint32_t ToBigEndian(uint32_t value); + + /** + * Convert Date type to standard C type time_t. + * + * @param date Date type value. + * @return Corresponding value of time_t. + */ + inline time_t DateToCTime(const Date& date) + { + return static_cast(date.GetSeconds()); + } + + /** + * Convert Timestamp type to standard C type time_t. + * + * @param ts Timestamp type value. + * @return Corresponding value of time_t. + */ + inline time_t TimestampToCTime(const Timestamp& ts) + { + return static_cast(ts.GetSeconds()); + } + + /** + * Convert Time type to standard C type time_t. + * + * @param time Time type value. + * @return Corresponding value of time_t. + */ + inline time_t TimeToCTime(const Time& time) + { + return static_cast(time.GetSeconds()); + } + + /** + * Convert Date type to standard C type time_t. + * + * @param date Date type value. + * @param ctime Corresponding value of struct tm. + * @return True on success. + */ + inline bool DateToCTm(const Date& date, tm& ctime) + { + time_t tmt = DateToCTime(date); + + return common::IgniteGmTime(tmt, ctime); + } + + /** + * Convert Timestamp type to standard C type struct tm. + * + * @param ts Timestamp type value. + * @param ctime Corresponding value of struct tm. + * @return True on success. + */ + inline bool TimestampToCTm(const Timestamp& ts, tm& ctime) + { + time_t tmt = TimestampToCTime(ts); + + return common::IgniteGmTime(tmt, ctime); + } + + /** + * Convert Time type to standard C type struct tm. + * + * @param time Time type value. + * @param ctime Corresponding value of struct tm. + * @return True on success. + */ + inline bool TimeToCTm(const Time& time, tm& ctime) + { + time_t tmt = TimeToCTime(time); + + return common::IgniteGmTime(tmt, ctime); + } + + /** + * Convert standard C type time_t to Date. + * + * @param ctime Standard C type time_t. + * @return Corresponding value of Date. + */ + inline Date CTimeToDate(time_t ctime) + { + return Date(ctime * 1000); + } + + /** + * Convert standard C type time_t to Time. + * + * @param ctime Standard C type time_t. + * @return Corresponding value of Time. + */ + inline Time CTimeToTime(time_t ctime) + { + return Time(ctime * 1000); + } + + /** + * Convert standard C type time_t to Timestamp type. + * + * @param ctime Standard C type time_t. + * @param ns Nanoseconds second fraction. + * @return Corresponding value of Timestamp. + */ + inline Timestamp CTimeToTimestamp(time_t ctime, int32_t ns) + { + return Timestamp(ctime, ns); + } + + /** + * Convert standard C type struct tm to Date type. + * + * @param ctime Standard C type struct tm. + * @return Corresponding value of Date. + */ + inline Date CTmToDate(const tm& ctime) + { + time_t time = common::IgniteTimeGm(ctime); + + return CTimeToDate(time); + } + + /** + * Convert standard C type struct tm to Time type. + * + * @param ctime Standard C type struct tm. + * @return Corresponding value of Time. + */ + inline Time CTmToTime(const tm& ctime) + { + time_t time = common::IgniteTimeGm(ctime); + + return CTimeToTime(time); + } + + /** + * Convert standard C type struct tm to Timestamp type. + * + * @param ctime Standard C type struct tm. + * @param ns Nanoseconds second fraction. + * @return Corresponding value of Timestamp. + */ + inline Timestamp CTmToTimestamp(const tm& ctime, int32_t ns) + { + time_t time = common::IgniteTimeGm(ctime); + + return CTimeToTimestamp(time, ns); + } + + /** + * Make Date in human understandable way. + * + * Created Date uses GMT timezone. + * + * @param year Year. + * @param month Month. + * @param day Day. + * @param hour Hour. + * @param min Min. + * @param sec Sec. + * @return Date. + */ + IGNITE_FRIEND_EXPORT Date MakeDateGmt(int year = 1900, int month = 1, + int day = 1, int hour = 0, int min = 0, int sec = 0); + + /** + * Make Date in human understandable way. + * + * Created Date uses local timezone. + * + * @param year Year. + * @param month Month. + * @param day Day. + * @param hour Hour. + * @param min Min. + * @param sec Sec. + * @return Date. + */ + IGNITE_FRIEND_EXPORT Date MakeDateLocal(int year = 1900, int month = 1, + int day = 1, int hour = 0, int min = 0, int sec = 0); + + /** + * Make Time in human understandable way. + * + * Created Time uses GMT timezone. + * + * @param hour Hour. + * @param min Minute. + * @param sec Second. + * @return Time. + */ + IGNITE_FRIEND_EXPORT Time MakeTimeGmt(int hour = 0, int min = 0, int sec = 0); + + /** + * Make Time in human understandable way. + * + * Created Time uses Local timezone. + * + * @param hour Hour. + * @param min Minute. + * @param sec Second. + * @return Time. + */ + IGNITE_FRIEND_EXPORT Time MakeTimeLocal(int hour = 0, int min = 0, int sec = 0); + + /** + * Make Timestamp in human understandable way. + * + * Created Timestamp uses GMT timezone. + * + * @param year Year. + * @param month Month. + * @param day Day. + * @param hour Hour. + * @param min Minute. + * @param sec Second. + * @param ns Nanosecond. + * @return Timestamp. + */ + IGNITE_FRIEND_EXPORT Timestamp MakeTimestampGmt(int year = 1900, int month = 1, + int day = 1, int hour = 0, int min = 0, int sec = 0, long ns = 0); + + /** + * Make Date in human understandable way. + * + * Created Timestamp uses Local timezone. + * + * @param year Year. + * @param month Month. + * @param day Day. + * @param hour Hour. + * @param min Minute. + * @param sec Second. + * @param ns Nanosecond. + * @return Timestamp. + */ + IGNITE_FRIEND_EXPORT Timestamp MakeTimestampLocal(int year = 1900, int month = 1, + int day = 1, int hour = 0, int min = 0, int sec = 0, long ns = 0); + + /** + * Meta-programming class. + * Defines T1 as ::type if the condition is true, otherwise + * defines T2 as ::type. + */ + template + struct Conditional + { + typedef T1 type; + }; + + /** + * Specialization for the false case. + */ + template + struct Conditional + { + typedef T2 type; + }; + + /** + * Returns the bigger type. + */ + template + struct Bigger + { + typedef typename Conditional<(sizeof(T1) > sizeof(T2)), T1, T2>::type type; + }; + + /** + * Utility class to bind class instance with member function. + */ + template + class BoundInstance + { + public: + typedef R FunctionReturnType; + typedef T ClassType; + typedef FunctionReturnType(ClassType::* MemberFunctionType)(); + + /** + * Constructor. + * + * @param instance Class instance. + * @param mfunc Member function. + */ + BoundInstance(ClassType* instance, MemberFunctionType mfunc) : + instance(instance), + mfunc(mfunc) + { + // No-op. + } + + /** + * Invoke operator. + * + * @return Result of the invokation of the member function on the bound instance. + */ + FunctionReturnType operator()() + { + return (instance->*mfunc)(); + } + + private: + /** Instance reference. */ + ClassType* instance; + + /** Member function pointer. */ + MemberFunctionType mfunc; + }; + + /** + * Utility function for binding. + */ + template + BoundInstance Bind(T* instance, R(T::* mfunc)()) + { + return BoundInstance(instance, mfunc); + } + + /** + * Method guard class template. + * + * Upon destruction calls provided method on provided class instance. + * + * @tparam T Value type. + */ + template + class MethodGuard + { + public: + /** Value type. */ + typedef T ValueType; + + /** Mehtod type. */ + typedef void (ValueType::*MethodType)(); + + /** + * Constructor. + * + * @param val Instance, to call method on. + * @param method Method to call. + */ + MethodGuard(ValueType* val, MethodType method) : + val(val), + method(method) + { + // No-op. + } + + /** + * Destructor. + */ + ~MethodGuard() + { + if (val && method) + (val->*method)(); + } + + /** + * Release control over object. + */ + void Release() + { + val = 0; + method = 0; + } + + private: + /** Instance, to call method on. */ + ValueType* val; + + /** Method to call. */ + MethodType method; + }; + + /** + * Deinit guard class template. + * + * Upon destruction calls provided deinit function on provided instance. + * + * @tparam T Value type. + */ + template + class DeinitGuard + { + public: + /** Value type. */ + typedef T ValueType; + + /** Deinit function type. */ + typedef void (*FuncType)(ValueType*); + + /** + * Constructor. + * + * @param val Instance, to call method on. + * @param method Method to call. + */ + DeinitGuard(ValueType* val, FuncType method) : + val(val), + func(method) + { + // No-op. + } + + /** + * Destructor. + */ + ~DeinitGuard() + { + if (val && func) + (func)(val); + } + + /** + * Release control over object. + */ + void Release() + { + val = 0; + func = 0; + } + + private: + /** Instance, to call method on. */ + ValueType* val; + + /** Method to call. */ + FuncType func; + }; + + /** + * Get dynamic library full name. + * @param name Name without extension. + * @return Full name. + */ + IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const char* name); + } + } +} + +#endif //_IGNITE_ODBC_COMMON_UTILS diff --git a/src/odbc/include/ignite/odbc/connection.h b/src/odbc/include/ignite/odbc/connection.h index 3fefc8e33..0a917a50d 100644 --- a/src/odbc/include/ignite/odbc/connection.h +++ b/src/odbc/include/ignite/odbc/connection.h @@ -30,7 +30,7 @@ #include "ignite/odbc/diagnostic/diagnosable_adapter.h" #include "ignite/odbc/streaming/streaming_context.h" #include "ignite/odbc/odbc_error.h" -#include "ignite/odbc/end_point.h" +#include "ignite/odbc/jni/java.h" namespace ignite { @@ -228,8 +228,6 @@ namespace ignite if (!success) return false; - parser.Decode(rsp, tempBuffer); - return true; } @@ -489,7 +487,23 @@ namespace ignite * @throw IgniteError on failure. * @return @c true on success and @c false otherwise. */ - bool TryRestoreConnection(); + bool TryRestoreConnection(IgniteError& err); + + /** + * Formats the JDBC connection string from configuration values. + * @return the JDBC connection string. + */ + std::string FormatJdbcConnectionString() const; + + /** + * Creates JVM options + */ + void SetJvmOptions(const std::string& cp); + + /** + * De-initializes the JVM options + */ + void Deinit(); /** * Collect all addresses from config. @@ -515,9 +529,6 @@ namespace ignite /** Parent. */ Environment* env; - /** Client Socket. */ - std::auto_ptr socket; - /** Connection timeout in seconds. */ int32_t timeout; @@ -536,6 +547,12 @@ namespace ignite /** Connection info. */ config::ConnectionInfo info; + /** Java connection object */ + jobject connection; + + /** JVM options */ + std::vector< char* > opts; + /** Streaming context. */ streaming::StreamingContext streamingContext; }; diff --git a/src/odbc/include/ignite/odbc/ignite_error.h b/src/odbc/include/ignite/odbc/ignite_error.h new file mode 100644 index 000000000..5034a6e9c --- /dev/null +++ b/src/odbc/include/ignite/odbc/ignite_error.h @@ -0,0 +1,316 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Declares ignite::IgniteError class. + */ + +#ifndef _IGNITE_ODBC_IGNITE_ERROR +#define _IGNITE_ODBC_IGNITE_ERROR + +#include + +#include +#include + +#include + +#define IGNITE_ERROR_1(code, part1) { \ + std::stringstream stream; \ + stream << (part1); \ + throw ignite::IgniteError(code, stream.str().c_str()); \ +} + +#define IGNITE_ERROR_2(code, part1, part2) { \ + std::stringstream stream; \ + stream << (part1) << (part2); \ + throw ignite::IgniteError(code, stream.str().c_str()); \ +} + +#define IGNITE_ERROR_3(code, part1, part2, part3) { \ + std::stringstream stream; \ + stream << (part1) << (part2) << (part3); \ + throw ignite::IgniteError(code, stream.str().c_str()); \ +} + +#define IGNITE_ERROR_FORMATTED_1(code, msg, key1, val1) { \ + std::stringstream stream; \ + stream << msg << " [" << key1 << "=" << (val1) << "]"; \ + throw ignite::IgniteError(code, stream.str().c_str()); \ +} + +#define IGNITE_ERROR_FORMATTED_2(code, msg, key1, val1, key2, val2) { \ + std::stringstream stream; \ + stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" << (val2) << "]"; \ + throw ignite::IgniteError(code, stream.str().c_str()); \ +} + +#define IGNITE_ERROR_FORMATTED_3(code, msg, key1, val1, key2, val2, key3, val3) { \ + std::stringstream stream; \ + stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" << (val2) << ", " << key3 << "=" << (val3) << "]"; \ + throw ignite::IgniteError(code, stream.str().c_str()); \ +} + +#define IGNITE_ERROR_FORMATTED_4(code, msg, key1, val1, key2, val2, key3, val3, key4, val4) { \ + std::stringstream stream; \ + stream << msg << " [" << key1 << "=" << (val1) << ", " << key2 << "=" << (val2) << ", " << key3 << "=" << (val3) << ", " << key4 << "=" << (val4) << "]"; \ + throw ignite::IgniteError(code, stream.str().c_str()); \ +} + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4275) +#endif //_MSC_VER + +namespace ignite +{ + namespace odbc + { + namespace java + { + /* JNI error constants. */ + const int IGNITE_JNI_ERR_SUCCESS = 0; + const int IGNITE_JNI_ERR_GENERIC = 1; + const int IGNITE_JNI_ERR_JVM_INIT = 2; + const int IGNITE_JNI_ERR_JVM_ATTACH = 3; + } + + /** + * %Ignite error information. + */ + class IGNITE_IMPORT_EXPORT IgniteError : public std::exception + { + public: + /** Success. */ + static const int IGNITE_SUCCESS = 0; + + /** Failed to initialize JVM. */ + static const int IGNITE_ERR_JVM_INIT = 1; + + /** Failed to attach to JVM. */ + static const int IGNITE_ERR_JVM_ATTACH = 2; + + /** JVM library is not found. */ + static const int IGNITE_ERR_JVM_LIB_NOT_FOUND = 3; + + /** Failed to load JVM library. */ + static const int IGNITE_ERR_JVM_LIB_LOAD_FAILED = 4; + + /** JVM classpath is not provided. */ + static const int IGNITE_ERR_JVM_NO_CLASSPATH = 5; + + /** JVM error: no class definition found. */ + static const int IGNITE_ERR_JVM_NO_CLASS_DEF_FOUND = 6; + + /** JVM error: no such method. */ + static const int IGNITE_ERR_JVM_NO_SUCH_METHOD = 7; + + /** Memory operation error. */ + static const int IGNITE_ERR_MEMORY = 1001; + + /** Binary error. */ + static const int IGNITE_ERR_BINARY = 1002; + + /** Standard library exception. */ + static const int IGNITE_ERR_STD = 1003; + + /** Generic %Ignite error. */ + static const int IGNITE_ERR_GENERIC = 2000; + + /** Illegal argument passed. */ + static const int IGNITE_ERR_ILLEGAL_ARGUMENT = 2001; + + /** Illegal state. */ + static const int IGNITE_ERR_ILLEGAL_STATE = 2002; + + /** Unsupported operation. */ + static const int IGNITE_ERR_UNSUPPORTED_OPERATION = 2003; + + /** Thread has been interrup. */ + static const int IGNITE_ERR_INTERRUPTED = 2004; + + /** Cluster group is empty. */ + static const int IGNITE_ERR_CLUSTER_GROUP_EMPTY = 2005; + + /** Cluster topology problem. */ + static const int IGNITE_ERR_CLUSTER_TOPOLOGY = 2006; + + /** Compute execution rejected. */ + static const int IGNITE_ERR_COMPUTE_EXECUTION_REJECTED = 2007; + + /** Compute job failover. */ + static const int IGNITE_ERR_COMPUTE_JOB_FAILOVER = 2008; + + /** Compute task cancelled. */ + static const int IGNITE_ERR_COMPUTE_TASK_CANCELLED = 2009; + + /** Compute task timeout. */ + static const int IGNITE_ERR_COMPUTE_TASK_TIMEOUT = 2010; + + /** Compute user undeclared exception. */ + static const int IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION = 2011; + + /** Generic cache error. */ + static const int IGNITE_ERR_CACHE = 2012; + + /** Generic cache loader error. */ + static const int IGNITE_ERR_CACHE_LOADER = 2013; + + /** Generic cache writer error. */ + static const int IGNITE_ERR_CACHE_WRITER = 2014; + + /** Generic cache entry processor error. */ + static const int IGNITE_ERR_ENTRY_PROCESSOR = 2015; + + /** Cache atomic update timeout. */ + static const int IGNITE_ERR_CACHE_ATOMIC_UPDATE_TIMEOUT = 2016; + + /** Cache partial update. */ + static const int IGNITE_ERR_CACHE_PARTIAL_UPDATE = 2017; + + /** Transaction optimisitc exception. */ + static const int IGNITE_ERR_TX_OPTIMISTIC = 2018; + + /** Transaction timeout. */ + static const int IGNITE_ERR_TX_TIMEOUT = 2019; + + /** Transaction rollback. */ + static const int IGNITE_ERR_TX_ROLLBACK = 2020; + + /** Transaction heuristic exception. */ + static const int IGNITE_ERR_TX_HEURISTIC = 2021; + + /** Authentication error. */ + static const int IGNITE_ERR_AUTHENTICATION = 2022; + + /** Security error. */ + static const int IGNITE_ERR_SECURITY = 2023; + + /** Future state error. */ + static const int IGNITE_ERR_FUTURE_STATE = 2024; + + /** Networking error. */ + static const int IGNITE_ERR_NETWORK_FAILURE = 2025; + + /** SSL/TLS error. */ + static const int IGNITE_ERR_SECURE_CONNECTION_FAILURE = 2026; + + /** Transaction already started by current thread. */ + static const int IGNITE_ERR_TX_THIS_THREAD = 2027; + + /** Generic transaction error. */ + static const int IGNITE_ERR_TX = 2028; + + + /** Unknown error. */ + static const int IGNITE_ERR_UNKNOWN = -1; + + /** + * Throw an error if code is not IGNITE_SUCCESS. + * + * @param err Error. + */ + static void ThrowIfNeeded(const IgniteError& err); + + /** + * Default constructor. + * Creates empty error. Code is IGNITE_SUCCESS and message is NULL. + */ + IgniteError(); + + /** + * Create error with specific code. Message is set to NULL. + * + * @param code Error code. + */ + IgniteError(const int32_t code); + + /** + * Create error with specific code and message. + * + * @param code Error code. + * @param msg Message. + */ + IgniteError(const int32_t code, const char* msg); + + /** + * Copy constructor. + * + * @param other Other instance. + */ + IgniteError(const IgniteError& other); + + /** + * Assignment operator. + * + * @param other Other instance. + * @return *this. + */ + IgniteError& operator=(const IgniteError& other); + + /** + * Destructor. + */ + ~IgniteError() IGNITE_NO_THROW; + + /** + * Get error code. + * + * @return Error code. + */ + int32_t GetCode() const; + + /** + * Get error message. + * + * @return Error message. Can be NULL. + */ + const char* GetText() const IGNITE_NO_THROW; + + /** + * Implementation of the standard std::exception::what() method. + * Synonym for GetText() method. + * + * @return Error message string. + */ + virtual const char* what() const IGNITE_NO_THROW; + + /** + * Initializes IgniteError instance from the JNI error. + * + * @param jniCode Error code. + * @param jniCls Error class. + * @param jniMsg Error message. + * @param err Error. Can not be NULL. + */ + static void SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError& err); + private: + /** Error code. */ + int32_t code; + + /** Error message. */ + char* msg; + }; + } +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif //_MSC_VER + +#endif //_IGNITE_ODBC_IGNITE_ERROR diff --git a/src/odbc/include/ignite/odbc/jni/java.h b/src/odbc/include/ignite/odbc/jni/java.h new file mode 100644 index 000000000..3925aaf0a --- /dev/null +++ b/src/odbc/include/ignite/odbc/jni/java.h @@ -0,0 +1,641 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_ODBC_JNI_JAVA +#define _IGNITE_ODBC_JNI_JAVA + +#include + +#include + +#include + +namespace ignite { + namespace odbc { + namespace jni { + namespace java { + + /* Handlers for callbacks from Java. */ + typedef int64_t(JNICALL* CacheStoreCreateHandler)(void* target, int64_t memPtr); + typedef int(JNICALL* CacheStoreInvokeHandler)(void* target, int64_t objPtr, + int64_t memPtr); + typedef void(JNICALL* CacheStoreDestroyHandler)(void* target, int64_t objPtr); + typedef int64_t(JNICALL* CacheStoreSessionCreateHandler)(void* target, + int64_t storePtr); + + typedef int64_t(JNICALL* CacheEntryFilterCreateHandler)(void* target, + int64_t memPtr); + typedef int(JNICALL* CacheEntryFilterApplyHandler)(void* target, int64_t ptr, + int64_t memPtr); + typedef void(JNICALL* CacheEntryFilterDestroyHandler)(void* target, + int64_t ptr); + + typedef void(JNICALL* CacheInvokeHandler)(void* target, int64_t inMemPtr, + int64_t outMemPtr); + + typedef void(JNICALL* ComputeTaskMapHandler)(void* target, int64_t taskPtr, + int64_t inMemPtr, + int64_t outMemPtr); + typedef int(JNICALL* ComputeTaskJobResultHandler)(void* target, int64_t taskPtr, + int64_t jobPtr, + int64_t memPtr); + typedef void(JNICALL* ComputeTaskReduceHandler)(void* target, int64_t taskPtr); + typedef void(JNICALL* ComputeTaskCompleteHandler)(void* target, int64_t taskPtr, + int64_t memPtr); + typedef int(JNICALL* ComputeJobSerializeHandler)(void* target, int64_t jobPtr, + int64_t memPtr); + typedef int64_t(JNICALL* ComputeJobCreateHandler)(void* target, int64_t memPtr); + typedef void(JNICALL* ComputeJobExecuteHandler)(void* target, int64_t jobPtr, + int cancel, int64_t memPtr); + typedef void(JNICALL* ComputeJobCancelHandler)(void* target, int64_t jobPtr); + typedef void(JNICALL* ComputeJobDestroyHandler)(void* target, int64_t jobPtr); + + typedef void(JNICALL* ContinuousQueryListenerApplyHandler)(void* target, + int64_t lsnrPtr, + int64_t memPtr); + typedef int64_t(JNICALL* ContinuousQueryFilterCreateHandler)(void* target, + int64_t memPtr); + typedef int(JNICALL* ContinuousQueryFilterApplyHandler)(void* target, + int64_t filterPtr, + int64_t memPtr); + typedef void(JNICALL* ContinuousQueryFilterReleaseHandler)(void* target, + int64_t filterPtr); + + typedef void(JNICALL* DataStreamerTopologyUpdateHandler)(void* target, + int64_t ldrPtr, + int64_t topVer, + int topSize); + typedef void(JNICALL* DataStreamerStreamReceiverInvokeHandler)( + void* target, int64_t ptr, void* cache, int64_t memPtr, + unsigned char keepPortable); + + typedef void(JNICALL* FutureByteResultHandler)(void* target, int64_t futAddr, + int res); + typedef void(JNICALL* FutureBoolResultHandler)(void* target, int64_t futAddr, + int res); + typedef void(JNICALL* FutureShortResultHandler)(void* target, int64_t futAddr, + int res); + typedef void(JNICALL* FutureCharResultHandler)(void* target, int64_t futAddr, + int res); + typedef void(JNICALL* FutureIntResultHandler)(void* target, int64_t futAddr, + int res); + typedef void(JNICALL* FutureFloatResultHandler)(void* target, int64_t futAddr, + float res); + typedef void(JNICALL* FutureLongResultHandler)(void* target, int64_t futAddr, + int64_t res); + typedef void(JNICALL* FutureDoubleResultHandler)(void* target, int64_t futAddr, + double res); + typedef void(JNICALL* FutureObjectResultHandler)(void* target, int64_t futAddr, + int64_t memPtr); + typedef void(JNICALL* FutureNullResultHandler)(void* target, int64_t futAddr); + typedef void(JNICALL* FutureErrorHandler)(void* target, int64_t futAddr, + int64_t memPtr); + + typedef void(JNICALL* LifecycleEventHandler)(void* target, int64_t ptr, + int evt); + + typedef void(JNICALL* MemoryReallocateHandler)(void* target, int64_t memPtr, + int cap); + + typedef int64_t(JNICALL* MessagingFilterCreateHandler)(void* target, + int64_t memPtr); + typedef int(JNICALL* MessagingFilterApplyHandler)(void* target, int64_t ptr, + int64_t memPtr); + typedef void(JNICALL* MessagingFilterDestroyHandler)(void* target, int64_t ptr); + + typedef int64_t(JNICALL* EventFilterCreateHandler)(void* target, + int64_t memPtr); + typedef int(JNICALL* EventFilterApplyHandler)(void* target, int64_t ptr, + int64_t memPtr); + typedef void(JNICALL* EventFilterDestroyHandler)(void* target, int64_t ptr); + + typedef int64_t(JNICALL* ServiceInitHandler)(void* target, int64_t memPtr); + typedef void(JNICALL* ServiceExecuteHandler)(void* target, int64_t svcPtr, + int64_t memPtr); + typedef void(JNICALL* ServiceCancelHandler)(void* target, int64_t svcPtr, + int64_t memPtr); + typedef void(JNICALL* ServiceInvokeMethodHandler)(void* target, int64_t svcPtr, + int64_t inMemPtr, + int64_t outMemPtr); + typedef int(JNICALL* ClusterNodeFilterApplyHandler)(void* target, + int64_t memPtr); + + typedef int64_t(JNICALL* NodeInfoHandler)(void* target, int64_t memPtr); + + typedef void(JNICALL* OnStartHandler)(void* target, void* proc, int64_t memPtr); + typedef void(JNICALL* OnStopHandler)(void* target); + typedef void(JNICALL* ErrorHandler)(void* target, int errCode, + const char* errClsChars, int errClsCharsLen, + const char* errMsgChars, int errMsgCharsLen, + const char* stackTraceChars, + int stackTraceCharsLen, void* errData, + int errDataLen); + + typedef int64_t(JNICALL* ExtensionCallbackInLongOutLongHandler)(void* target, + int typ, + int64_t arg1); + typedef int64_t(JNICALL* ExtensionCallbackInLongLongOutLongHandler)( + void* target, int typ, int64_t arg1, int64_t arg2); + + typedef void(JNICALL* OnClientDisconnectedHandler)(void* target); + typedef void(JNICALL* OnClientReconnectedHandler)( + void* target, unsigned char clusterRestarted); + + typedef int64_t(JNICALL* AffinityFunctionInitHandler)(void* target, + int64_t memPtr, + void* baseFunc); + typedef int(JNICALL* AffinityFunctionPartitionHandler)(void* target, + int64_t ptr, + int64_t memPtr); + typedef void(JNICALL* AffinityFunctionAssignPartitionsHandler)( + void* target, int64_t ptr, int64_t inMemPtr, int64_t outMemPtr); + typedef void(JNICALL* AffinityFunctionRemoveNodeHandler)(void* target, + int64_t ptr, + int64_t memPtr); + typedef void(JNICALL* AffinityFunctionDestroyHandler)(void* target, + int64_t ptr); + + typedef void(JNICALL* ConsoleWriteHandler)(const char* chars, int charsLen, + unsigned char isErr); + + typedef void(JNICALL* LoggerLogHandler)( + void* target, int level, const char* messageChars, int messageCharsLen, + const char* categoryChars, int categoryCharsLen, const char* errorInfoChars, + int errorInfoCharsLen, int64_t memPtr); + typedef bool(JNICALL* LoggerIsLevelEnabledHandler)(void* target, int level); + + typedef int64_t(JNICALL* InLongOutLongHandler)(void* target, int type, + int64_t val); + typedef int64_t(JNICALL* InLongLongLongObjectOutLongHandler)( + void* target, int type, int64_t val1, int64_t val2, int64_t val3, + void* arg); + + /** + * Is Java 9 or later is used. + * + * @return true if the Java 9 or later is in use. + */ + bool IGNITE_IMPORT_EXPORT IsJava9OrLater(); + + /** + * JNI handlers holder. + */ + struct JniHandlers { + void* target; + + ErrorHandler error; + + LoggerLogHandler loggerLog; + LoggerIsLevelEnabledHandler loggerIsLevelEnabled; + + InLongOutLongHandler inLongOutLong; + InLongLongLongObjectOutLongHandler inLongLongLongObjectOutLong; + }; + + /** + * JNI Java members. + */ + struct JniJavaMembers { + jclass c_Class; + jmethodID m_Class_getName; + + jclass c_Throwable; + jmethodID m_Throwable_getMessage; + jmethodID m_Throwable_printStackTrace; + + jclass c_PlatformUtils; + jmethodID m_PlatformUtils_getFullStackTrace; + + /** + * Constructor. + */ + void Initialize(JNIEnv* env); + + /** + * Destroy members releasing all allocated classes. + */ + void Destroy(JNIEnv* env); + + /** + * Write error information. + */ + bool WriteErrorInfo(JNIEnv* env, char** errClsName, int* errClsNameLen, + char** errMsg, int* errMsgLen, char** stackTrace, + int* stackTraceLen); + }; + + /** + * JNI members. + */ + struct JniMembers { + jclass c_DocumentDbConnectionProperties; + jmethodID m_DocumentDbConnectionPropertiesGetPropertiesFromConnectionString; + + jclass c_DocumentDbConnection; + jmethodID m_DocumentDbConnectionInit; + jmethodID m_DocumentDbClose; + + jclass c_DriverManager; + jmethodID m_DriverManagerGetConnection; + + jclass c_JavaSqlConnection; + jmethodID m_JavaSqlConnectionClose; + + jclass c_IgniteException; + + jclass c_PlatformIgnition; + jmethodID m_PlatformIgnition_start; + jmethodID m_PlatformIgnition_instance; + jmethodID m_PlatformIgnition_environmentPointer; + jmethodID m_PlatformIgnition_stop; + jmethodID m_PlatformIgnition_stopAll; + + jclass c_PlatformTarget; + jmethodID m_PlatformTarget_inLongOutLong; + jmethodID m_PlatformTarget_inStreamOutLong; + jmethodID m_PlatformTarget_inStreamOutObject; + jmethodID m_PlatformTarget_outStream; + jmethodID m_PlatformTarget_outObject; + jmethodID m_PlatformTarget_inStreamAsync; + jmethodID m_PlatformTarget_inStreamOutObjectAsync; + jmethodID m_PlatformTarget_inStreamOutStream; + jmethodID m_PlatformTarget_inObjectStreamOutObjectStream; + + jclass c_PlatformUtils; + jmethodID m_PlatformUtils_reallocate; + jmethodID m_PlatformUtils_errData; + + /** + * Constructor. + */ + void Initialize(JNIEnv* env); + + /** + * Destroy members releasing all allocated classes. + */ + void Destroy(JNIEnv* env); + }; + + /** + * JNI JVM wrapper. + */ + class IGNITE_IMPORT_EXPORT JniJvm { + public: + /** + * Default constructor for uninitialized JVM. + */ + JniJvm(); + + /** + * Constructor. + * + * @param jvm JVM. + * @param javaMembers Java members. + * @param members Members. + */ + JniJvm(JavaVM* jvm, JniJavaMembers javaMembers, JniMembers members); + + /** + * Get JVM. + * + * @param JVM. + */ + JavaVM* GetJvm(); + + /** + * Get Java members. + * + * @param Java members. + */ + JniJavaMembers& GetJavaMembers(); + + /** + * Get members. + * + * @param Members. + */ + JniMembers& GetMembers(); + + private: + /** JVM. */ + JavaVM* jvm; + + /** Java members. */ + JniJavaMembers javaMembers; + + /** Members. */ + JniMembers members; + }; + + /** + * JNI error information. + */ + struct IGNITE_IMPORT_EXPORT JniErrorInfo { + int code; + char* errCls = nullptr; + char* errMsg = nullptr; + + /** + * Default constructor. Creates empty error info. + */ + JniErrorInfo(); + + /** + * Constructor. + * + * @param code Code. + * @param errCls Error class. + * @param errMsg Error message. + */ + JniErrorInfo(int code, const char* errCls, const char* errMsg); + + /** + * Copy constructor. + * + * @param other Other instance. + */ + JniErrorInfo(const JniErrorInfo& other); + + /** + * Assignment operator overload. + * + * @param other Other instance. + * @return This instance. + */ + JniErrorInfo& operator=(const JniErrorInfo& other); + + /** + * Destructor. + */ + ~JniErrorInfo(); + }; + + /** + * Unmanaged context. + */ + class IGNITE_IMPORT_EXPORT JniContext { + public: + static JniContext* Create(char** opts, int optsLen, JniHandlers hnds); + static JniContext* Create(char** opts, int optsLen, JniHandlers hnds, + JniErrorInfo* errInfo); + static int Reallocate(int64_t memPtr, int cap); + static void Detach(); + static void Release(jobject obj); + static void SetConsoleHandler(ConsoleWriteHandler consoleHandler); + static int RemoveConsoleHandler(ConsoleWriteHandler consoleHandler); + + jobject DocumentDbConnect(const char* connectionString, + JniErrorInfo* errInfo); + + void DocumentDbDisconnect(const jobject connection, JniErrorInfo* errInfo); + + int64_t TargetInLongOutLong(jobject obj, int type, int64_t memPtr, + JniErrorInfo* errInfo = NULL); + int64_t TargetInStreamOutLong(jobject obj, int type, int64_t memPtr, + JniErrorInfo* errInfo = NULL); + void TargetInStreamOutStream(jobject obj, int opType, int64_t inMemPtr, + int64_t outMemPtr, + JniErrorInfo* errInfo = NULL); + jobject TargetInStreamOutObject(jobject obj, int type, int64_t memPtr, + JniErrorInfo* errInfo = NULL); + jobject TargetInObjectStreamOutObjectStream(jobject obj, int opType, + void* arg, int64_t inMemPtr, + int64_t outMemPtr, + JniErrorInfo* errInfo = NULL); + void TargetOutStream(jobject obj, int opType, int64_t memPtr, + JniErrorInfo* errInfo = NULL); + jobject TargetOutObject(jobject obj, int opType, + JniErrorInfo* errInfo = NULL); + void TargetInStreamAsync(jobject obj, int type, int64_t memPtr, + JniErrorInfo* errInfo = NULL); + jobject TargetInStreamOutObjectAsync(jobject obj, int type, int64_t memPtr, + JniErrorInfo* errInfo = NULL); + + jobject CacheOutOpQueryCursor(jobject obj, int type, int64_t memPtr, + JniErrorInfo* errInfo = NULL); + jobject CacheOutOpContinuousQuery(jobject obj, int type, int64_t memPtr, + JniErrorInfo* errInfo = NULL); + + jobject Acquire(jobject obj); + + void DestroyJvm(); + void ThrowToJava(char* errMsg); + + private: + JniJvm* jvm; + JniHandlers hnds; + + JniContext(JniJvm* jvm, JniHandlers hnds); + + JNIEnv* Attach(); + void ExceptionCheck(JNIEnv* env); + void ExceptionCheck(JNIEnv* env, JniErrorInfo* errInfo); + jobject LocalToGlobal(JNIEnv* env, jobject obj); + }; + + JNIEXPORT jlong JNICALL JniCacheStoreCreate(JNIEnv* env, jclass cls, + jlong envPtr, jlong memPtr); + JNIEXPORT jint JNICALL JniCacheStoreInvoke(JNIEnv* env, jclass cls, + jlong envPtr, jlong objPtr, + jlong memPtr); + JNIEXPORT void JNICALL JniCacheStoreDestroy(JNIEnv* env, jclass cls, + jlong envPtr, jlong objPtr); + JNIEXPORT jlong JNICALL JniCacheStoreSessionCreate(JNIEnv* env, jclass cls, + jlong envPtr, + jlong storePtr); + + JNIEXPORT jlong JNICALL JniCacheEntryFilterCreate(JNIEnv* env, jclass cls, + jlong envPtr, jlong memPtr); + JNIEXPORT jint JNICALL JniCacheEntryFilterApply(JNIEnv* env, jclass cls, + jlong envPtr, jlong objPtr, + jlong memPtr); + JNIEXPORT void JNICALL JniCacheEntryFilterDestroy(JNIEnv* env, jclass cls, + jlong envPtr, jlong objPtr); + + JNIEXPORT void JNICALL JniCacheInvoke(JNIEnv* env, jclass cls, jlong envPtr, + jlong inMemPtr, jlong outMemPtr); + + JNIEXPORT void JNICALL JniComputeTaskMap(JNIEnv* env, jclass cls, jlong envPtr, + jlong taskPtr, jlong inMemPtr, + jlong outMemPtr); + JNIEXPORT jint JNICALL JniComputeTaskJobResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong taskPtr, + jlong jobPtr, jlong memPtr); + JNIEXPORT void JNICALL JniComputeTaskReduce(JNIEnv* env, jclass cls, + jlong envPtr, jlong taskPtr); + JNIEXPORT void JNICALL JniComputeTaskComplete(JNIEnv* env, jclass cls, + jlong envPtr, jlong taskPtr, + jlong memPtr); + JNIEXPORT jint JNICALL JniComputeJobSerialize(JNIEnv* env, jclass cls, + jlong envPtr, jlong jobPtr, + jlong memPtr); + JNIEXPORT jlong JNICALL JniComputeJobCreate(JNIEnv* env, jclass cls, + jlong envPtr, jlong memPtr); + JNIEXPORT void JNICALL JniComputeJobExecute(JNIEnv* env, jclass cls, + jlong envPtr, jlong jobPtr, + jint cancel, jlong memPtr); + JNIEXPORT void JNICALL JniComputeJobCancel(JNIEnv* env, jclass cls, + jlong envPtr, jlong jobPtr); + JNIEXPORT void JNICALL JniComputeJobDestroy(JNIEnv* env, jclass cls, + jlong envPtr, jlong jobPtr); + + JNIEXPORT void JNICALL JniContinuousQueryListenerApply(JNIEnv* env, jclass cls, + jlong envPtr, + jlong cbPtr, + jlong memPtr); + JNIEXPORT jlong JNICALL JniContinuousQueryFilterCreate(JNIEnv* env, jclass cls, + jlong envPtr, + jlong memPtr); + JNIEXPORT jint JNICALL JniContinuousQueryFilterApply(JNIEnv* env, jclass cls, + jlong envPtr, + jlong filterPtr, + jlong memPtr); + JNIEXPORT void JNICALL JniContinuousQueryFilterRelease(JNIEnv* env, jclass cls, + jlong envPtr, + jlong filterPtr); + + JNIEXPORT void JNICALL JniDataStreamerTopologyUpdate(JNIEnv* env, jclass cls, + jlong envPtr, jlong ldrPtr, + jlong topVer, + jint topSize); + JNIEXPORT void JNICALL JniDataStreamerStreamReceiverInvoke( + JNIEnv* env, jclass cls, jlong envPtr, jlong ptr, jobject cache, + jlong memPtr, jboolean keepPortable); + + JNIEXPORT void JNICALL JniFutureByteResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr, + jint res); + JNIEXPORT void JNICALL JniFutureBoolResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr, + jint res); + JNIEXPORT void JNICALL JniFutureShortResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr, + jint res); + JNIEXPORT void JNICALL JniFutureCharResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr, + jint res); + JNIEXPORT void JNICALL JniFutureIntResult(JNIEnv* env, jclass cls, jlong envPtr, + jlong futPtr, jint res); + JNIEXPORT void JNICALL JniFutureFloatResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr, + jfloat res); + JNIEXPORT void JNICALL JniFutureLongResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr, + jlong res); + JNIEXPORT void JNICALL JniFutureDoubleResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr, + jdouble res); + JNIEXPORT void JNICALL JniFutureObjectResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr, + jlong memPtr); + JNIEXPORT void JNICALL JniFutureNullResult(JNIEnv* env, jclass cls, + jlong envPtr, jlong futPtr); + JNIEXPORT void JNICALL JniFutureError(JNIEnv* env, jclass cls, jlong envPtr, + jlong futPtr, jlong memPtr); + + JNIEXPORT void JNICALL JniLifecycleEvent(JNIEnv* env, jclass cls, jlong envPtr, + jlong ptr, jint evt); + + JNIEXPORT void JNICALL JniMemoryReallocate(JNIEnv* env, jclass cls, + jlong envPtr, jlong memPtr, + jint cap); + + JNIEXPORT jlong JNICALL JniMessagingFilterCreate(JNIEnv* env, jclass cls, + jlong envPtr, jlong memPtr); + JNIEXPORT jint JNICALL JniMessagingFilterApply(JNIEnv* env, jclass cls, + jlong envPtr, jlong ptr, + jlong memPtr); + JNIEXPORT void JNICALL JniMessagingFilterDestroy(JNIEnv* env, jclass cls, + jlong envPtr, jlong ptr); + + JNIEXPORT jlong JNICALL JniEventFilterCreate(JNIEnv* env, jclass cls, + jlong envPtr, jlong memPtr); + JNIEXPORT jint JNICALL JniEventFilterApply(JNIEnv* env, jclass cls, + jlong envPtr, jlong ptr, + jlong memPtr); + JNIEXPORT void JNICALL JniEventFilterDestroy(JNIEnv* env, jclass cls, + jlong envPtr, jlong ptr); + + JNIEXPORT jlong JNICALL JniServiceInit(JNIEnv* env, jclass cls, jlong envPtr, + jlong memPtr); + JNIEXPORT void JNICALL JniServiceExecute(JNIEnv* env, jclass cls, jlong envPtr, + jlong svcPtr, jlong memPtr); + JNIEXPORT void JNICALL JniServiceCancel(JNIEnv* env, jclass cls, jlong envPtr, + jlong svcPtr, jlong memPtr); + JNIEXPORT void JNICALL JniServiceInvokeMethod(JNIEnv* env, jclass cls, + jlong envPtr, jlong svcPtr, + jlong inMemPtr, jlong outMemPtr); + JNIEXPORT jint JNICALL JniClusterNodeFilterApply(JNIEnv* env, jclass cls, + jlong envPtr, jlong memPtr); + + JNIEXPORT jlong JNICALL JniNodeInfo(JNIEnv* env, jclass cls, jlong envPtr, + jlong memPtr); + + JNIEXPORT void JNICALL JniOnStart(JNIEnv* env, jclass cls, jlong envPtr, + jobject proc, jlong memPtr); + JNIEXPORT void JNICALL JniOnStop(JNIEnv* env, jclass cls, jlong envPtr); + + JNIEXPORT jlong JNICALL JniExtensionCallbackInLongOutLong(JNIEnv* env, + jclass cls, + jlong envPtr, + jint typ, jlong arg1); + JNIEXPORT jlong JNICALL JniExtensionCallbackInLongLongOutLong( + JNIEnv* env, jclass cls, jlong envPtr, jint typ, jlong arg1, jlong arg2); + + JNIEXPORT void JNICALL JniOnClientDisconnected(JNIEnv* env, jclass cls, + jlong envPtr); + JNIEXPORT void JNICALL JniOnClientReconnected(JNIEnv* env, jclass cls, + jlong envPtr, + jboolean clusterRestarted); + + JNIEXPORT jlong JNICALL JniAffinityFunctionInit(JNIEnv* env, jclass cls, + jlong envPtr, jlong memPtr, + jobject baseFunc); + JNIEXPORT jint JNICALL JniAffinityFunctionPartition(JNIEnv* env, jclass cls, + jlong envPtr, jlong ptr, + jlong memPtr); + JNIEXPORT void JNICALL + JniAffinityFunctionAssignPartitions(JNIEnv* env, jclass cls, jlong envPtr, + jlong ptr, jlong inMemPtr, jlong outMemPtr); + JNIEXPORT void JNICALL JniAffinityFunctionRemoveNode(JNIEnv* env, jclass cls, + jlong envPtr, jlong ptr, + jlong memPtr); + JNIEXPORT void JNICALL JniAffinityFunctionDestroy(JNIEnv* env, jclass cls, + jlong envPtr, jlong ptr); + + JNIEXPORT void JNICALL JniConsoleWrite(JNIEnv* env, jclass cls, jstring str, + jboolean isErr); + + JNIEXPORT void JNICALL JniLoggerLog(JNIEnv* env, jclass cls, jlong envPtr, + jint level, jstring message, + jstring category, jstring errorInfo, + jlong memPtr); + JNIEXPORT jboolean JNICALL JniLoggerIsLevelEnabled(JNIEnv* env, jclass cls, + jlong envPtr, jint level); + + JNIEXPORT jlong JNICALL JniInLongOutLong(JNIEnv* env, jclass cls, jlong envPtr, + jint type, jlong val); + JNIEXPORT jlong JNICALL JniInLongLongLongObjectOutLong(JNIEnv* env, jclass cls, + jlong envPtr, jint type, + jlong val1, jlong val2, + jlong val3, jobject arg); + } // namespace java + } // namespace jni + } // namespace odbc +} // namespace ignite + +#endif //_IGNITE_ODBC_JNI_JAVA diff --git a/src/odbc/include/ignite/odbc/jni/utils.h b/src/odbc/include/ignite/odbc/jni/utils.h new file mode 100644 index 000000000..508a40756 --- /dev/null +++ b/src/odbc/include/ignite/odbc/jni/utils.h @@ -0,0 +1,193 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _IGNITE_ODBC_JNI_UTILS +#define _IGNITE_ODBC_JNI_UTILS + +#include + +#include +#include +#include + +namespace ignite +{ + namespace odbc + { + namespace jni + { + /** + * Helper class to manage attached threads. + */ + class AttachHelper + { + public: + /** + * Destructor. + */ + ~AttachHelper(); + + /** + * Callback invoked on successful thread attach ot JVM. + */ + static void OnThreadAttach(); + }; + + /** + * Represents global reference to Java object. + */ + class IGNITE_IMPORT_EXPORT JavaGlobalRef + { + public: + /** + * Default constructor + */ + JavaGlobalRef() : + obj(NULL) + { + // No-op. + } + + /** + * Constructor + * + * @param ctx JNI context. + * @param obj Java object. + */ + JavaGlobalRef(common::concurrent::SharedPointer& ctx, jobject obj) + : obj(NULL) + { + Init(ctx, obj); + } + + /** + * Copy constructor + * + * @param other Other instance. + */ + JavaGlobalRef(const JavaGlobalRef& other) + : obj(NULL) + { + Init(other.ctx, other.obj); + } + + /** + * Assignment operator. + * + * @param other Other instance. + * @return *this. + */ + JavaGlobalRef& operator=(const JavaGlobalRef& other) + { + if (this != &other) + { + java::JniContext::Release(obj); + + Init(other.ctx, other.obj); + } + + return *this; + } + + /** + * Destructor. + */ + ~JavaGlobalRef() + { + java::JniContext::Release(obj); + } + + /** + * Get object. + * + * @return Object. + */ + jobject Get() + { + return obj; + } + + private: + /** Initializer */ + void Init(const common::concurrent::SharedPointer& ctx0, jobject obj0) { + ctx = ctx0; + + if (ctx.IsValid()) + this->obj = ctx.Get()->Acquire(obj0); + } + + /** Context. */ + common::concurrent::SharedPointer ctx; + + /** Object. */ + jobject obj; + }; + + /** + * Attempts to find JVM library to load it into the process later. + * First search is performed using the passed path argument (is not NULL). + * Then JRE_HOME is evaluated. Last, JAVA_HOME is evaluated. + * + * @param path Explicitly defined path (optional). + * @return Path to the file. Empty string if the library was not found. + */ + IGNITE_IMPORT_EXPORT std::string FindJvmLibrary(const std::string& path); + + /** + * Load JVM library into the process. + * + * @param path Optional path to the library. + * @return Whether load was successful. + */ + IGNITE_IMPORT_EXPORT bool LoadJvmLibrary(const std::string& path); + + /** + * Helper function to create classpath based on Ignite home directory. + * + * @param home Home directory; expected to be valid. + * @param forceTest Force test classpath. + * @return Classpath. + */ + IGNITE_IMPORT_EXPORT std::string CreateDocumentDbHomeClasspath(const std::string& home, bool forceTest); + + /** + * Create Ignite classpath based on user input and home directory. + * + * @param usrCp User's classpath. + * @param home Ignite home directory. + * @return Classpath. + */ + IGNITE_IMPORT_EXPORT std::string CreateDocumentDbClasspath(const std::string& usrCp, const std::string& home); + + /** + * Resolve DOCUMENTDB_HOME directory. Resolution is performed in several + * steps: + * 1) Check for path provided as argument. + * 2) Check for environment variable. + * 3) Check for current working directory. + * Result of these checks are evaluated based on existence of certain + * predefined folders inside possible Ignite home. If they are found, + * IGNITE_HOME is considered resolved. + * + * @param path Optional path to evaluate. + * @return Resolved Ignite home. + */ + IGNITE_IMPORT_EXPORT std::string ResolveDocumentDbHome(const std::string& path = ""); + } + } +} + +#endif //_IGNITE_ODBC_JNI_UTILS diff --git a/src/odbc/include/ignite/odbc/log.h b/src/odbc/include/ignite/odbc/log.h index 5a6dafcb9..2e361ea20 100644 --- a/src/odbc/include/ignite/odbc/log.h +++ b/src/odbc/include/ignite/odbc/log.h @@ -22,8 +22,8 @@ #include #include -#include "ignite/common/common.h" -#include "ignite/common/concurrent.h" +#include "ignite/odbc/common/common.h" +#include "ignite/odbc/common/concurrent.h" # define LOG_MSG(param) \ if (ignite::odbc::Logger* p = ignite::odbc::Logger::Get()) \ @@ -112,7 +112,7 @@ namespace ignite IGNITE_NO_COPY_ASSIGNMENT(Logger); /** Mutex for writes synchronization. */ - ignite::common::concurrent::CriticalSection mutex; + odbc::common::concurrent::CriticalSection mutex; /** File stream. */ std::ofstream stream; diff --git a/src/odbc/include/ignite/odbc/meta/column_meta.h b/src/odbc/include/ignite/odbc/meta/column_meta.h index 5144fa3b8..d38ed2b9c 100644 --- a/src/odbc/include/ignite/odbc/meta/column_meta.h +++ b/src/odbc/include/ignite/odbc/meta/column_meta.h @@ -75,7 +75,7 @@ namespace ignite /** * Default constructor. */ - ColumnMeta() + ColumnMeta() : dataType(), nullability(), precision(), scale() { // No-op. } diff --git a/src/odbc/include/ignite/odbc/meta/primary_key_meta.h b/src/odbc/include/ignite/odbc/meta/primary_key_meta.h index a2f531863..1cb69f741 100644 --- a/src/odbc/include/ignite/odbc/meta/primary_key_meta.h +++ b/src/odbc/include/ignite/odbc/meta/primary_key_meta.h @@ -40,7 +40,7 @@ namespace ignite /** * Default constructor. */ - PrimaryKeyMeta() + PrimaryKeyMeta() : keySeq(0) { // No-op. } diff --git a/src/odbc/include/ignite/odbc/odbc_error.h b/src/odbc/include/ignite/odbc/odbc_error.h index 9b3b48d4f..07664329d 100644 --- a/src/odbc/include/ignite/odbc/odbc_error.h +++ b/src/odbc/include/ignite/odbc/odbc_error.h @@ -21,7 +21,7 @@ #include #include -#include +#include namespace ignite { @@ -102,13 +102,13 @@ namespace ignite std::string errMessage; }; - typedef common::Unexpected OdbcUnexpected; + typedef odbc::common::Unexpected OdbcUnexpected; /** * Expected specialization for OdbcError. */ template - struct OdbcExpected : common::Expected + struct OdbcExpected : odbc::common::Expected { OdbcExpected(const R& res) : common::Expected(res) diff --git a/src/odbc/include/ignite/odbc/utility.h b/src/odbc/include/ignite/odbc/utility.h index 152da6635..cf31de0d6 100644 --- a/src/odbc/include/ignite/odbc/utility.h +++ b/src/odbc/include/ignite/odbc/utility.h @@ -26,8 +26,8 @@ #include -#include -#include +#include +#include #include "ignite/impl/binary/binary_reader_impl.h" #include "ignite/impl/binary/binary_writer_impl.h" @@ -83,7 +83,7 @@ namespace ignite * @param reader Reader. * @param decimal Decimal value. */ - void ReadDecimal(impl::binary::BinaryReaderImpl& reader, common::Decimal& decimal); + void ReadDecimal(impl::binary::BinaryReaderImpl& reader, odbc::common::Decimal& decimal); /** * Write decimal value using writer. @@ -91,7 +91,7 @@ namespace ignite * @param writer Writer. * @param decimal Decimal value. */ - void WriteDecimal(impl::binary::BinaryWriterImpl& writer, const common::Decimal& decimal); + void WriteDecimal(impl::binary::BinaryWriterImpl& writer, const odbc::common::Decimal& decimal); /** * Convert SQL string buffer to std::string. diff --git a/src/odbc/install/install_amd64.cmd b/src/odbc/install/install_amd64.cmd index 6c7de9393..5795e0cf8 100644 --- a/src/odbc/install/install_amd64.cmd +++ b/src/odbc/install/install_amd64.cmd @@ -29,7 +29,7 @@ if exist %ODBC_AMD64% ( if [%ODBC_X86%] == [] ( echo warning: 32-bit driver is not specified. If you want to install 32-bit driver please specify path to it as a second argument. pause - exit /b 1 + exit /b 0 ) if exist %ODBC_X86% ( @@ -44,5 +44,6 @@ if exist %ODBC_X86% ( reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI\ODBC Drivers" /v "Apache Ignite" /t REG_SZ /d "Installed" /f ) else ( echo warning: 32-bit driver can not be found: %ODBC_X86% + exit /b 1 ) diff --git a/src/odbc/os/linux/include/ignite/odbc/common/common.h b/src/odbc/os/linux/include/ignite/odbc/common/common.h new file mode 100644 index 000000000..5e3924c3a --- /dev/null +++ b/src/odbc/os/linux/include/ignite/odbc/common/common.h @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_ODBC_COMMON_COMMON +#define _IGNITE_ODBC_COMMON_COMMON + +#ifndef __has_attribute +# define __has_attribute(x) 0 +#endif + +#if (defined(__GNUC__) && ((__GNUC__ > 4) || (__GNUC__ == 4) && (__GNUC_MINOR__ > 2))) || __has_attribute(visibility) +# define IGNITE_EXPORT __attribute__((visibility("default"))) +# define IGNITE_IMPORT __attribute__((visibility("default"))) +#else +# define IGNITE_EXPORT +# define IGNITE_IMPORT +#endif + +#define IGNITE_CALL + +#ifdef IGNITE_IMPL +# define IGNITE_IMPORT_EXPORT IGNITE_EXPORT +#else +# define IGNITE_IMPORT_EXPORT IGNITE_IMPORT +#endif + +#if (__cplusplus >= 201103L) +# define IGNITE_NO_THROW noexcept +#else +# define IGNITE_NO_THROW throw() +#endif + +#define IGNITE_UNUSED(x) ((void) x) + +/** + * Common construction to disable copy constructor and assignment for class. + */ +#define IGNITE_NO_COPY_ASSIGNMENT(cls) \ + cls(const cls& src); \ + cls& operator= (const cls& other) + +#endif //_IGNITE_ODBC_COMMON_COMMON diff --git a/src/odbc/os/linux/include/ignite/odbc/common/concurrent_os.h b/src/odbc/os/linux/include/ignite/odbc/common/concurrent_os.h new file mode 100644 index 000000000..74711337b --- /dev/null +++ b/src/odbc/os/linux/include/ignite/odbc/common/concurrent_os.h @@ -0,0 +1,701 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_ODBC_COMMON_CONCURRENT_OS +#define _IGNITE_ODBC_COMMON_CONCURRENT_OS + +#include +#include +#include + +#include + +#include +#include + +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + namespace concurrent + { + /** + * Static class to manage memory visibility semantics. + */ + class IGNITE_IMPORT_EXPORT Memory { + public: + /** + * Full fence. + */ + static void Fence(); + }; + + /** + * Critical section. + */ + class IGNITE_IMPORT_EXPORT CriticalSection + { + friend class ConditionVariable; + public: + /** + * Constructor. + */ + CriticalSection(); + + /** + * Destructor. + */ + ~CriticalSection(); + + /** + * Enter critical section. + */ + void Enter(); + + /** + * Leave critical section. + */ + void Leave(); + private: + pthread_mutex_t mux; + + IGNITE_NO_COPY_ASSIGNMENT(CriticalSection); + }; + + class IGNITE_IMPORT_EXPORT ReadWriteLock + { + public: + /** + * Constructor. + */ + ReadWriteLock(); + + /** + * Destructor. + */ + ~ReadWriteLock(); + + /** + * Lock in exclusive mode. + */ + void LockExclusive(); + + /** + * Release in exclusive mode. + */ + void ReleaseExclusive(); + + /** + * Lock in shared mode. + */ + void LockShared(); + + /** + * Release in shared mode. + */ + void ReleaseShared(); + + private: + /** Lock. */ + pthread_rwlock_t lock; + + IGNITE_NO_COPY_ASSIGNMENT(ReadWriteLock); + }; + + /** + * Special latch with count = 1. + */ + class IGNITE_IMPORT_EXPORT SingleLatch + { + public: + /** + * Constructor. + */ + SingleLatch(); + + /** + * Destructor. + */ + ~SingleLatch(); + + /** + * Perform the countdown. + */ + void CountDown(); + + /** + * Await the countdown. + */ + void Await(); + private: + /** Mutex. */ + pthread_mutex_t mux; + + /** Condition. */ + pthread_cond_t cond; + + /** Ready flag. */ + bool ready; + + IGNITE_NO_COPY_ASSIGNMENT(SingleLatch); + }; + + /** + * Primitives for atomic access. + */ + class IGNITE_IMPORT_EXPORT Atomics + { + public: + /** + * Update the 32-bit integer value if it is equal to expected value. + * + * @param ptr Pointer. + * @param expVal Expected value. + * @param newVal New value. + * @return True if update occurred as a result of this call, false otherwise. + */ + static bool CompareAndSet32(int32_t* ptr, int32_t expVal, int32_t newVal); + + /** + * Update the 32-bit integer value if it is equal to expected value. + * + * @param ptr Pointer. + * @param expVal Expected value. + * @param newVal New value. + * @return Value which were observed during CAS attempt. + */ + static int32_t CompareAndSet32Val(int32_t* ptr, int32_t expVal, int32_t newVal); + + /** + * Increment 32-bit integer and return new value. + * + * @param ptr Pointer. + * @return Value after increment. + */ + static int32_t IncrementAndGet32(int32_t* ptr); + + /** + * Decrement 32-bit integer and return new value. + * + * @param ptr Pointer. + * @return Value after decrement. + */ + static int32_t DecrementAndGet32(int32_t* ptr); + + /** + * Update the 64-bit integer value if it is equal to expected value. + * + * @param ptr Pointer. + * @param expVal Expected value. + * @param newVal New value. + * @return True if update occurred as a result of this call, false otherwise. + */ + static bool CompareAndSet64(int64_t* ptr, int64_t expVal, int64_t newVal); + + /** + * Update the 64-bit integer value if it is equal to expected value. + * + * @param ptr Pointer. + * @param expVal Expected value. + * @param newVal New value. + * @return Value which were observed during CAS attempt. + */ + static int64_t CompareAndSet64Val(int64_t* ptr, int64_t expVal, int64_t newVal); + + /** + * Increment 64-bit integer and return new value. + * + * @param ptr Pointer. + * @return Value after increment. + */ + static int64_t IncrementAndGet64(int64_t* ptr); + + /** + * Decrement 64-bit integer and return new value. + * + * @param ptr Pointer. + * @return Value after decrement. + */ + static int64_t DecrementAndGet64(int64_t* ptr); + }; + + /** + * Thread-local entry. + */ + class IGNITE_IMPORT_EXPORT ThreadLocalEntry + { + public: + /** + * Virtual destructor to allow for correct typed entries cleanup. + */ + virtual ~ThreadLocalEntry() + { + // No-op. + } + }; + + /** + * Typed thread-local entry. + */ + template + class IGNITE_IMPORT_EXPORT ThreadLocalTypedEntry : public ThreadLocalEntry + { + public: + /** + * Constructor. + * + * @param val Value. + */ + ThreadLocalTypedEntry(T val) : val(val) + { + // No-op. + } + + ~ThreadLocalTypedEntry() + { + // No-op. + } + + /** + * Get value. + * + * @return Value. + */ + T Get() + { + return val; + } + private: + /** Value. */ + T val; + }; + + /** + * Thread-local abstraction. + */ + class IGNITE_IMPORT_EXPORT ThreadLocal + { + public: + /** + * Get next available index to be used in thread-local storage. + * + * @return Index. + */ + static int32_t NextIndex(); + + /** + * Get value by index. + * + * @param idx Index. + * @return Value associated with the index or NULL. + */ + template + static T Get(int32_t idx) + { + void* linuxVal = Get0(); + + if (linuxVal) + { + std::map* map = + static_cast*>(linuxVal); + + ThreadLocalTypedEntry* entry = static_cast*>((*map)[idx]); + + if (entry) + return entry->Get(); + } + + return T(); + } + + /** + * Set value at the given index. + * + * @param idx Index. + * @param val Value to be associated with the index. + */ + template + static void Set(int32_t idx, const T& val) + { + void* linuxVal = Get0(); + + if (linuxVal) + { + std::map* map = + static_cast*>(linuxVal); + + ThreadLocalEntry* appVal = (*map)[idx]; + + if (appVal) + delete appVal; + + (*map)[idx] = new ThreadLocalTypedEntry(val); + } + else + { + std::map* map = new std::map(); + + Set0(map); + + (*map)[idx] = new ThreadLocalTypedEntry(val); + } + } + + /** + * Remove value at the given index. + * + * @param idx Index. + */ + static void Remove(int32_t idx); + + /** + * Internal thread-local map clear routine. + * + * @param mapPtr Pointer to map. + */ + static void Clear0(void* mapPtr); + + private: + /** + * Internal get routine. + * + * @param Associated value. + */ + static void* Get0(); + + /** + * Internal set routine. + * + * @param ptr Pointer. + */ + static void Set0(void* ptr); + }; + + /** + * Thread-local instance. Simplifies API avoiding direct index allocations. + */ + template + class IGNITE_IMPORT_EXPORT ThreadLocalInstance + { + public: + /** + * Constructor. + */ + ThreadLocalInstance() : idx(ThreadLocal::NextIndex()) + { + // No-op. + } + + /** + * Destructor. + */ + ~ThreadLocalInstance() + { + Remove(); + } + + /** + * Get value. + * + * @return Value. + */ + T Get() + { + return ThreadLocal::Get(idx); + } + + /** + * Set instance. + * + * @param val Value. + */ + void Set(const T& val) + { + ThreadLocal::Set(idx, val); + } + + /** + * Remove instance. + */ + void Remove() + { + ThreadLocal::Remove(idx); + } + + private: + /** Index. */ + int32_t idx; + }; + + /** + * Cross-platform wrapper for Condition Variable synchronization + * primitive concept. + */ + class ConditionVariable + { + public: + /** + * Constructor. + */ + ConditionVariable() + { + pthread_condattr_t attr; + int err = pthread_condattr_init(&attr); + assert(!err); + IGNITE_UNUSED(err); + + #if !defined(__APPLE__) + err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + assert(!err); + IGNITE_UNUSED(err); + #endif + err = pthread_cond_init(&cond, &attr); + assert(!err); + IGNITE_UNUSED(err); + } + + /** + * Destructor. + */ + ~ConditionVariable() + { + pthread_cond_destroy(&cond); + } + + /** + * Wait for Condition Variable to be notified. + * + * @param cs Critical section in which to wait. + */ + void Wait(CriticalSection& cs) + { + pthread_cond_wait(&cond, &cs.mux); + } + + /** + * Wait for Condition Variable to be notified for specified time. + * + * @param cs Critical section in which to wait. + * @param msTimeout Timeout in milliseconds. + * @return True if the object has been notified and false in case of timeout. + */ + bool WaitFor(CriticalSection& cs, int32_t msTimeout) + { + timespec ts; + int err = clock_gettime(CLOCK_MONOTONIC, &ts); + assert(!err); + + IGNITE_UNUSED(err); + + ts.tv_sec += msTimeout / 1000 + (ts.tv_nsec + (msTimeout % 1000) * 1000000) / 1000000000; + ts.tv_nsec = (ts.tv_nsec + (msTimeout % 1000) * 1000000) % 1000000000; + + int res = pthread_cond_timedwait(&cond, &cs.mux, &ts); + + return res == 0; + } + + /** + * Notify single thread waiting for the condition variable. + */ + void NotifyOne() + { + int err = pthread_cond_signal(&cond); + + assert(!err); + + IGNITE_UNUSED(err); + } + + /** + * Notify all threads that are waiting on the variable. + */ + void NotifyAll() + { + int err = pthread_cond_broadcast(&cond); + + assert(!err); + + IGNITE_UNUSED(err); + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(ConditionVariable); + + /** OS-specific type. */ + pthread_cond_t cond; + }; + + /** + * Manually triggered event. + * Once triggered it stays in passing state until manually reset. + */ + class ManualEvent + { + public: + /** + * Constructs manual event. + * Initial state is untriggered. + */ + ManualEvent() : + cond(), + mutex(), + state(false) + { + pthread_condattr_t attr; + int err = pthread_condattr_init(&attr); + assert(!err); + IGNITE_UNUSED(err); + + #if !defined(__APPLE__) + err = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC); + assert(!err); + IGNITE_UNUSED(err); + #endif + + err = pthread_cond_init(&cond, &attr); + assert(!err); + IGNITE_UNUSED(err); + + err = pthread_mutex_init(&mutex, NULL); + assert(!err); + IGNITE_UNUSED(err); + } + + /** + * Destructor. + */ + ~ManualEvent() + { + pthread_mutex_destroy(&mutex); + pthread_cond_destroy(&cond); + } + + /** + * Sets event into triggered state. + */ + void Set() + { + int err = pthread_mutex_lock(&mutex); + assert(!err); + IGNITE_UNUSED(err); + + state = true; + + err = pthread_cond_broadcast(&cond); + assert(!err); + IGNITE_UNUSED(err); + + err = pthread_mutex_unlock(&mutex); + assert(!err); + IGNITE_UNUSED(err); + } + + /** + * Resets event into non-triggered state. + */ + void Reset() + { + int err = pthread_mutex_lock(&mutex); + assert(!err); + IGNITE_UNUSED(err); + + state = false; + + err = pthread_mutex_unlock(&mutex); + assert(!err); + IGNITE_UNUSED(err); + } + + /** + * Wait for event to be triggered. + */ + void Wait() + { + int err = pthread_mutex_lock(&mutex); + assert(!err); + IGNITE_UNUSED(err); + + while (!state) + { + err = pthread_cond_wait(&cond, &mutex); + assert(!err); + IGNITE_UNUSED(err); + } + + err = pthread_mutex_unlock(&mutex); + assert(!err); + IGNITE_UNUSED(err); + } + + /** + * Wait for event to be triggered for specified time. + * + * @param msTimeout Timeout in milliseconds. + * @return True if the object has been triggered and false in case of timeout. + */ + bool WaitFor(int32_t msTimeout) + { + int res = 0; + int err = pthread_mutex_lock(&mutex); + assert(!err); + IGNITE_UNUSED(err); + + if (!state) + { + timespec ts; + err = clock_gettime(CLOCK_MONOTONIC, &ts); + assert(!err); + IGNITE_UNUSED(err); + + ts.tv_sec += msTimeout / 1000 + (ts.tv_nsec + (msTimeout % 1000) * 1000000) / 1000000000; + ts.tv_nsec = (ts.tv_nsec + (msTimeout % 1000) * 1000000) % 1000000000; + + res = pthread_cond_timedwait(&cond, &mutex, &ts); + assert(res == 0 || res == ETIMEDOUT); + IGNITE_UNUSED(res); + } + + err = pthread_mutex_unlock(&mutex); + assert(!err); + IGNITE_UNUSED(err); + + return res == 0; + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(ManualEvent); + + /** Condition variable. */ + pthread_cond_t cond; + + /** Mutex. */ + pthread_mutex_t mutex; + + /** State. */ + bool state; + }; + } + } + } +} + +#endif // _IGNITE_ODBC_COMMON_CONCURRENT_OS diff --git a/src/odbc/os/linux/src/common/concurrent_os.cpp b/src/odbc/os/linux/src/common/concurrent_os.cpp new file mode 100644 index 000000000..aa04e55c9 --- /dev/null +++ b/src/odbc/os/linux/src/common/concurrent_os.cpp @@ -0,0 +1,211 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ignite/odbc/common/concurrent_os.h" + +namespace ignite +{ + namespace odbc + { + namespace common + { + namespace concurrent + { + /** Key indicating that the thread is attached. */ + static pthread_key_t tlsKey; + + /** Helper to ensure that attach key is allocated only once. */ + static pthread_once_t tlsKeyInit = PTHREAD_ONCE_INIT; + + /** + * Routine to destroy TLS key. + * + * @param key Key. + */ + void DestroyTlsKey(void* key) { + ThreadLocal::Clear0(key); + } + + /** + * Routine to allocate TLS key. + */ + void AllocateTlsKey() { + pthread_key_create(&tlsKey, DestroyTlsKey); + } + + void Memory::Fence() { + __asm__ volatile ("" ::: "memory"); + } + + CriticalSection::CriticalSection() { + pthread_mutex_init(&mux, NULL); + + Memory::Fence(); + } + + CriticalSection::~CriticalSection() { + Memory::Fence(); + + pthread_mutex_destroy(&mux); + } + + void CriticalSection::Enter() { + Memory::Fence(); + + pthread_mutex_lock(&mux); + } + + void CriticalSection::Leave() { + Memory::Fence(); + + pthread_mutex_unlock(&mux); + } + + ReadWriteLock::ReadWriteLock() : + lock() + { + pthread_rwlock_init(&lock, NULL); + + Memory::Fence(); + } + + ReadWriteLock::~ReadWriteLock() + { + pthread_rwlock_destroy(&lock); + } + + void ReadWriteLock::LockExclusive() + { + pthread_rwlock_wrlock(&lock); + } + + void ReadWriteLock::ReleaseExclusive() + { + pthread_rwlock_unlock(&lock); + } + + void ReadWriteLock::LockShared() + { + pthread_rwlock_rdlock(&lock); + } + + void ReadWriteLock::ReleaseShared() + { + pthread_rwlock_unlock(&lock); + } + + SingleLatch::SingleLatch() + { + pthread_mutex_init(&mux, NULL); + pthread_cond_init(&cond, NULL); + ready = false; + + Memory::Fence(); + } + + SingleLatch::~SingleLatch() + { + Memory::Fence(); + + pthread_cond_destroy(&cond); + pthread_mutex_destroy(&mux); + } + + void SingleLatch::CountDown() + { + pthread_mutex_lock(&mux); + + if (!ready) { + ready = true; + + pthread_cond_broadcast(&cond); + } + + pthread_mutex_unlock(&mux); + + Memory::Fence(); + } + + void SingleLatch::Await() + { + pthread_mutex_lock(&mux); + + while (!ready) + pthread_cond_wait(&cond, &mux); + + pthread_mutex_unlock(&mux); + + Memory::Fence(); + } + + bool Atomics::CompareAndSet32(int32_t* ptr, int32_t expVal, int32_t newVal) + { + return __sync_bool_compare_and_swap(ptr, expVal, newVal); + } + + int32_t Atomics::CompareAndSet32Val(int32_t* ptr, int32_t expVal, int32_t newVal) + { + return __sync_val_compare_and_swap(ptr, expVal, newVal); + } + + int32_t Atomics::IncrementAndGet32(int32_t* ptr) + { + return __sync_fetch_and_add(ptr, 1) + 1; + } + + int32_t Atomics::DecrementAndGet32(int32_t* ptr) + { + return __sync_fetch_and_sub(ptr, 1) - 1; + } + + bool Atomics::CompareAndSet64(int64_t* ptr, int64_t expVal, int64_t newVal) + { + return __sync_bool_compare_and_swap(ptr, expVal, newVal); + } + + int64_t Atomics::CompareAndSet64Val(int64_t* ptr, int64_t expVal, int64_t newVal) + { + return __sync_val_compare_and_swap(ptr, expVal, newVal); + } + + int64_t Atomics::IncrementAndGet64(int64_t* ptr) + { + return __sync_fetch_and_add(ptr, 1) + 1; + } + + int64_t Atomics::DecrementAndGet64(int64_t* ptr) + { + return __sync_fetch_and_sub(ptr, 1) - 1; + } + + void* ThreadLocal::Get0() + { + pthread_once(&tlsKeyInit, AllocateTlsKey); + + return pthread_getspecific(tlsKey); + } + + void ThreadLocal::Set0(void* ptr) + { + pthread_once(&tlsKeyInit, AllocateTlsKey); + + pthread_setspecific(tlsKey, ptr); + } + } + } + } +} diff --git a/src/odbc/os/linux/src/common/platform_utils.cpp b/src/odbc/os/linux/src/common/platform_utils.cpp new file mode 100644 index 000000000..f0076598f --- /dev/null +++ b/src/odbc/os/linux/src/common/platform_utils.cpp @@ -0,0 +1,143 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + time_t IgniteTimeGm(const tm& time) + { + tm tmc = time; + + return timegm(&tmc); + } + + time_t IgniteTimeLocal(const tm& time) + { + tm tmc = time; + + return mktime(&tmc); + } + + bool IgniteGmTime(time_t in, tm& out) + { + return gmtime_r(&in, &out) != NULL; + } + + bool IgniteLocalTime(time_t in, tm& out) + { + return localtime_r(&in, &out) == 0; + } + + std::string GetEnv(const std::string& name) + { + static const std::string empty; + + return GetEnv(name, empty); + } + + std::string GetEnv(const std::string& name, const std::string& dflt) + { + char* val0 = std::getenv(name.c_str()); + + if (!val0) + return dflt; + + return std::string(val0); + } + + bool FileExists(const std::string& path) + { + glob_t gs; + + int res = glob(path.c_str(), 0, 0, &gs); + + globfree(&gs); + + return res == 0; + } + + bool IsValidDirectory(const std::string& path) + { + if (path.empty()) + return false; + + struct stat pathStat; + + return stat(path.c_str(), &pathStat) != -1 && S_ISDIR(pathStat.st_mode); + } + + static int rmFiles(const char *pathname, const struct stat*, int, struct FTW*) + { + remove(pathname); + + return 0; + } + + bool DeletePath(const std::string& path) + { + return nftw(path.c_str(), rmFiles, 10, FTW_DEPTH | FTW_MOUNT | FTW_PHYS) == 0; + } + + StdCharOutStream& Fs(StdCharOutStream& ostr) + { + ostr.put('/'); + return ostr; + } + + StdCharOutStream& Dle(StdCharOutStream& ostr) + { + #ifdef __APPLE__ + static const char expansion[] = ".dylib"; + #else + static const char expansion[] = ".so"; + #endif + ostr.write(expansion, sizeof(expansion) - 1); + + return ostr; + } + + IGNITE_IMPORT_EXPORT unsigned GetRandSeed() + { + timespec ts; + + clock_gettime(CLOCK_MONOTONIC, &ts); + + unsigned res = static_cast(ts.tv_sec); + res ^= static_cast(ts.tv_nsec); + res ^= static_cast(getpid()); + + return res; + } + } + } +} diff --git a/src/odbc/os/win/include/ignite/odbc/common/common.h b/src/odbc/os/win/include/ignite/odbc/common/common.h new file mode 100644 index 000000000..e7cda4b52 --- /dev/null +++ b/src/odbc/os/win/include/ignite/odbc/common/common.h @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef _IGNITE_COMMON_COMMON +#define _IGNITE_COMMON_COMMON + +#define IGNITE_EXPORT __declspec(dllexport) +#define IGNITE_IMPORT __declspec(dllimport) +#define IGNITE_CALL __stdcall + +#define IGNITE_IMPORT_EXPORT IGNITE_EXPORT + +#include + +#define IGNITE_TRACE_ALLOC(addr) \ + std::cout << "ALLOC " << __FILE__ << "(" << __LINE__ << "): 0x" << (void*)addr << std::endl; + +/** + * Common construction to disable copy constructor and assignment for class. + */ +#define IGNITE_NO_COPY_ASSIGNMENT(cls) \ + cls(const cls& src); \ + cls& operator= (const cls& other); + +#if (__cplusplus >= 201103L) +# define IGNITE_NO_THROW noexcept +#else +# define IGNITE_NO_THROW throw() +#endif + +#define IGNITE_UNUSED(x) ((void) x) + +#endif //_IGNITE_COMMON_COMMON \ No newline at end of file diff --git a/src/odbc/os/win/include/ignite/odbc/common/concurrent_os.h b/src/odbc/os/win/include/ignite/odbc/common/concurrent_os.h new file mode 100644 index 000000000..855a995b6 --- /dev/null +++ b/src/odbc/os/win/include/ignite/odbc/common/concurrent_os.h @@ -0,0 +1,610 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _IGNITE_ODBC_COMMON_CONCURRENT_OS +#define _IGNITE_ODBC_COMMON_CONCURRENT_OS + +#include + +#include +#include + +#include + +#include "ignite/odbc/common/common.h" +namespace ignite +{ + namespace odbc + { + namespace common + { + namespace concurrent + { + /** + * Static class to manage memory visibility semantics. + */ + class IGNITE_IMPORT_EXPORT Memory + { + public: + /** + * Full fence. + */ + static void Fence(); + }; + + /** + * Critical section. + */ + class IGNITE_IMPORT_EXPORT CriticalSection + { + friend class ConditionVariable; + public: + /** + * Constructor. + */ + CriticalSection(); + + /** + * Destructor. + */ + ~CriticalSection(); + + /** + * Enter critical section. + */ + void Enter(); + + /** + * Leave critical section. + */ + void Leave(); + private: + /** Handle. */ + CRITICAL_SECTION hnd; + + IGNITE_NO_COPY_ASSIGNMENT(CriticalSection) + }; + + class IGNITE_IMPORT_EXPORT ReadWriteLock + { + public: + /** + * Constructor. + */ + ReadWriteLock(); + + /** + * Destructor. + */ + ~ReadWriteLock(); + + /** + * Lock in exclusive mode. + */ + void LockExclusive(); + + /** + * Release in exclusive mode. + */ + void ReleaseExclusive(); + + /** + * Lock in shared mode. + */ + void LockShared(); + + /** + * Release in shared mode. + */ + void ReleaseShared(); + + private: + /** Lock. */ + SRWLOCK lock; + + IGNITE_NO_COPY_ASSIGNMENT(ReadWriteLock) + }; + + /** + * Special latch with count = 1. + */ + class IGNITE_IMPORT_EXPORT SingleLatch + { + public: + /** + * Constructor. + */ + SingleLatch(); + + /** + * Destructor. + */ + ~SingleLatch(); + + /** + * Perform the countdown. + */ + void CountDown(); + + /** + * Await the countdown. + */ + void Await(); + private: + /** Handle. */ + HANDLE hnd = CreateEvent(nullptr, TRUE, FALSE, nullptr); + + IGNITE_NO_COPY_ASSIGNMENT(SingleLatch) + }; + + /** + * Primitives for atomic access. + */ + class IGNITE_IMPORT_EXPORT Atomics + { + public: + /** + * Update the 32-bit integer value if it is equal to expected value. + * + * @param ptr Pointer. + * @param expVal Expected value. + * @param newVal New value. + * @return True if update occurred as a result of this call, false otherwise. + */ + static bool CompareAndSet32(int32_t* ptr, int32_t expVal, int32_t newVal); + + /** + * Update the 32-bit integer value if it is equal to expected value. + * + * @param ptr Pointer. + * @param expVal Expected value. + * @param newVal New value. + * @return Value which were observed during CAS attempt. + */ + static int32_t CompareAndSet32Val(int32_t* ptr, int32_t expVal, int32_t newVal); + + /** + * Increment 32-bit integer and return new value. + * + * @param ptr Pointer. + * @return Value after increment. + */ + static int32_t IncrementAndGet32(int32_t* ptr); + + /** + * Decrement 32-bit integer and return new value. + * + * @param ptr Pointer. + * @return Value after decrement. + */ + static int32_t DecrementAndGet32(int32_t* ptr); + + /** + * Update the 64-bit integer value if it is equal to expected value. + * + * @param ptr Pointer. + * @param expVal Expected value. + * @param newVal New value. + * @return True if update occurred as a result of this call, false otherwise. + */ + static bool CompareAndSet64(int64_t* ptr, int64_t expVal, int64_t newVal); + + /** + * Update the 64-bit integer value if it is equal to expected value. + * + * @param ptr Pointer. + * @param expVal Expected value. + * @param newVal New value. + * @return Value which were observed during CAS attempt. + */ + static int64_t CompareAndSet64Val(int64_t* ptr, int64_t expVal, int64_t newVal); + + /** + * Increment 64-bit integer and return new value. + * + * @param ptr Pointer. + * @return Value after increment. + */ + static int64_t IncrementAndGet64(int64_t* ptr); + + /** + * Decrement 64-bit integer and return new value. + * + * @param ptr Pointer. + * @return Value after decrement. + */ + static int64_t DecrementAndGet64(int64_t* ptr); + }; + + /** + * Thread-local entry. + */ + class IGNITE_IMPORT_EXPORT ThreadLocalEntry + { + public: + /** + * Virtual destructor to allow for correct typed entries cleanup. + */ + virtual ~ThreadLocalEntry() + { + // No-op. + } + }; + + /** + * Typed thread-local entry. + */ + template + class IGNITE_IMPORT_EXPORT ThreadLocalTypedEntry : public ThreadLocalEntry + { + public: + /** + * Constructor. + * + * @param val Value. + */ + ThreadLocalTypedEntry(T val) : val(val) + { + // No-op. + } + + ~ThreadLocalTypedEntry() + { + // No-op. + } + + /** + * Get value. + * + * @return Value. + */ + T Get() + { + return val; + } + private: + /** Value. */ + T val; + }; + + /** + * Thread-local abstraction. + */ + class IGNITE_IMPORT_EXPORT ThreadLocal + { + public: + /** + * Allocate thread-local index. Invoked once on DLL process attach. + * + * @return True if allocation was successful. + */ + static bool OnProcessAttach(); + + /** + * Release thread-local entry. Invoked on DLL thread detach. + */ + static void OnThreadDetach(); + + /** + * Release thread-local index. Invoked once on DLL process detach. + */ + static void OnProcessDetach(); + + /** + * Get next available index to be used in thread-local storage. + * + * @return Index. + */ + static int32_t NextIndex(); + + /** + * Get value by index. + * + * @param idx Index. + * @return Value associated with the index or NULL. + */ + template + static T Get(int32_t idx) + { + void* winVal = Get0(); + + if (winVal) + { + std::map* map = + static_cast*>(winVal); + + ThreadLocalTypedEntry* entry = static_cast*>((*map)[idx]); + + if (entry) + return entry->Get(); + } + + return T(); + } + + /** + * Set value at the given index. + * + * @param idx Index. + * @param val Value to be associated with the index. + */ + template + static void Set(int32_t idx, const T& val) + { + void* winVal = Get0(); + + if (winVal) + { + std::map* map = + static_cast*>(winVal); + + ThreadLocalEntry* appVal = (*map)[idx]; + + if (appVal) + delete appVal; + + (*map)[idx] = new ThreadLocalTypedEntry(val); + } + else + { + std::map* map = new std::map(); + + Set0(map); + + (*map)[idx] = new ThreadLocalTypedEntry(val); + } + } + + /** + * Remove value at the given index. + * + * @param idx Index. + */ + static void Remove(int32_t idx); + + private: + /** + * Internal get routine. + * + * @param Associated value. + */ + static void* Get0(); + + /** + * Internal set routine. + * + * @param ptr Pointer. + */ + static void Set0(void* ptr); + + /** + * Internal thread-local map clear routine. + * + * @param mapPtr Pointer to map. + */ + static void Clear0(void* mapPtr); + }; + + /** + * Thread-local instance. Simplifies API avoiding direct index allocations. + */ + template + class IGNITE_IMPORT_EXPORT ThreadLocalInstance + { + public: + /** + * Constructor. + */ + ThreadLocalInstance() : idx(ThreadLocal::NextIndex()) + { + // No-op. + } + + /** + * Destructor. + */ + ~ThreadLocalInstance() + { + Remove(); + } + + /** + * Get value. + * + * @return Value. + */ + T Get() + { + return ThreadLocal::Get(idx); + } + + /** + * Set instance. + * + * @param val Value. + */ + void Set(const T& val) + { + ThreadLocal::Set(idx, val); + } + + /** + * Remove instance. + */ + void Remove() + { + ThreadLocal::Remove(idx); + } + + private: + /** Index. */ + int32_t idx; + }; + + /** + * Cross-platform wrapper for Condition Variable synchronization + * primitive concept. + */ + class ConditionVariable + { + public: + /** + * Constructor. + */ + ConditionVariable() + { + InitializeConditionVariable(&cond); + } + + /** + * Destructor. + */ + ~ConditionVariable() + { + // No-op. + } + + /** + * Wait for Condition Variable to be notified. + * + * @param cs Critical section in which to wait. + */ + void Wait(CriticalSection& cs) + { + SleepConditionVariableCS(&cond, &cs.hnd, INFINITE); + } + + /** + * Wait for Condition Variable to be notified for specified time. + * + * @param cs Critical section in which to wait. + * @param msTimeout Timeout in milliseconds. + * @return True if the object has been notified and false in case of timeout. + */ + bool WaitFor(CriticalSection& cs, int32_t msTimeout) + { + BOOL notified = SleepConditionVariableCS(&cond, &cs.hnd, msTimeout); + + return notified != FALSE; + } + + /** + * Notify single thread waiting for the condition variable. + */ + void NotifyOne() + { + WakeConditionVariable(&cond); + } + + /** + * Notify all threads that are waiting on the variable. + */ + void NotifyAll() + { + WakeAllConditionVariable(&cond); + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(ConditionVariable); + + /** OS-specific type. */ + CONDITION_VARIABLE cond; + }; + + /** + * Manually triggered event. + * Once triggered it stays in passing state until manually reset. + */ + class ManualEvent + { + public: + /** + * Constructs manual event. + * Initial state is untriggered. + */ + ManualEvent() + { + handle = CreateEvent(NULL, TRUE, FALSE, NULL); + + assert(handle != NULL); + } + + /** + * Destructor. + */ + ~ManualEvent() + { + CloseHandle(handle); + } + + /** + * Sets event into triggered state. + */ + void Set() + { + BOOL success = SetEvent(handle); + + assert(success); + } + + /** + * Resets event into non-triggered state. + */ + void Reset() + { + BOOL success = ResetEvent(handle); + + assert(success); + } + + /** + * Wait for event to be triggered. + */ + void Wait() + { + DWORD res = WaitForSingleObject(handle, INFINITE); + + assert(res == WAIT_OBJECT_0); + } + + /** + * Wait for event to be triggered for specified time. + * + * @param msTimeout Timeout in milliseconds. + * @return True if the object has been triggered and false in case of timeout. + */ + bool WaitFor(int32_t msTimeout) + { + DWORD res = WaitForSingleObject(handle, static_cast(msTimeout)); + + assert(res == WAIT_OBJECT_0 || res == WAIT_TIMEOUT); + + return res == WAIT_OBJECT_0; + } + + private: + IGNITE_NO_COPY_ASSIGNMENT(ManualEvent); + + /** Event handle. */ + HANDLE handle; + }; + } + } + } +} + +#endif //_IGNITE_ODBC_COMMON_CONCURRENT_OS diff --git a/src/odbc/os/win/src/common/concurrent_os.cpp b/src/odbc/os/win/src/common/concurrent_os.cpp new file mode 100644 index 000000000..71f5587db --- /dev/null +++ b/src/odbc/os/win/src/common/concurrent_os.cpp @@ -0,0 +1,208 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ignite/odbc/common/concurrent_os.h" + +#pragma intrinsic(_InterlockedCompareExchange64) + +namespace ignite +{ + namespace odbc + { + namespace common + { + namespace concurrent + { + /** Thread-local index for Windows. */ + DWORD winTlsIdx; + + void Memory::Fence() { + MemoryBarrier(); + } + + CriticalSection::CriticalSection() : + hnd() + { + InitializeCriticalSection(&hnd); + + Memory::Fence(); + } + + CriticalSection::~CriticalSection() = default; + + void CriticalSection::Enter() + { + Memory::Fence(); + + EnterCriticalSection(&hnd); + } + + void CriticalSection::Leave() + { + Memory::Fence(); + + LeaveCriticalSection(&hnd); + } + + ReadWriteLock::ReadWriteLock() : + lock() + { + InitializeSRWLock(&lock); + + Memory::Fence(); + } + + ReadWriteLock::~ReadWriteLock() = default; + + void ReadWriteLock::LockExclusive() + { + AcquireSRWLockExclusive(&lock); + } + + void ReadWriteLock::ReleaseExclusive() + { + ReleaseSRWLockExclusive(&lock); + } + + void ReadWriteLock::LockShared() + { + AcquireSRWLockShared(&lock); + } + + void ReadWriteLock::ReleaseShared() + { + ReleaseSRWLockShared(&lock); + } + + SingleLatch::SingleLatch() + { + Memory::Fence(); + } + + SingleLatch::~SingleLatch() + { + Memory::Fence(); + + CloseHandle(hnd); + } + + void SingleLatch::CountDown() + { + SetEvent(hnd); + } + + void SingleLatch::Await() + { + WaitForSingleObject(hnd, INFINITE); + } + + bool Atomics::CompareAndSet32(int32_t* ptr, int32_t expVal, int32_t newVal) + { + return CompareAndSet32Val(ptr, expVal, newVal) == expVal; + } + + int32_t Atomics::CompareAndSet32Val(int32_t* ptr, int32_t expVal, int32_t newVal) + { + return InterlockedCompareExchange(reinterpret_cast(ptr), newVal, expVal); + } + + int32_t Atomics::IncrementAndGet32(int32_t* ptr) + { + return InterlockedIncrement(reinterpret_cast(ptr)); + } + + int32_t Atomics::DecrementAndGet32(int32_t* ptr) + { + return InterlockedDecrement(reinterpret_cast(ptr)); + } + + bool Atomics::CompareAndSet64(int64_t* ptr, int64_t expVal, int64_t newVal) + { + return CompareAndSet64Val(ptr, expVal, newVal) == expVal; + } + + int64_t Atomics::CompareAndSet64Val(int64_t* ptr, int64_t expVal, int64_t newVal) + { + return _InterlockedCompareExchange64(ptr, newVal, expVal); + } + + int64_t Atomics::IncrementAndGet64(int64_t* ptr) + { + #ifdef _WIN64 + return InterlockedIncrement64(ptr); + #else + while (true) + { + int64_t expVal = *ptr; + int64_t newVal = expVal + 1; + + if (CompareAndSet64(ptr, expVal, newVal)) + return newVal; + } + #endif + } + + int64_t Atomics::DecrementAndGet64(int64_t* ptr) + { + #ifdef _WIN64 + return InterlockedDecrement64(ptr); + #else + while (true) + { + int64_t expVal = *ptr; + int64_t newVal = expVal - 1; + + if (CompareAndSet64(ptr, expVal, newVal)) + return newVal; + } + #endif + } + + bool ThreadLocal::OnProcessAttach() + { + return (winTlsIdx = TlsAlloc()) != TLS_OUT_OF_INDEXES; + } + + void ThreadLocal::OnThreadDetach() + { + if (winTlsIdx != TLS_OUT_OF_INDEXES) + { + void* mapPtr = Get0(); + + Clear0(mapPtr); + } + } + + void ThreadLocal::OnProcessDetach() + { + if (winTlsIdx != TLS_OUT_OF_INDEXES) + TlsFree(winTlsIdx); + } + + void* ThreadLocal::Get0() + { + return TlsGetValue(winTlsIdx); + } + + void ThreadLocal::Set0(void* ptr) + { + TlsSetValue(winTlsIdx, ptr); + } + } + } + } +} diff --git a/src/odbc/os/win/src/common/platform_utils.cpp b/src/odbc/os/win/src/common/platform_utils.cpp new file mode 100644 index 000000000..35261fa0d --- /dev/null +++ b/src/odbc/os/win/src/common/platform_utils.cpp @@ -0,0 +1,140 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +#include + +namespace ignite { + namespace odbc + { + namespace common + { + time_t IgniteTimeGm(const tm& time) + { + tm tmc = time; + + return _mkgmtime(&tmc); + } + + time_t IgniteTimeLocal(const tm& time) + { + tm tmc = time; + + return mktime(&tmc); + } + + bool IgniteGmTime(time_t in, tm& out) + { + return gmtime_s(&out, &in) == 0; + } + + bool IgniteLocalTime(time_t in, tm& out) + { + return localtime_s(&out, &in) == 0; + } + + std::string GetEnv(const std::string& name) + { + static const std::string empty; + + return GetEnv(name, empty); + } + + std::string GetEnv(const std::string& name, const std::string& dflt) + { + char res[32767]; + + DWORD envRes = GetEnvironmentVariableA(name.c_str(), res, sizeof(res) / sizeof(res[0])); + + if (envRes == 0 || envRes > sizeof(res)) + return dflt; + + return std::string(res, static_cast(envRes)); + } + + bool FileExists(const std::string& path) + { + WIN32_FIND_DATAA findres; + + HANDLE hnd = FindFirstFileA(path.c_str(), &findres); + + if (hnd == INVALID_HANDLE_VALUE) + return false; + + FindClose(hnd); + + return true; + } + + bool IsValidDirectory(const std::string& path) + { + if (path.empty()) + return false; + + DWORD attrs = GetFileAttributesA(path.c_str()); + + return attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0; + } + + bool DeletePath(const std::string& path) + { + std::vector path0(path.begin(), path.end()); + path0.push_back('\0'); + path0.push_back('\0'); + + SHFILEOPSTRUCT fileop; + fileop.hwnd = nullptr; + fileop.wFunc = FO_DELETE; + fileop.pFrom = &path0[0]; + fileop.pTo = nullptr; + fileop.fFlags = FOF_NOCONFIRMATION | FOF_SILENT; + + fileop.fAnyOperationsAborted = FALSE; + fileop.lpszProgressTitle = nullptr; + fileop.hNameMappings = nullptr; + + int ret = SHFileOperation(&fileop); + + return ret == 0; + } + + StdCharOutStream& Fs(StdCharOutStream& ostr) + { + ostr.put('\\'); + return ostr; + } + + StdCharOutStream& Dle(StdCharOutStream& ostr) + { + static const char expansion[] = ".dll"; + + ostr.write(expansion, sizeof(expansion) - 1); + + return ostr; + } + + IGNITE_IMPORT_EXPORT unsigned GetRandSeed() + { + return static_cast(GetTickCount64() ^ GetCurrentProcessId()); + } + } + } +} diff --git a/src/odbc/os/win/src/system/ui/window.cpp b/src/odbc/os/win/src/system/ui/window.cpp index 02d62e2d8..8512bda8a 100644 --- a/src/odbc/os/win/src/system/ui/window.cpp +++ b/src/odbc/os/win/src/system/ui/window.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -#include +#include #include "ignite/odbc/system/ui/window.h" @@ -58,7 +58,7 @@ namespace ignite title(), handle(handle), created(false), - parent(0) + parent(nullptr) { // No-op. } @@ -88,7 +88,7 @@ namespace ignite posY, width, height, - parent ? parent->GetHandle() : NULL, + parent ? parent->GetHandle() : nullptr, reinterpret_cast(static_cast(id)), GetHInstance(), this @@ -125,7 +125,7 @@ namespace ignite if (handle) DestroyWindow(handle); - handle = NULL; + handle = nullptr; } void Window::GetText(std::string& text) const diff --git a/src/odbc/src/app/application_data_buffer.cpp b/src/odbc/src/app/application_data_buffer.cpp index 2942defc8..f4977bb09 100644 --- a/src/odbc/src/app/application_data_buffer.cpp +++ b/src/odbc/src/app/application_data_buffer.cpp @@ -19,7 +19,7 @@ #include #include -#include "ignite/common/bits.h" +#include "ignite/odbc/common/bits.h" #include "ignite/impl/binary/binary_utils.h" diff --git a/src/odbc/src/common/big_integer.cpp b/src/odbc/src/common/big_integer.cpp new file mode 100644 index 000000000..3114a452f --- /dev/null +++ b/src/odbc/src/common/big_integer.cpp @@ -0,0 +1,866 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ignite/odbc/ignite_error.h" +#include "ignite/odbc/common/bits.h" +#include "ignite/odbc/common/big_integer.h" + +namespace ignite +{ + namespace odbc + { + namespace common + { + BigInteger::BigInteger() : + sign(1), + mag() + { + // No-op. + } + + BigInteger::BigInteger(int64_t val) : + sign(1), + mag() + { + AssignInt64(val); + } + + BigInteger::BigInteger(const char* val, int32_t len) : + sign(1), + mag() + { + AssignString(val, len); + } + + BigInteger::BigInteger(const BigInteger& other) : + sign(other.sign), + mag(other.mag) + { + // No-op. + } + + BigInteger::BigInteger(const int8_t* val, int32_t len, int32_t sign, bool bigEndian) : + sign(sign), + mag() + { + assert(val != 0); + assert(len >= 0); + assert(sign == 1 || sign == 0 || sign == -1); + + if (bigEndian) + { + int32_t firstNonZero = 0; + while (firstNonZero < len && val[firstNonZero] == 0) + ++firstNonZero; + + if (firstNonZero == len) + { + AssignInt64(0); + + return; + } + + int32_t intLength = (len - firstNonZero + 3) / 4; + + mag.Resize(intLength); + + int32_t b = len - 1; + + for (int32_t i = 0; i < intLength - 1; ++i) + { + mag[i] = (val[b] & 0xFFUL) + | ((val[b - 1] & 0xFFUL) << 8) + | ((val[b - 2] & 0xFFUL) << 16) + | ((val[b - 3] & 0xFFUL) << 24); + + b -= 4; + } + + int32_t bytesRemaining = b - firstNonZero + 1; + + assert(bytesRemaining > 0 && bytesRemaining <= 4); + + switch (bytesRemaining) + { + case 4: + mag[intLength - 1] |= (val[b - 3] & 0xFF) << 24; + // Fall-through. + + case 3: + mag[intLength - 1] |= (val[b - 2] & 0xFF) << 16; + // Fall-through. + + case 2: + mag[intLength - 1] |= (val[b - 1] & 0xFF) << 8; + // Fall-through. + + case 1: + mag[intLength - 1] |= val[b] & 0xFF; + // Fall-through. + + default: + break; + } + } + else + { + int32_t firstNonZero = len - 1; + + while (firstNonZero >= 0 && val[firstNonZero] == 0) + --firstNonZero; + + if (firstNonZero == -1) + { + AssignInt64(0); + + return; + } + + int32_t intLength = (firstNonZero + 4) / 4; + + mag.Resize(intLength); + + int32_t b = 0; + + for (int32_t i = 0; i < intLength - 1; ++i) + { + mag[i] = (val[b] & 0xFFUL) + | ((val[b + 1] & 0xFFUL) << 8) + | ((val[b + 2] & 0xFFUL) << 16) + | ((val[b + 3] & 0xFFUL) << 24); + + b += 4; + } + + int32_t bytesRemaining = firstNonZero - b + 1; + + assert(bytesRemaining > 0 && bytesRemaining <= 4); + + switch (bytesRemaining) + { + case 4: + mag[intLength - 1] |= (val[b + 3] & 0xFF) << 24; + // Fall-through. + + case 3: + mag[intLength - 1] |= (val[b + 2] & 0xFF) << 16; + // Fall-through. + + case 2: + mag[intLength - 1] |= (val[b + 1] & 0xFF) << 8; + // Fall-through. + + case 1: + mag[intLength - 1] |= val[b] & 0xFF; + // Fall-through. + + default: + break; + } + } + } + + BigInteger::BigInteger(MagArray &mag, int8_t sign) : + sign(sign), + mag() + { + this->mag.Swap(mag); + } + + BigInteger& BigInteger::operator=(const BigInteger& other) + { + Assign(other); + + return *this; + } + + void BigInteger::Assign(const BigInteger& val) + { + if (this != &val) + { + sign = val.sign; + mag = val.mag; + } + } + + void BigInteger::AssignInt64(int64_t val) + { + if (val < 0) + { + AssignUint64(static_cast(-val)); + + sign = -1; + } + else + AssignUint64(static_cast(val)); + } + + void BigInteger::AssignString(const char* val, int32_t len) + { + std::stringstream converter; + + converter.write(val, len); + + converter >> *this; + } + + void BigInteger::AssignUint64(uint64_t val) + { + sign = 1; + + if (val == 0) + { + mag.Clear(); + + return; + } + + uint32_t highWord = static_cast(val >> 32); + + if (highWord == 0) + mag.Resize(1); + else + { + mag.Resize(2); + mag[1] = highWord; + } + + mag[0] = static_cast(val); + } + + int8_t BigInteger::GetSign() const + { + return sign; + } + + void BigInteger::Swap(BigInteger& other) + { + using std::swap; + + swap(sign, other.sign); + mag.Swap(other.mag); + } + + const BigInteger::MagArray& BigInteger::GetMagnitude() const + { + return mag; + } + + uint32_t BigInteger::GetBitLength() const + { + if (mag.IsEmpty()) + return 0; + + int32_t res = bits::BitLengthU32(mag[mag.GetSize() - 1]); + + if (mag.GetSize() > 1) + res += (mag.GetSize() - 1) * 32; + + return res; + } + + int32_t BigInteger::GetPrecision() const + { + // See http://graphics.stanford.edu/~seander/bithacks.html + // for the details on the algorithm. + + if (mag.GetSize() == 0) + return 1; + + int32_t r = static_cast((( + static_cast(GetBitLength()) + 1) * 646456993) >> 31); + + BigInteger prec; + BigInteger::GetPowerOfTen(r, prec); + + return Compare(prec, true) < 0 ? r : r + 1; + } + + void BigInteger::MagnitudeToBytes(common::FixedSizeArray& buffer) const + { + int32_t bytesNum = static_cast((GetBitLength() + 7) / 8); + + if (bytesNum == 0) + { + buffer.Reset(1); + + return; + } + + buffer.Reset(bytesNum); + + int32_t i; + for (i = 0; i < mag.GetSize() - 1; ++i) + { + int32_t j = bytesNum - 1 - 4 * i; + + buffer[j] = static_cast(mag[i]); + buffer[j - 1] = static_cast(mag[i] >> 8); + buffer[j - 2] = static_cast(mag[i] >> 16); + buffer[j - 3] = static_cast(mag[i] >> 24); + } + + int32_t bytesRemaining = bytesNum - 4 * i; + + assert(bytesRemaining >= 0 && bytesRemaining <= 4); + + i = 0; + switch (bytesRemaining) + { + case 4: + buffer[i++] |= static_cast(mag[mag.GetSize() - 1] >> 24); + // Fall-through. + + case 3: + buffer[i++] |= static_cast(mag[mag.GetSize() - 1] >> 16); + // Fall-through. + + case 2: + buffer[i++] |= static_cast(mag[mag.GetSize() - 1] >> 8); + // Fall-through. + + case 1: + buffer[i++] |= static_cast(mag[mag.GetSize() - 1]); + // Fall-through. + + default: + break; + } + } + + void BigInteger::Pow(int32_t exp) + { + if (exp < 0) + { + AssignInt64(0); + + return; + } + + uint32_t bitsLen = GetBitLength(); + + if (!bitsLen) + return; + + if (bitsLen == 1) + { + if ((exp % 2 == 0) && sign < 0) + sign = -sign; + + return; + } + + BigInteger multiplicant(*this); + AssignInt64(1); + + int32_t mutExp = exp; + while (mutExp) + { + if (mutExp & 1) + Multiply(multiplicant, *this); + + mutExp >>= 1; + + if (mutExp) + multiplicant.Multiply(multiplicant, multiplicant); + } + } + + void BigInteger::Multiply(const BigInteger& other, BigInteger& res) const + { + MagArray resMag(mag.GetSize() + other.mag.GetSize()); + + resMag.Resize(mag.GetSize() + other.mag.GetSize()); + + for (int32_t i = 0; i < other.mag.GetSize(); ++i) + { + uint32_t carry = 0; + + for (int32_t j = 0; j < mag.GetSize(); ++j) + { + uint64_t product = static_cast(mag[j]) * other.mag[i] + + + resMag[i + j] + carry; + + resMag[i + j] = static_cast(product); + carry = static_cast(product >> 32); + } + + resMag[i + mag.GetSize()] = carry; + } + + res.mag.Swap(resMag); + res.sign = sign * other.sign; + + res.Normalize(); + } + + /** + * Shift magnitude left by the specified number of bits. + * + * @param in Input magnitude. + * @param len Magnitude length. + * @param out Output magnitude. Should be not shorter than the input + * magnitude. + * @param n Number of bits to shift to. + */ + void ShiftLeft(const uint32_t* in, int32_t len, uint32_t* out, unsigned n) + { + assert(n < 32); + + if (n == 0) + { + std::copy(in, in + len, out); + + return; + } + + for (int32_t i = len - 1; i > 0; --i) + out[i] = (in[i] << n) | (in[i - 1] >> (32 - n)); + + out[0] = in[0] << n; + } + + /** + * Shift magnitude right by the specified number of bits. + * + * @param in Input magnitude. + * @param len Magnitude length. + * @param out Output magnitude. Should be not shorter than the input + * magnitude. + * @param n Number of bits to shift to. + */ + void ShiftRight(const uint32_t* in, int32_t len, uint32_t* out, unsigned n) + { + assert(n < 32); + + if (n == 0) + { + std::copy(in, in + len, out); + + return; + } + + for (int32_t i = 0; i < len - 1; ++i) + out[i] = (in[i] >> n) | (in[i + 1] << (32 - n)); + + out[len - 1] = in[len - 1] >> n; + } + + /** + * Part of the division algorithm. Computes q - (a * x). + * + * @param q Minuend. + * @param a Multipliplier of the subtrahend. + * @param alen Length of the a. + * @param x Multipliplicand of the subtrahend. + * @return Carry. + */ + uint32_t MultiplyAndSubstruct(uint32_t* q, const uint32_t* a, int32_t alen, uint32_t x) + { + uint64_t carry = 0; + + for (int32_t i = 0; i < alen; ++i) + { + uint64_t product = a[i] * static_cast(x); + int64_t difference = q[i] - carry - (product & 0xFFFFFFFF); + + q[i] = static_cast(difference); + + // This will add one if difference is negative. + carry = (product >> 32) - (difference >> 32); + } + + return static_cast(carry); + } + + /** + * Add two magnitude arrays and return carry. + * + * @param res First addend. Result is placed here. Length of this addend + * should be equal or greater than len. + * @param addend Second addend. + * @param len Length of the second addend. + * @return Carry. + */ + uint32_t Add(uint32_t* res, const uint32_t* addend, int32_t len) + { + uint64_t carry = 0; + + for (int32_t i = 0; i < len; ++i) + { + uint64_t sum = static_cast(res[i]) + addend[i] + carry; + res[i] = static_cast(sum); + carry = sum >> 32; + } + + return static_cast(carry); + } + + /** + * Add single number to a magnitude array and return carry. + * + * @param res First addend. Result is placed here. Length of this addend + * should be equal or greater than len. + * @param len Length of the First addend. + * @param addend Second addend. + * @return Carry. + */ + uint32_t Add(uint32_t* res, int32_t len, uint32_t addend) + { + uint64_t carry = addend; + + for (int32_t i = 0; (i < len) && carry; ++i) + { + uint64_t sum = static_cast(res[i]) + carry; + res[i] = static_cast(sum); + carry = sum >> 32; + } + + return static_cast(carry); + } + + void BigInteger::Divide(const BigInteger& divisor, BigInteger& res) const + { + Divide(divisor, res, 0); + } + + void BigInteger::Divide(const BigInteger& divisor, BigInteger& res, BigInteger& rem) const + { + Divide(divisor, res, &rem); + } + + void BigInteger::Add(const uint32_t* addend, int32_t len) + { + if (mag.GetSize() < len) + { + mag.Reserve(len + 1); + + mag.Resize(len); + } + else + mag.Reserve(mag.GetSize() + 1); + + uint32_t carry = common::Add(mag.GetData(), addend, len); + + if (carry) + { + carry = common::Add(mag.GetData() + len, mag.GetSize() - len, carry); + + if (carry) + mag.PushBack(carry); + } + } + + void BigInteger::Add(uint64_t x) + { + if (x == 0) + return; + + if (IsZero()) + { + AssignUint64(x); + + return; + } + + uint32_t val[2]; + + val[0] = static_cast(x); + val[1] = static_cast(x >> 32); + + Add(val, val[1] ? 2 : 1); + } + + int32_t BigInteger::Compare(const BigInteger& other, bool ignoreSign) const + { + // What we should return if magnitude is greater. + int32_t mgt = 1; + + if (!ignoreSign) + { + if (sign != other.sign) + return sign > other.sign ? 1 : -1; + else + mgt = sign; + } + + if (mag.GetSize() != other.mag.GetSize()) + return mag.GetSize() > other.mag.GetSize() ? mgt : -mgt; + + for (int32_t i = mag.GetSize() - 1; i >= 0; --i) + { + if (mag[i] == other.mag[i]) + continue; + else if (mag[i] > other.mag[i]) + return mgt; + else + return -mgt; + } + + return 0; + } + + int64_t BigInteger::ToInt64() const + { + return (static_cast(GetMagInt(1)) << 32) | GetMagInt(0); + } + + void BigInteger::GetPowerOfTen(int32_t pow, BigInteger& res) + { + using namespace common; + + assert(pow >= 0); + + if (pow < bits::UINT64_MAX_PRECISION) + { + res.AssignUint64(bits::TenPowerU64(pow)); + + return; + } + + res.AssignInt64(10); + res.Pow(pow); + } + + uint32_t BigInteger::GetMagInt(int32_t n) const + { + assert(n >= 0); + + if (n >= mag.GetSize()) + return sign > 0 ? 0 : -1; + + return sign * mag[n]; + } + + void BigInteger::Divide(const BigInteger& divisor, BigInteger& res, BigInteger* rem) const + { + // Can't divide by zero. + if (divisor.mag.IsEmpty()) + throw IgniteError(IgniteError::IGNITE_ERR_ILLEGAL_ARGUMENT, "Division by zero."); + + int32_t compRes = Compare(divisor, true); + + int8_t resSign = sign * divisor.sign; + + // The same magnitude. Result is [-]1 and remainder is zero. + if (compRes == 0) + { + res.AssignInt64(resSign); + + if (rem) + rem->AssignInt64(0); + + return; + } + + // Divisor is greater than this. Result is 0 and remainder is this. + if (compRes == -1) + { + // Order is important here! Copy to rem first to handle the case + // when &res == this. + if (rem) + rem->Assign(*this); + + res.AssignInt64(0); + + return; + } + + // If divisor is [-]1 result is [-]this and remainder is zero. + if (divisor.GetBitLength() == 1) + { + // Once again: order is important. + res.Assign(*this); + res.sign = sign * divisor.sign; + + if (rem) + rem->AssignInt64(0); + + return; + } + + // Trivial case. + if (mag.GetSize() <= 2) + { + uint64_t u = mag[0]; + uint64_t v = divisor.mag[0]; + + if (mag.GetSize() == 2) + u |= static_cast(mag[1]) << 32; + + if (divisor.mag.GetSize() == 2) + v |= static_cast(divisor.mag[1]) << 32; + + // Divisor can not be 1, or 0. + assert(v > 1); + + // It should also be less than dividend. + assert(v < u); + + // (u / v) is always fits into int64_t because abs(v) >= 2. + res.AssignInt64(resSign * static_cast(u / v)); + + // (u % v) is always fits into int64_t because (u > v) -> + // (u % v) < (u / 2). + if (rem) + rem->AssignInt64(resSign * static_cast(u % v)); + + return; + } + + // Using Knuth division algorithm D for common case. + + // Short aliases. + const MagArray& u = mag; + const MagArray& v = divisor.mag; + MagArray& q = res.mag; + int32_t ulen = u.GetSize(); + int32_t vlen = v.GetSize(); + + // First we need to normilize divisor. + MagArray nv; + nv.Resize(v.GetSize()); + + int32_t shift = bits::NumberOfLeadingZerosU32(v.Back()); + ShiftLeft(v.GetData(), vlen, nv.GetData(), shift); + + // Divisor is normilized. Now we need to normilize divident. + MagArray nu; + + // First find out what is the size of it. + if (bits::NumberOfLeadingZerosU32(u.Back()) >= shift) + { + // Everything is the same as with divisor. Just add leading zero. + nu.Resize(ulen + 1); + + ShiftLeft(u.GetData(), ulen, nu.GetData(), shift); + + assert((static_cast(u.Back()) >> (32 - shift)) == 0); + } + else + { + // We need one more byte here. Also adding leading zero. + nu.Resize(ulen + 2); + + ShiftLeft(u.GetData(), ulen, nu.GetData(), shift); + + nu[ulen] = u[ulen - 1] >> (32 - shift); + + assert(nu[ulen] != 0); + } + + assert(nu.Back() == 0); + + // Resizing resulting array. + q.Resize(ulen - vlen + 1); + + // Main loop + for (int32_t i = ulen - vlen; i >= 0; --i) + { + uint64_t base = bits::MakeU64(nu[i + vlen], nu[i + vlen - 1]); + + uint64_t qhat = base / nv[vlen - 1]; // Estimated quotient. + uint64_t rhat = base % nv[vlen - 1]; // A remainder. + + // Adjusting result if needed. + while (qhat > UINT32_MAX || + ((qhat * nv[vlen - 2]) > ((UINT32_MAX + static_cast(1)) * rhat + nu[i + vlen - 2]))) + { + --qhat; + rhat += nv[vlen - 1]; + + if (rhat > UINT32_MAX) + break; + } + + uint32_t qhat32 = static_cast(qhat); + + // Multiply and subtract. + uint32_t carry = MultiplyAndSubstruct(nu.GetData() + i, nv.GetData(), vlen, qhat32); + + int64_t difference = nu[i + vlen] - carry; + + nu[i + vlen] = static_cast(difference); + + if (difference < 0) + { + --qhat32; + carry = common::Add(nu.GetData() + i, nv.GetData(), vlen); + + assert(carry == 0); + } + + q[i] = qhat32; + } + + res.sign = resSign; + res.Normalize(); + + // If remainder is needed unnormolize it. + if (rem) + { + rem->sign = resSign; + rem->mag.Resize(vlen); + + ShiftRight(nu.GetData(), rem->mag.GetSize(), rem->mag.GetData(), shift); + + rem->Normalize(); + } + } + + void BigInteger::Normalize() + { + int32_t lastNonZero = mag.GetSize() - 1; + while (lastNonZero >= 0 && mag[lastNonZero] == 0) + --lastNonZero; + + mag.Resize(lastNonZero + 1); + } + + bool operator==(const BigInteger& val1, const BigInteger& val2) + { + return val1.Compare(val2) == 0; + } + + bool operator!=(const BigInteger& val1, const BigInteger& val2) + { + return val1.Compare(val2) != 0; + } + + bool operator<(const BigInteger& val1, const BigInteger& val2) + { + return val1.Compare(val2) < 0; + } + + bool operator<=(const BigInteger& val1, const BigInteger& val2) + { + return val1.Compare(val2) <= 0; + } + + bool operator>(const BigInteger& val1, const BigInteger& val2) + { + return val1.Compare(val2) > 0; + } + + bool operator>=(const BigInteger& val1, const BigInteger& val2) + { + return val1.Compare(val2) >= 0; + } + } + } +} + diff --git a/src/odbc/src/common/bits.cpp b/src/odbc/src/common/bits.cpp new file mode 100644 index 000000000..a5c922a8b --- /dev/null +++ b/src/odbc/src/common/bits.cpp @@ -0,0 +1,236 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "ignite/odbc/common/bits.h" + +namespace ignite +{ + namespace odbc + { + namespace common + { + namespace bits + { + int32_t NumberOfTrailingZerosI32(int32_t i) + { + int32_t y; + + if (i == 0) return 32; + + int32_t n = 31; + + y = i << 16; + + if (y != 0) { + n = n - 16; + i = y; + } + + y = i << 8; + + if (y != 0) { + n = n - 8; + i = y; + } + + y = i << 4; + + if (y != 0) { + n = n - 4; + i = y; + } + + y = i << 2; + + if (y != 0) { + n = n - 2; + i = y; + } + + return n - static_cast(static_cast(i << 1) >> 31); + } + + int32_t NumberOfLeadingZerosI32(int32_t i) + { + return NumberOfLeadingZerosU32(static_cast(i)); + } + + int32_t NumberOfLeadingZerosU32(uint32_t i) + { + if (i == 0) + return 32; + + int32_t n = 1; + + if (i >> 16 == 0) { + n += 16; + i <<= 16; + } + + if (i >> 24 == 0) { + n += 8; + i <<= 8; + } + + if (i >> 28 == 0) { + n += 4; + i <<= 4; + } + + if (i >> 30 == 0) { + n += 2; + i <<= 2; + } + + return n - static_cast(i >> 31); + } + + int32_t NumberOfLeadingZerosI64(int64_t i) + { + return NumberOfLeadingZerosU64(static_cast(i)); + } + + int32_t NumberOfLeadingZerosU64(uint64_t i) + { + if (i == 0) + return 64; + + int32_t n = 1; + + uint32_t x = static_cast(i >> 32); + + if (x == 0) { + n += 32; + x = static_cast(i); + } + + if (x >> 16 == 0) { + n += 16; + x <<= 16; + } + + if (x >> 24 == 0) { + n += 8; + x <<= 8; + } + + if (x >> 28 == 0) { + n += 4; + x <<= 4; + } + + if (x >> 30 == 0) { + n += 2; + x <<= 2; + } + + n -= x >> 31; + + return n; + } + + int32_t BitCountI32(int32_t i) + { + uint32_t ui = static_cast(i); + + ui -= (ui >> 1) & 0x55555555; + ui = (ui & 0x33333333) + ((ui >> 2) & 0x33333333); + ui = (ui + (ui >> 4)) & 0x0f0f0f0f; + ui += ui >> 8; + ui += ui >> 16; + + return static_cast(ui & 0x3f); + } + + int32_t BitLengthI32(int32_t i) + { + return 32 - NumberOfLeadingZerosI32(i); + } + + int32_t BitLengthU32(uint32_t i) + { + return 32 - NumberOfLeadingZerosU32(i); + } + + int32_t GetCapasityForSize(int32_t size) + { + assert(size > 0); + + if (size <= 8) + return 8; + + int32_t bl = BitLengthI32(size); + + if (bl > 30) + return INT32_MAX; + + int32_t res = 1 << bl; + + return size > res ? res << 1 : res; + } + + int32_t DigitLength(uint64_t x) + { + // See http://graphics.stanford.edu/~seander/bithacks.html + // for the details on the algorithm. + + if (x < 10) + return 1; + + int32_t r = ((64 - NumberOfLeadingZerosU64(x) + 1) * 1233) >> 12; + + assert(r <= UINT64_MAX_PRECISION); + + return (r == UINT64_MAX_PRECISION || x < TenPowerU64(r)) ? r : r + 1; + } + + uint64_t TenPowerU64(int32_t n) + { + static const uint64_t TEN_POWERS_TABLE[UINT64_MAX_PRECISION] = { + 1U, // 0 / 10^0 + 10U, // 1 / 10^1 + 100U, // 2 / 10^2 + 1000U, // 3 / 10^3 + 10000U, // 4 / 10^4 + 100000U, // 5 / 10^5 + 1000000U, // 6 / 10^6 + 10000000U, // 7 / 10^7 + 100000000U, // 8 / 10^8 + 1000000000U, // 9 / 10^9 + 10000000000U, // 10 / 10^10 + 100000000000U, // 11 / 10^11 + 1000000000000U, // 12 / 10^12 + 10000000000000U, // 13 / 10^13 + 100000000000000U, // 14 / 10^14 + 1000000000000000U, // 15 / 10^15 + 10000000000000000U, // 16 / 10^16 + 100000000000000000U, // 17 / 10^17 + 1000000000000000000U, // 18 / 10^18 + 10000000000000000000U // 19 / 10^19 + }; + + assert(n >= 0 && n < UINT64_MAX_PRECISION); + + return TEN_POWERS_TABLE[n]; + } + } + } + } +} diff --git a/src/odbc/src/common/concurrent.cpp b/src/odbc/src/common/concurrent.cpp new file mode 100644 index 000000000..1d041644c --- /dev/null +++ b/src/odbc/src/common/concurrent.cpp @@ -0,0 +1,108 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "ignite/odbc/common/concurrent.h" + +namespace ignite +{ + namespace odbc + { + namespace common + { + namespace concurrent + { + /** Thread-local index generator for application. */ + int32_t appTlsIdxGen = 0; + + int32_t ThreadLocal::NextIndex() + { + return Atomics::IncrementAndGet32(&appTlsIdxGen); + } + + void ThreadLocal::Remove(int32_t idx) + { + void* val = Get0(); + + if (val) + { + std::map* map = + static_cast*>(val); + + ThreadLocalEntry* appVal = (*map)[idx]; + + if (appVal) + delete appVal; + + map->erase(idx); + + if (map->size() == 0) + { + delete map; + + Set0(NULL); + } + } + } + + void ThreadLocal::Clear0(void* mapPtr) + { + if (mapPtr) + { + std::map* map = + static_cast*>(mapPtr); + + for (std::map::iterator it = map->begin(); it != map->end(); ++it) + delete it->second; + + delete map; + } + } + + SharedPointerImpl::SharedPointerImpl(void* ptr, DeleterType deleter) : + ptr(ptr), deleter(deleter), refCnt(1) + { + Memory::Fence(); + } + + void* SharedPointerImpl::Pointer() + { + return ptr; + } + + const void* SharedPointerImpl::Pointer() const + { + return ptr; + } + + SharedPointerImpl::DeleterType SharedPointerImpl::Deleter() + { + return deleter; + } + + void SharedPointerImpl::Increment() + { + Atomics::IncrementAndGet32(&refCnt); + } + + bool SharedPointerImpl::Decrement() + { + return Atomics::DecrementAndGet32(&refCnt) == 0; + } + } + } + } +} diff --git a/src/odbc/src/common/decimal.cpp b/src/odbc/src/common/decimal.cpp new file mode 100644 index 000000000..40d597547 --- /dev/null +++ b/src/odbc/src/common/decimal.cpp @@ -0,0 +1,278 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "ignite/odbc/common/utils.h" +#include "ignite/odbc/common/decimal.h" + +using ignite::odbc::common::BigInteger; + +namespace ignite +{ + namespace odbc + { + namespace common + { + Decimal::Decimal() : + scale(0), + magnitude(0) + { + // No-op. + } + + Decimal::Decimal(const int8_t* mag, int32_t len, int32_t scale, int32_t sign, bool bigEndian) : + scale(scale & 0x7FFFFFFF), + magnitude(mag, len, sign, bigEndian) + { + // No-op. + } + + Decimal::Decimal(const Decimal& other) : + scale(other.scale), + magnitude(other.magnitude) + { + // No-op. + } + + Decimal::Decimal(int64_t val) : + scale(0), + magnitude(val) + { + // No-op. + } + + Decimal::Decimal(int64_t val, int32_t scale) : + scale(scale), + magnitude(val) + { + // No-op. + } + + Decimal::Decimal(const BigInteger& val, int32_t scale) : + scale(scale), + magnitude(val) + { + // No-op. + } + + Decimal::Decimal(const char* val, int32_t len) : + scale(0), + magnitude(0) + { + AssignString(val, len); + } + + Decimal::~Decimal() + { + // No-op. + } + + Decimal& Decimal::operator=(const Decimal& other) + { + scale = other.scale; + magnitude = other.magnitude; + + return *this; + } + + Decimal::operator double() const + { + return ToDouble(); + } + + Decimal::operator int64_t() const + { + return ToInt64(); + } + + double Decimal::ToDouble() const + { + return common::LexicalCast(*this); + } + + int64_t Decimal::ToInt64() const + { + if (scale == 0) + return magnitude.ToInt64(); + + Decimal zeroScaled; + + SetScale(0, zeroScaled); + + return zeroScaled.magnitude.ToInt64(); + } + + int32_t Decimal::GetScale() const + { + return scale; + } + + void Decimal::SetScale(int32_t newScale, Decimal& res) const + { + if (scale == newScale) + return; + + int32_t diff = scale - newScale; + + BigInteger adjustment; + + if (diff > 0) + { + BigInteger::GetPowerOfTen(diff, adjustment); + + magnitude.Divide(adjustment, res.magnitude); + } + else + { + BigInteger::GetPowerOfTen(-diff, adjustment); + + magnitude.Multiply(adjustment, res.magnitude); + } + + res.scale = newScale; + } + + int32_t Decimal::GetPrecision() const + { + return magnitude.GetPrecision(); + } + + const BigInteger& Decimal::GetUnscaledValue() const + { + return magnitude; + } + + void Decimal::Swap(Decimal& second) + { + using std::swap; + + swap(scale, second.scale); + magnitude.Swap(second.magnitude); + } + + int32_t Decimal::GetMagnitudeLength() const + { + return magnitude.mag.GetSize(); + } + + void Decimal::AssignString(const char* val, int32_t len) + { + std::stringstream converter; + + converter.write(val, len); + + converter >> *this; + } + + void Decimal::AssignInt64(int64_t val) + { + magnitude.AssignInt64(val); + + scale = 0; + } + + void Decimal::AssignDouble(double val) + { + std::stringstream converter; + + converter.precision(16); + + converter << val; + converter >> *this; + } + + void Decimal::AssignUint64(uint64_t val) + { + magnitude.AssignUint64(val); + + scale = 0; + } + + int32_t Decimal::Compare(const Decimal& other) const + { + if (IsZero() && other.IsZero()) + return 0; + + if (scale == other.scale) + return magnitude.Compare(other.magnitude); + else if (scale > other.scale) + { + Decimal scaled; + + other.SetScale(scale, scaled); + + return magnitude.Compare(scaled.magnitude); + } + else + { + Decimal scaled; + + SetScale(other.scale, scaled); + + return scaled.magnitude.Compare(other.magnitude); + } + } + + bool Decimal::IsNegative() const + { + return magnitude.IsNegative(); + } + + bool Decimal::IsZero() const + { + return magnitude.IsZero(); + } + + bool Decimal::IsPositive() const + { + return magnitude.IsPositive(); + } + + bool operator==(const Decimal& val1, const Decimal& val2) + { + return val1.Compare(val2) == 0; + } + + bool operator!=(const Decimal& val1, const Decimal& val2) + { + return val1.Compare(val2) != 0; + } + + bool operator<(const Decimal& val1, const Decimal& val2) + { + return val1.Compare(val2) < 0; + } + + bool operator<=(const Decimal& val1, const Decimal& val2) + { + return val1.Compare(val2) <= 0; + } + + bool operator>(const Decimal& val1, const Decimal& val2) + { + return val1.Compare(val2) > 0; + } + + bool operator>=(const Decimal& val1, const Decimal& val2) + { + return val1.Compare(val2) >= 0; + } + } + } +} diff --git a/src/odbc/src/common/utils.cpp b/src/odbc/src/common/utils.cpp new file mode 100644 index 000000000..5dc44111f --- /dev/null +++ b/src/odbc/src/common/utils.cpp @@ -0,0 +1,219 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +namespace ignite +{ + namespace odbc + { + namespace common + { + /** + * Check if string ends with the given ending. + * + * @param str String to check. + * @param ending Ending. + * @return Result. + */ + inline bool StringEndsWith(const std::string& str, const std::string& ending) + { + if (str.length() > ending.length()) + return str.compare(str.length() - ending.length(), ending.length(), ending) == 0; + + return false; + } + + void StripSurroundingWhitespaces(std::string& str) + { + std::string::size_type newBegin = 0; + while (newBegin < str.size() && ::isspace(str[newBegin])) + ++newBegin; + + if (newBegin == str.size()) + { + str.clear(); + + return; + } + + std::string::size_type newEnd = str.size() - 1; + while (::isspace(str[newEnd])) + --newEnd; + + str.assign(str, newBegin, (newEnd - newBegin) + 1); + } + + char* CopyChars(const char* val) + { + if (val) { + size_t len = strlen(val); + char* dest = new char[len + 1]; + strcpy(dest, val); + *(dest + len) = 0; + return dest; + } + + return 0; + } + + void ReleaseChars(char* val) + { + // Its OK to delete null-pointer. + delete[] val; + } + + uint32_t ToBigEndian(uint32_t value) + { + // The answer is 42 + static const int num = 42; + static const bool isLittleEndian = (*reinterpret_cast(&num) == num); + + if (isLittleEndian) + return ((value & 0xFF) << 24) | (((value >> 8) & 0xFF) << 16) | (((value >> 16) & 0xFF) << 8) | ((value >> 24) & 0xFF); + + return value; + } + + IGNITE_FRIEND_EXPORT Date MakeDateGmt(int year, int month, int day, int hour, + int min, int sec) + { + tm date; + + std::memset(&date, 0, sizeof(date)); + + date.tm_year = year - 1900; + date.tm_mon = month - 1; + date.tm_mday = day; + date.tm_hour = hour; + date.tm_min = min; + date.tm_sec = sec; + + return CTmToDate(date); + } + + IGNITE_FRIEND_EXPORT Date MakeDateLocal(int year, int month, int day, int hour, + int min, int sec) + { + tm date; + + std::memset(&date, 0, sizeof(date)); + + date.tm_year = year - 1900; + date.tm_mon = month - 1; + date.tm_mday = day; + date.tm_hour = hour; + date.tm_min = min; + date.tm_sec = sec; + + time_t localTime = common::IgniteTimeLocal(date); + + return CTimeToDate(localTime); + } + + IGNITE_FRIEND_EXPORT Time MakeTimeGmt(int hour, int min, int sec) + { + tm date; + + std::memset(&date, 0, sizeof(date)); + + date.tm_year = 70; + date.tm_mon = 0; + date.tm_mday = 1; + date.tm_hour = hour; + date.tm_min = min; + date.tm_sec = sec; + + return CTmToTime(date); + } + + IGNITE_FRIEND_EXPORT Time MakeTimeLocal(int hour, int min, int sec) + { + tm date; + + std::memset(&date, 0, sizeof(date)); + + date.tm_year = 70; + date.tm_mon = 0; + date.tm_mday = 1; + date.tm_hour = hour; + date.tm_min = min; + date.tm_sec = sec; + + time_t localTime = common::IgniteTimeLocal(date); + + return CTimeToTime(localTime); + } + + IGNITE_FRIEND_EXPORT Timestamp MakeTimestampGmt(int year, int month, int day, + int hour, int min, int sec, long ns) + { + tm date; + + std::memset(&date, 0, sizeof(date)); + + date.tm_year = year - 1900; + date.tm_mon = month - 1; + date.tm_mday = day; + date.tm_hour = hour; + date.tm_min = min; + date.tm_sec = sec; + + return CTmToTimestamp(date, ns); + } + + IGNITE_FRIEND_EXPORT Timestamp MakeTimestampLocal(int year, int month, int day, + int hour, int min, int sec, long ns) + { + tm date; + + std::memset(&date, 0, sizeof(date)); + + date.tm_year = year - 1900; + date.tm_mon = month - 1; + date.tm_mday = day; + date.tm_hour = hour; + date.tm_min = min; + date.tm_sec = sec; + + time_t localTime = common::IgniteTimeLocal(date); + + return CTimeToTimestamp(localTime, ns); + } + + IGNITE_IMPORT_EXPORT std::string GetDynamicLibraryName(const char* name) + { + std::stringstream libNameBuffer; + + libNameBuffer << name << Dle; + + return libNameBuffer.str(); + } + + IGNITE_IMPORT_EXPORT bool AllDigits(const std::string &val) + { + std::string::const_iterator i = val.begin(); + + while (i != val.end() && isdigit(*i)) + ++i; + + return i == val.end(); + } + + } + } +} diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index 066ffab76..4bdc511f7 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -21,8 +21,7 @@ #include #include -#include - +#include #include #include "ignite/odbc/log.h" @@ -37,6 +36,10 @@ #include "ignite/odbc/config/configuration.h" #include "ignite/odbc/config/connection_string_parser.h" #include "ignite/odbc/system/system_dsn.h" +#include "ignite/odbc/jni/java.h" +#include "ignite/odbc/jni/utils.h" +#include "ignite/odbc/common/concurrent.h" +#include "ignite/odbc/common/utils.h" // Uncomment for per-byte debug. //#define PER_BYTE_DEBUG @@ -58,16 +61,16 @@ namespace ignite { Connection::Connection(Environment* env) : env(env), - socket(), timeout(0), loginTimeout(DEFAULT_CONNECT_TIMEOUT), autoCommit(true), parser(), config(), info(config), - streamingContext() + connection(), + opts() { - streamingContext.SetConnection(*this); + // No-op } Connection::~Connection() @@ -144,47 +147,15 @@ namespace ignite IGNITE_ODBC_API_CALL(InternalEstablish(cfg)); } - SqlResult::Type Connection::InitSocket() - { - // Removed SSL Mode in DSN. Replaced this with REQUIRE for now. - ssl::SslMode::Type sslMode = ssl::SslMode::REQUIRE; - - if (sslMode == ssl::SslMode::DISABLE) - { - socket.reset(network::ssl::MakeTcpSocketClient()); - - return SqlResult::AI_SUCCESS; - } - - try - { - network::ssl::EnsureSslLoaded(); - } - catch (const IgniteError &err) - { - LOG_MSG("Can not load OpenSSL library: " << err.GetText()); - - AddStatusRecord("Can not load OpenSSL library (did you set OPENSSL_HOME environment variable?)"); - - return SqlResult::AI_ERROR; - } - - // Removed SSL key and cert files from DSN. Replaced with empty string for now. - socket.reset(network::ssl::MakeSecureSocketClient( - "", "", config.GetTlsCaFile())); - - return SqlResult::AI_SUCCESS; - } - SqlResult::Type Connection::InternalEstablish(const config::Configuration& cfg) { using ssl::SslMode; config = cfg; - if (socket.get() != 0) - { - AddStatusRecord(SqlState::S08002_ALREADY_CONNECTED, "Already connected."); + if (connection) { + AddStatusRecord(SqlState::S08002_ALREADY_CONNECTED, + "Already connected."); return SqlResult::AI_ERROR; } @@ -196,11 +167,15 @@ namespace ignite return SqlResult::AI_ERROR; } - bool connected = TryRestoreConnection(); + odbc::IgniteError err; + bool connected = TryRestoreConnection(err); if (!connected) { - AddStatusRecord(SqlState::S08001_CANNOT_CONNECT, "Failed to establish connection with the host."); + std::string errMessage = "Failed to establish connection with the host.\n"; + errMessage.append(err.GetText()); + AddStatusRecord( + SqlState::S08001_CANNOT_CONNECT, errMessage); return SqlResult::AI_ERROR; } @@ -222,7 +197,7 @@ namespace ignite SqlResult::Type Connection::InternalRelease() { - if (socket.get() == 0) + if (!connection) { AddStatusRecord(SqlState::S08003_NOT_CONNECTED, "Connection is not open."); @@ -238,12 +213,19 @@ namespace ignite void Connection::Close() { - if (socket.get() != 0) - { - socket->Close(); - - socket.reset(); + if (connection) { + using namespace jni::java; + using namespace common::concurrent; + SharedPointer< JniContext > ctx(JniContext::Create(&opts[0], static_cast(opts.size()), JniHandlers())); + JniErrorInfo errInfo; + // NOTE: DocumentDbDisconnect will notify JNI connection is no longer used - must set to nullptr. + ctx.Get()->DocumentDbDisconnect(connection, &errInfo); + if (errInfo.code != java::IGNITE_JNI_ERR_SUCCESS) { + // TODO: Determine if we need to error check the close. + } + connection = nullptr; } + Deinit(); } Statement* Connection::CreateStatement() @@ -271,125 +253,26 @@ namespace ignite bool Connection::Send(const int8_t* data, size_t len, int32_t timeout) { - if (socket.get() == 0) - throw OdbcError(SqlState::S08003_NOT_CONNECTED, "Connection is not established"); - - int32_t newLen = static_cast(len + sizeof(OdbcProtocolHeader)); - - common::FixedSizeArray msg(newLen); - - OdbcProtocolHeader *hdr = reinterpret_cast(msg.GetData()); - - hdr->len = static_cast(len); - - memcpy(msg.GetData() + sizeof(OdbcProtocolHeader), data, len); - - OperationResult::T res = SendAll(msg.GetData(), msg.GetSize(), timeout); - - if (res == OperationResult::TIMEOUT) - return false; - - if (res == OperationResult::FAIL) - throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not send message due to connection failure"); - -#ifdef PER_BYTE_DEBUG - LOG_MSG("message sent: (" << msg.GetSize() << " bytes)" << utility::HexDump(msg.GetData(), msg.GetSize())); -#endif //PER_BYTE_DEBUG - + // TODO: Remove if unnecessary return true; } Connection::OperationResult::T Connection::SendAll(const int8_t* data, size_t len, int32_t timeout) { - int sent = 0; - - while (sent != static_cast(len)) - { - int res = socket->Send(data + sent, len - sent, timeout); - - LOG_MSG("Sent: " << res); - - if (res < 0 || res == network::SocketClient::WaitResult::TIMEOUT) - { - Close(); - - return res < 0 ? OperationResult::FAIL : OperationResult::TIMEOUT; - } - - sent += res; - } - - assert(static_cast(sent) == len); - + // TODO: Remove if unnecessary. + // No-op return OperationResult::SUCCESS; } bool Connection::Receive(std::vector& msg, int32_t timeout) { - if (socket.get() == 0) - throw OdbcError(SqlState::S08003_NOT_CONNECTED, "Connection is not established"); - - msg.clear(); - - OdbcProtocolHeader hdr; - - OperationResult::T res = ReceiveAll(reinterpret_cast(&hdr), sizeof(hdr), timeout); - - if (res == OperationResult::TIMEOUT) - return false; - - if (res == OperationResult::FAIL) - throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not receive message header"); - - if (hdr.len < 0) - { - Close(); - - throw OdbcError(SqlState::SHY000_GENERAL_ERROR, "Protocol error: Message length is negative"); - } - - if (hdr.len == 0) - return false; - - msg.resize(hdr.len); - - res = ReceiveAll(&msg[0], hdr.len, timeout); - - if (res == OperationResult::TIMEOUT) - return false; - - if (res == OperationResult::FAIL) - throw OdbcError(SqlState::S08S01_LINK_FAILURE, "Can not receive message body"); - -#ifdef PER_BYTE_DEBUG - LOG_MSG("Message received: " << utility::HexDump(&msg[0], msg.size())); -#endif //PER_BYTE_DEBUG - + // TODO: Remove if unnecessary. return true; } Connection::OperationResult::T Connection::ReceiveAll(void* dst, size_t len, int32_t timeout) { - size_t remain = len; - int8_t* buffer = reinterpret_cast(dst); - - while (remain) - { - size_t received = len - remain; - - int res = socket->Receive(buffer + received, remain, timeout); - LOG_MSG("Receive res: " << res << " remain: " << remain); - - if (res < 0 || res == network::SocketClient::WaitResult::TIMEOUT) - { - Close(); - - return res < 0 ? OperationResult::FAIL : OperationResult::TIMEOUT; - } - - remain -= static_cast(res); - } - + // TODO: Remove if unnecessary. return OperationResult::SUCCESS; } @@ -445,7 +328,7 @@ namespace ignite return SqlResult::AI_ERROR; } - catch (const IgniteError& err) + catch (const odbc::IgniteError& err) { AddStatusRecord(err.GetText()); @@ -486,7 +369,7 @@ namespace ignite return SqlResult::AI_ERROR; } - catch (const IgniteError& err) + catch (const odbc::IgniteError& err) { AddStatusRecord(err.GetText()); @@ -516,7 +399,7 @@ namespace ignite { SQLUINTEGER *val = reinterpret_cast(buf); - *val = socket.get() != 0 ? SQL_CD_FALSE : SQL_CD_TRUE; + *val = connection ? SQL_CD_FALSE : SQL_CD_TRUE; if (valueLen) *valueLen = SQL_IS_INTEGER; @@ -681,7 +564,7 @@ namespace ignite return SqlResult::AI_ERROR; } - catch (const IgniteError& err) + catch (const odbc::IgniteError& err) { AddStatusRecord(SqlState::S08004_CONNECTION_REJECTED, err.GetText()); @@ -716,67 +599,177 @@ namespace ignite void Connection::EnsureConnected() { - if (socket.get() != 0) + if (connection) return; - bool success = TryRestoreConnection(); + odbc::IgniteError err; + bool success = TryRestoreConnection(err); if (!success) throw OdbcError(SqlState::S08001_CANNOT_CONNECT, "Failed to establish connection with any provided hosts"); } - bool Connection::TryRestoreConnection() + bool Connection::TryRestoreConnection(odbc::IgniteError& err) { - std::vector addrs; - - CollectAddresses(config, addrs); + bool connected = false; - if (socket.get() == 0) - { - SqlResult::Type res = InitSocket(); + using namespace jni::java; + using namespace common::concurrent; - if (res != SqlResult::AI_SUCCESS) - return false; + if (connection) { + return true; } - bool connected = false; + std::string connectionString = FormatJdbcConnectionString(); + JniErrorInfo errInfo; - while (!addrs.empty() && !connected) - { - const EndPoint& addr = addrs.back(); + std::string docdb_home = common::GetEnv("DOCUMENTDB_HOME") + + "\\documentdb-jdbc-1.1.0-all.jar"; + + // 2. Resolve DOCUMENTDB_HOME. + std::string home = jni::ResolveDocumentDbHome(); - for (uint16_t port = addr.port; port <= addr.port + addr.range; ++port) - { - try - { - connected = socket->Connect(addr.host.c_str(), port, loginTimeout); - } - catch (const IgniteError& err) - { - LOG_MSG("Error while trying connect to " << addr.host << ":" << addr.port <<", " << err.GetText()); - } + // 3. Create classpath. + std::string cp = jni::CreateDocumentDbClasspath(std::string(), home); - if (connected) - { - SqlResult::Type res = MakeRequestHandshake(); + if (cp.empty()) { + err = + odbc::IgniteError(odbc::IgniteError::IGNITE_ERR_JVM_NO_CLASSPATH, + "Java classpath is empty (did you set " + "DOCUMENTDB_HOME environment variable?)"); - connected = res != SqlResult::AI_ERROR; + return false; + } - if (connected) - break; - } + SetJvmOptions(cp); + + SharedPointer< JniContext > ctx(JniContext::Create(&opts[0], static_cast(opts.size()), JniHandlers(), &errInfo)); + if (ctx.Get()) { + jobject result = ctx.Get()->DocumentDbConnect( + connectionString.c_str(), &errInfo); + connected = (result && errInfo.code == java::IGNITE_JNI_ERR_SUCCESS); + if (!connected) { + err = odbc::IgniteError( + odbc::IgniteError::IGNITE_ERR_SECURE_CONNECTION_FAILURE, + errInfo.errMsg); + Close(); } - - addrs.pop_back(); + connection = result; + } else { + err = odbc::IgniteError(odbc::IgniteError::IGNITE_ERR_JVM_INIT, "Unable to get initialized JVM."); + connection = nullptr; } - if (!connected) - Close(); - return connected; } + std::string Connection::FormatJdbcConnectionString() const { + std::string host = "localhost"; + std::string port = "27017"; + if (!config.GetAddresses().empty()) { + host = config.GetAddresses()[0].host; + port = std::to_string(config.GetAddresses()[0].port); + } + std::string jdbConnectionString; + + jdbConnectionString = "jdbc:documentdb:"; + jdbConnectionString.append("//" + config.GetUser()); + jdbConnectionString.append(":" + config.GetPassword()); + jdbConnectionString.append("@" + host); + jdbConnectionString.append(":" + port); + jdbConnectionString.append("/" + config.GetSchema()); + jdbConnectionString.append("?tlsAllowInvalidHostnames=true"); + + // Check if internal SSH tunnel should be enabled. + // TODO: Remove use of environment variables and use DSN properties + std::string sshUserAtHost = common::GetEnv("DOC_DB_USER", ""); + std::string sshRemoteHost = common::GetEnv("DOC_DB_HOST", ""); + std::string sshPrivKeyFile = common::GetEnv("DOC_DB_PRIV_KEY_FILE", ""); + std::string sshUser; + std::string sshTunnelHost; + size_t indexOfAt = sshUserAtHost.find_first_of('@'); + if (indexOfAt >= 0 && sshUserAtHost.size() > (indexOfAt + 1)) { + sshUser = sshUserAtHost.substr(0, indexOfAt); + sshTunnelHost = sshUserAtHost.substr(indexOfAt + 1); + } + if (!sshUserAtHost.empty() + && !sshRemoteHost.empty() + && !sshPrivKeyFile.empty() + && !sshUser.empty() + && !sshTunnelHost.empty()) { + jdbConnectionString.append("&sshUser=" + sshUser); + jdbConnectionString.append("&sshHost=" + sshTunnelHost); + jdbConnectionString.append("&sshPrivateKeyFile=" + sshPrivKeyFile); + jdbConnectionString.append("&sshStrictHostKeyChecking=false"); + } + + return jdbConnectionString; + } + + /** + * Create JVM options from configuration. + * + * @param cfg Configuration. + * @param home Optional GG home. + * @param cp Classpath. + */ + void Connection::SetJvmOptions(const std::string& cp) { + using namespace common; + Deinit(); + + const size_t REQ_OPTS_CNT = 4; + const size_t JAVA9_OPTS_CNT = 6; + + opts.reserve(REQ_OPTS_CNT + JAVA9_OPTS_CNT); + + // 1. Set classpath. + std::string cpFull = "-Djava.class.path=" + cp; + + opts.push_back(CopyChars(cpFull.c_str())); + + // 3. Set Xms, Xmx. + std::string xmsStr = "-Xms" + std::to_string(256) + "m"; + std::string xmxStr = "-Xmx" + std::to_string(1024) + "m"; + + opts.push_back(CopyChars(xmsStr.c_str())); + opts.push_back(CopyChars(xmxStr.c_str())); + + // 4. Optional debug arguments + //std::string debugStr = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005"; + //opts.push_back(CopyChars(debugStr.c_str())); + + // 5. Set file.encoding. + std::string fileEncParam = "-Dfile.encoding="; + std::string fileEncFull = fileEncParam + "UTF-8"; + opts.push_back(CopyChars(fileEncFull.c_str())); + + // Adding options for Java 9 or later + if (jni::java::IsJava9OrLater()) { + opts.push_back(CopyChars( + "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED")); + opts.push_back(CopyChars( + "--add-exports=java.base/sun.nio.ch=ALL-UNNAMED")); + opts.push_back(CopyChars( + "--add-exports=java.management/com.sun.jmx.mbeanserver=ALL-UNNAMED")); + opts.push_back(CopyChars( + "--add-exports=jdk.internal.jvmstat/sun.jvmstat.monitor=ALL-UNNAMED")); + opts.push_back(CopyChars( + "--add-exports=java.base/sun.reflect.generics.reflectiveObjects=ALL-UNNAMED")); + opts.push_back(CopyChars( + "--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED")); + } + } + + /** + * Deallocates all allocated data. + */ + void Connection::Deinit() { + using namespace common; + std::for_each(opts.begin(), opts.end(), ReleaseChars); + opts.clear(); + } + void Connection::CollectAddresses(const config::Configuration& cfg, std::vector& endPoints) { endPoints.clear(); @@ -806,14 +799,6 @@ namespace ignite { SQLUINTEGER uTimeout = static_cast(reinterpret_cast(value)); - if (uTimeout != 0 && socket.get() != 0 && socket->IsBlocking()) - { - AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, "Can not set timeout, because can not " - "enable non-blocking mode on TCP connection. Setting to 0."); - - return 0; - } - if (uTimeout > INT32_MAX) { std::stringstream ss; diff --git a/src/odbc/src/ignite_error.cpp b/src/odbc/src/ignite_error.cpp new file mode 100644 index 000000000..23841d413 --- /dev/null +++ b/src/odbc/src/ignite_error.cpp @@ -0,0 +1,227 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include +#include + +using namespace ignite::odbc::common; +using namespace ignite::odbc::java; + +namespace ignite +{ + namespace odbc + { + void IgniteError::ThrowIfNeeded(const IgniteError& err) + { + if (err.code != IGNITE_SUCCESS) + throw err; + } + + IgniteError::IgniteError() : + code(IGNITE_SUCCESS), + msg(NULL) + { + // No-op. + } + + IgniteError::IgniteError(int32_t code) : + code(code), + msg(NULL) + { + } + + IgniteError::IgniteError(int32_t code, const char* msg) : + code(code), + msg(CopyChars(msg)) + { + // No-op. + } + + IgniteError::IgniteError(const IgniteError& other) : + code(other.code), + msg(CopyChars(other.msg)) + { + // No-op. + } + + IgniteError& IgniteError::operator=(const IgniteError& other) + { + if (this != &other) + { + IgniteError tmp(other); + + std::swap(code, tmp.code); + std::swap(msg, tmp.msg); + } + + return *this; + } + + IgniteError::~IgniteError() IGNITE_NO_THROW + { + ReleaseChars(msg); + } + + int32_t IgniteError::GetCode() const + { + return code; + } + + const char* IgniteError::GetText() const IGNITE_NO_THROW + { + if (code == IGNITE_SUCCESS) + return "Operation completed successfully."; + else if (msg) + return msg; + else + return "No additional information available."; + } + + const char* IgniteError::what() const IGNITE_NO_THROW + { + return GetText(); + } + + void IgniteError::SetError(const int jniCode, const char* jniCls, const char* jniMsg, IgniteError& err) + { + if (jniCode == IGNITE_JNI_ERR_SUCCESS) + err = IgniteError(); + else if (jniCode == IGNITE_JNI_ERR_GENERIC) + { + // The most common case when we have Java exception "in hands" and must map it to respective code. + if (jniCls) + { + std::string jniCls0 = jniCls; + + if (jniCls0.compare("java.lang.NoClassDefFoundError") == 0) + { + std::stringstream stream; + + stream << "Java class is not found (did you set DOCUMENTDB_HOME environment variable?)"; + + if (jniMsg) + stream << ": " << jniMsg; + + err = IgniteError(IGNITE_ERR_JVM_NO_CLASS_DEF_FOUND, stream.str().c_str()); + } + else if (jniCls0.compare("java.lang.NoSuchMethodError") == 0) + { + std::stringstream stream; + + stream << "Java method is not found (did you set DOCUMENTDB_HOME environment variable?)"; + + if (jniMsg) + stream << ": " << jniMsg; + + err = IgniteError(IGNITE_ERR_JVM_NO_SUCH_METHOD, stream.str().c_str()); + } + else if (jniCls0.compare("java.lang.IllegalArgumentException") == 0) + err = IgniteError(IGNITE_ERR_ILLEGAL_ARGUMENT, jniMsg); + else if (jniCls0.compare("java.lang.IllegalStateException") == 0) + err = IgniteError(IGNITE_ERR_ILLEGAL_STATE, jniMsg); + else if (jniCls0.compare("java.lang.UnsupportedOperationException") == 0) + err = IgniteError(IGNITE_ERR_UNSUPPORTED_OPERATION, jniMsg); + else if (jniCls0.compare("java.lang.InterruptedException") == 0) + err = IgniteError(IGNITE_ERR_INTERRUPTED, jniMsg); + else if (jniCls0.compare("org.apache.ignite.cluster.ClusterGroupEmptyException") == 0) + err = IgniteError(IGNITE_ERR_CLUSTER_GROUP_EMPTY, jniMsg); + else if (jniCls0.compare("org.apache.ignite.cluster.ClusterTopologyException") == 0) + err = IgniteError(IGNITE_ERR_CLUSTER_TOPOLOGY, jniMsg); + else if (jniCls0.compare("org.apache.ignite.compute.ComputeExecutionRejectedException") == 0) + err = IgniteError(IGNITE_ERR_COMPUTE_EXECUTION_REJECTED, jniMsg); + else if (jniCls0.compare("org.apache.ignite.compute.ComputeJobFailoverException") == 0) + err = IgniteError(IGNITE_ERR_COMPUTE_JOB_FAILOVER, jniMsg); + else if (jniCls0.compare("org.apache.ignite.compute.ComputeTaskCancelledException") == 0) + err = IgniteError(IGNITE_ERR_COMPUTE_TASK_CANCELLED, jniMsg); + else if (jniCls0.compare("org.apache.ignite.compute.ComputeTaskTimeoutException") == 0) + err = IgniteError(IGNITE_ERR_COMPUTE_TASK_TIMEOUT, jniMsg); + else if (jniCls0.compare("org.apache.ignite.compute.ComputeUserUndeclaredException") == 0) + err = IgniteError(IGNITE_ERR_COMPUTE_USER_UNDECLARED_EXCEPTION, jniMsg); + else if (jniCls0.compare("javax.cache.CacheException") == 0) + err = IgniteError(IGNITE_ERR_CACHE, jniMsg); + else if (jniCls0.compare("javax.cache.integration.CacheLoaderException") == 0) + err = IgniteError(IGNITE_ERR_CACHE_LOADER, jniMsg); + else if (jniCls0.compare("javax.cache.integration.CacheWriterException") == 0) + err = IgniteError(IGNITE_ERR_CACHE_WRITER, jniMsg); + else if (jniCls0.compare("javax.cache.processor.EntryProcessorException") == 0) + err = IgniteError(IGNITE_ERR_ENTRY_PROCESSOR, jniMsg); + else if (jniCls0.compare("org.apache.ignite.cache.CachePartialUpdateException") == 0) + err = IgniteError(IGNITE_ERR_CACHE_PARTIAL_UPDATE, jniMsg); + else if (jniCls0.compare("org.apache.ignite.transactions.TransactionOptimisticException") == 0) + err = IgniteError(IGNITE_ERR_TX_OPTIMISTIC, jniMsg); + else if (jniCls0.compare("org.apache.ignite.transactions.TransactionTimeoutException") == 0) + err = IgniteError(IGNITE_ERR_TX_TIMEOUT, jniMsg); + else if (jniCls0.compare("org.apache.ignite.transactions.TransactionRollbackException") == 0) + err = IgniteError(IGNITE_ERR_TX_ROLLBACK, jniMsg); + else if (jniCls0.compare("org.apache.ignite.transactions.TransactionHeuristicException") == 0) + err = IgniteError(IGNITE_ERR_TX_HEURISTIC, jniMsg); + else if (jniCls0.compare("org.apache.ignite.IgniteAuthenticationException") == 0) + err = IgniteError(IGNITE_ERR_AUTHENTICATION, jniMsg); + else if (jniCls0.compare("org.apache.ignite.plugin.security.GridSecurityException") == 0) + err = IgniteError(IGNITE_ERR_SECURITY, jniMsg); + else if (jniCls0.compare("org.apache.ignite.IgniteException") == 0) + err = IgniteError(IGNITE_ERR_GENERIC, jniMsg); + else if (jniCls0.compare("org.apache.ignite.IgniteCheckedException") == 0) + err = IgniteError(IGNITE_ERR_GENERIC, jniMsg); + else + { + std::stringstream stream; + + stream << "Java exception occurred [cls=" << jniCls0; + + if (jniMsg) + stream << ", msg=" << jniMsg; + + stream << "]"; + + err = IgniteError(IGNITE_ERR_UNKNOWN, stream.str().c_str()); + } + } + else + { + // JNI class name is not available. Something really weird. + err = IgniteError(IGNITE_ERR_UNKNOWN); + } + } + else if (jniCode == IGNITE_JNI_ERR_JVM_INIT) + { + std::stringstream stream; + + stream << "Failed to initialize JVM [errCls="; + + if (jniCls) + stream << jniCls; + else + stream << "N/A"; + + stream << ", errMsg="; + + if (jniMsg) + stream << jniMsg; + else + stream << "N/A"; + + stream << "]"; + + err = IgniteError(IGNITE_ERR_JVM_INIT, stream.str().c_str()); + } + else if (jniCode == IGNITE_JNI_ERR_JVM_ATTACH) + err = IgniteError(IGNITE_ERR_JVM_ATTACH, "Failed to attach to JVM."); + } + } +} diff --git a/src/odbc/src/jni/java.cpp b/src/odbc/src/jni/java.cpp new file mode 100644 index 000000000..dcd21b0b3 --- /dev/null +++ b/src/odbc/src/jni/java.cpp @@ -0,0 +1,1102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// ReSharper disable once CppUnusedIncludeDirective +#include // needed only on linux +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifndef JNI_VERSION_9 +#define JNI_VERSION_9 0x00090000 +#endif // JNI_VERSION_9 + +#define IGNITE_SAFE_PROC_NO_ARG(jniEnv, envPtr, type, field) { \ + JniHandlers* hnds = reinterpret_cast(envPtr); \ + type hnd = hnds->field; \ + if (hnd) \ + { \ + try \ + { \ + hnd(hnds->target); \ + } \ + catch (std::exception& err) \ + { \ + ThrowToJava(jniEnv, err.what()); \ + } \ + } \ + else \ + ThrowOnMissingHandler(jniEnv); \ +} + +#define IGNITE_SAFE_PROC(jniEnv, envPtr, type, field, ...) { \ + JniHandlers* hnds = reinterpret_cast(envPtr); \ + type hnd = hnds->field; \ + if (hnd) \ + { \ + try \ + { \ + hnd(hnds->target, __VA_ARGS__); \ + } \ + catch (std::exception& err) \ + { \ + ThrowToJava(jniEnv, err.what()); \ + } \ + } \ + else \ + ThrowOnMissingHandler(jniEnv); \ +} + +#define IGNITE_SAFE_FUNC(jniEnv, envPtr, type, field, ...) { \ + JniHandlers* hnds = reinterpret_cast(envPtr); \ + type hnd = hnds->field; \ + if (hnd) \ + { \ + try \ + { \ + return hnd(hnds->target, __VA_ARGS__); \ + } \ + catch (std::exception& err) \ + { \ + ThrowToJava(jniEnv, err.what()); \ + return 0; \ + } \ + } \ + else \ + { \ + ThrowOnMissingHandler(jniEnv); \ + return 0; \ + }\ +} + +using namespace ignite::odbc::java; + +namespace ignite +{ + namespace odbc + { + namespace jni + { + namespace java + { + namespace iocc = ignite::odbc::common::concurrent; + + bool IGNITE_IMPORT_EXPORT IsJava9OrLater() + { + JavaVMInitArgs args; + + memset(&args, 0, sizeof(args)); + + args.version = JNI_VERSION_9; + + return JNI_GetDefaultJavaVMInitArgs(&args) == JNI_OK; + } + + /* --- Startup exception. --- */ + class JvmException : public std::exception { + // No-op. + }; + + /* --- JNI method definitions. --- */ + struct JniMethod { + char* name; + char* sign; + bool isStatic; + + JniMethod(const char* name, const char* sign, bool isStatic) + : name(const_cast< char* >(name)), + sign(const_cast< char* >(sign)), + isStatic(isStatic) { + } + }; + + JniErrorInfo::JniErrorInfo() : code(IGNITE_JNI_ERR_SUCCESS) + { + // No-op. + } + + JniErrorInfo::JniErrorInfo(int code, const char* errCls, const char* errMsg) : code(code) + { + this->errCls = common::CopyChars(errCls); + this->errMsg = common::CopyChars(errMsg); + } + + JniErrorInfo::JniErrorInfo(const JniErrorInfo& other) : code(other.code) + { + this->errCls = common::CopyChars(other.errCls); + this->errMsg = common::CopyChars(other.errMsg); + } + + JniErrorInfo& JniErrorInfo::operator=(const JniErrorInfo& other) + { + if (this != &other) + { + // 1. Create new instance, exception could occur at this point. + JniErrorInfo tmp(other); + + // 2. Swap with temp. + std::swap(code, tmp.code); + std::swap(errCls, tmp.errCls); + std::swap(errMsg, tmp.errMsg); + } + + return *this; + } + + JniErrorInfo::~JniErrorInfo() + { + delete[] errCls; + delete[] errMsg; + } + + /** + * Guard to ensure global reference cleanup. + */ + class JniGlobalRefGuard + { + public: + JniGlobalRefGuard(JNIEnv *e, jobject obj) : env(e), ref(obj) + { + // No-op. + } + + ~JniGlobalRefGuard() + { + env->DeleteGlobalRef(ref); + } + + private: + /** Environment. */ + JNIEnv* env; + + /** Target reference. */ + jobject ref; + + IGNITE_NO_COPY_ASSIGNMENT(JniGlobalRefGuard); + }; + + const char* C_THROWABLE = "java/lang/Throwable"; + JniMethod M_THROWABLE_GET_MESSAGE = JniMethod("getMessage", "()Ljava/lang/String;", false); + JniMethod M_THROWABLE_PRINT_STACK_TRACE = JniMethod("printStackTrace", "()V", false); + + const char* C_CLASS = "java/lang/Class"; + JniMethod M_CLASS_GET_NAME = JniMethod("getName", "()Ljava/lang/String;", false); + + const char* C_DOCUMENTDB_CONNECTION_PROPERTIES = + "software/amazon/documentdb/jdbc/DocumentDbConnectionProperties"; + JniMethod M_DOCUMENTDB_CONNECTION_PROPERTIES_GET_PROPERTIES_FROM_CONNECTION_STRING = + JniMethod( + "getPropertiesFromConnectionString", + "(Ljava/lang/String;)Lsoftware/amazon/documentdb/jdbc/DocumentDbConnectionProperties;", + true); + + const char* C_DOCUMENTDB_CONNECTION = "software/amazon/documentdb/jdbc/DocumentDbConnectionProperties"; + + const char* C_DRIVERMANAGER = "java/sql/DriverManager"; + JniMethod M_DRIVERMANAGER_GET_CONNECTION = + JniMethod("getConnection", "(Ljava/lang/String;)Ljava/sql/Connection;", true); + + const char* C_JAVA_SQL_CONNECTION = "java/sql/Connection"; + JniMethod M_JAVA_SQL_CONNECTION_CLOSE = JniMethod("close", "()V", false); + + // TODO: Provide a "getFullStackTrace" from DocumentDB + //JniMethod M_PLATFORM_UTILS_GET_FULL_STACK_TRACE = JniMethod("getFullStackTrace", "(Ljava/lang/Throwable;)Ljava/lang/String;", true); + + + /* STATIC STATE. */ + iocc::CriticalSection JVM_LOCK; + iocc::CriticalSection CONSOLE_LOCK; + JniJvm JVM; + bool PRINT_EXCEPTION = false; + std::vector consoleWriteHandlers; + + /* HELPER METHODS. */ + + /** + * Throw exception to Java in case of missing callback pointer. It means that callback is not implemented in + * native platform and Java -> platform operation cannot proceede further. As JniContext is not available at + * this point, we have to obtain exception details from scratch. This is not critical from performance + * perspective because missing handler usually denotes fatal condition. + * + * @param env JNI environment. + */ + int ThrowOnMissingHandler(JNIEnv* env) + { + //jclass cls = env->FindClass(C_PLATFORM_NO_CALLBACK_EXCEPTION); + + //env->ThrowNew(cls, "Callback handler is not set in native platform."); + + return 0; + } + + /** + * Throw generic exception to Java in case of native exception. As JniContext is not available at + * this point, we have to obtain exception details from scratch. This is not critical from performance + * perspective because such exception is usually denotes fatal condition. + * + * @param env JNI environment. + * @param msg Message. + */ + void ThrowToJava(JNIEnv* env, const char* msg) + { + //jclass cls = env->FindClass(C_IGNITE_EXCEPTION); + + //env->ThrowNew(cls, msg); + } + + char* StringToChars(JNIEnv* env, jstring str, int* len) { + if (!str) { + *len = 0; + return NULL; + } + + const char* strChars = env->GetStringUTFChars(str, 0); + const int strCharsLen = env->GetStringUTFLength(str); + + char* strChars0 = new char[strCharsLen + 1]; + std::strcpy(strChars0, strChars); + *(strChars0 + strCharsLen) = 0; + + env->ReleaseStringUTFChars(str, strChars); + + if (len) + *len = strCharsLen; + + return strChars0; + } + + std::string JavaStringToCString(JNIEnv* env, jstring str, int* len) + { + char* resChars = StringToChars(env, str, len); + + if (resChars) + { + std::string res = std::string(resChars, *len); + + delete[] resChars; + + return res; + } + else + return std::string(); + } + + jclass FindClass(JNIEnv* env, const char *name) { + jclass res = env->FindClass(name); + + if (!res) + throw JvmException(); + + jclass res0 = static_cast(env->NewGlobalRef(res)); + + env->DeleteLocalRef(res); + + return res0; + } + + void DeleteClass(JNIEnv* env, jclass cls) { + if (cls) + env->DeleteGlobalRef(cls); + } + + void CheckClass(JNIEnv* env, const char *name) + { + jclass res = env->FindClass(name); + + if (!res) + throw JvmException(); + } + + jmethodID FindMethod(JNIEnv* env, jclass cls, JniMethod mthd) { + jmethodID mthd0 = mthd.isStatic + ? env->GetStaticMethodID(cls, mthd.name, mthd.sign) + : env->GetMethodID(cls, mthd.name, mthd.sign); + + if (!mthd0) + throw JvmException(); + + return mthd0; + } + + jobject NewObject(JNIEnv* env, jclass clazz, jmethodID constructor, ...) { + va_list args; + va_start(args, constructor); + jobject result = env->NewObject(clazz, constructor, args); + va_end(args); + + if (!result) + throw JvmException(); + + return result; + } + + void AddNativeMethod(JNINativeMethod* mthd, JniMethod jniMthd, void* fnPtr) { + mthd->name = jniMthd.name; + mthd->signature = jniMthd.sign; + mthd->fnPtr = fnPtr; + } + + void JniJavaMembers::Initialize(JNIEnv* env) { + c_Class = FindClass(env, C_CLASS); + m_Class_getName = FindMethod(env, c_Class, M_CLASS_GET_NAME); + + c_Throwable = FindClass(env, C_THROWABLE); + m_Throwable_getMessage = FindMethod(env, c_Throwable, M_THROWABLE_GET_MESSAGE); + m_Throwable_printStackTrace = FindMethod(env, c_Throwable, M_THROWABLE_PRINT_STACK_TRACE); + + // TODO: Provide "getFullStackTrace" in DocumentDB + //m_PlatformUtils_getFullStackTrace = FindMethod(env, c_PlatformUtils, M_PLATFORM_UTILS_GET_FULL_STACK_TRACE); + } + + void JniJavaMembers::Destroy(JNIEnv* env) { + DeleteClass(env, c_Class); + DeleteClass(env, c_Throwable); + DeleteClass(env, c_PlatformUtils); + } + + bool JniJavaMembers::WriteErrorInfo(JNIEnv* env, char** errClsName, int* errClsNameLen, char** errMsg, + int* errMsgLen, char** stackTrace, int* stackTraceLen) { + if (env && env->ExceptionCheck()) { + if (m_Class_getName && m_Throwable_getMessage) { + jthrowable err = env->ExceptionOccurred(); + + env->ExceptionClear(); + + jclass errCls = env->GetObjectClass(err); + + jstring clsName = static_cast(env->CallObjectMethod(errCls, m_Class_getName)); + *errClsName = StringToChars(env, clsName, errClsNameLen); + + jstring msg = static_cast(env->CallObjectMethod(err, m_Throwable_getMessage)); + *errMsg = StringToChars(env, msg, errMsgLen); + + jstring trace = NULL; + + if (c_PlatformUtils && m_PlatformUtils_getFullStackTrace) { + trace = static_cast(env->CallStaticObjectMethod(c_PlatformUtils, m_PlatformUtils_getFullStackTrace, err)); + *stackTrace = StringToChars(env, trace, stackTraceLen); + } + + if (errCls) + env->DeleteLocalRef(errCls); + + if (clsName) + env->DeleteLocalRef(clsName); + + if (msg) + env->DeleteLocalRef(msg); + + if (trace) + env->DeleteLocalRef(trace); + + return true; + } + else { + env->ExceptionClear(); + } + } + + return false; + } + + void JniMembers::Initialize(JNIEnv* env) { + c_DocumentDbConnectionProperties = FindClass(env, C_DOCUMENTDB_CONNECTION_PROPERTIES); + m_DocumentDbConnectionPropertiesGetPropertiesFromConnectionString = + FindMethod(env, c_DocumentDbConnectionProperties, M_DOCUMENTDB_CONNECTION_PROPERTIES_GET_PROPERTIES_FROM_CONNECTION_STRING); + + c_DocumentDbConnection = FindClass(env, C_DOCUMENTDB_CONNECTION); + //m_DocumentDbConnectionInit = FindMethod(env, c_DocumentDbConnection, M_DOCUMENTDB_CONNECTION_PROPERTIES_INIT); + + c_DriverManager = FindClass(env, C_DRIVERMANAGER); + m_DriverManagerGetConnection = FindMethod(env, c_DriverManager, M_DRIVERMANAGER_GET_CONNECTION); + + c_JavaSqlConnection = FindClass(env, C_JAVA_SQL_CONNECTION); + m_JavaSqlConnectionClose = FindMethod(env, c_JavaSqlConnection, M_JAVA_SQL_CONNECTION_CLOSE); + } + + void JniMembers::Destroy(JNIEnv* env) { + DeleteClass(env, c_IgniteException); + DeleteClass(env, c_PlatformIgnition); + DeleteClass(env, c_PlatformTarget); + DeleteClass(env, c_PlatformUtils); + } + + JniJvm::JniJvm() : jvm(NULL), javaMembers(JniJavaMembers()), members(JniMembers()) + { + // No-op. + } + + JniJvm::JniJvm(JavaVM* jvm, JniJavaMembers javaMembers, JniMembers members) : + jvm(jvm), javaMembers(javaMembers), members(members) + { + // No-op. + } + + JavaVM* JniJvm::GetJvm() + { + return jvm; + } + + JniJavaMembers& JniJvm::GetJavaMembers() + { + return javaMembers; + } + + JniMembers& JniJvm::GetMembers() + { + return members; + } + + /** + * Create JVM. + */ + jint GetOrCreateJvm(char** opts, int optsLen, JavaVM** jvm, JNIEnv** env) { + // Check to see if a VM is already created + const jsize nJvms = 1; + jsize nJvmsAvailable = 0; + JavaVM* availableJvms[nJvms]{}; + jint res = JNI_GetCreatedJavaVMs(&availableJvms[0], nJvms, + &nJvmsAvailable); + if (res == JNI_OK && nJvmsAvailable >= 1) { + *jvm = availableJvms[0]; + res = (*jvm)->GetEnv(reinterpret_cast< void** >(env), + JNI_VERSION_1_8); + if (res == JNI_OK) { + return res; + } + } + + // Otherwise, create a VM + JavaVMOption* opts0 = new JavaVMOption[optsLen]; + + for (int i = 0; i < optsLen; i++) + opts0[i].optionString = *(opts + i); + + JavaVMInitArgs args{}; + args.version = JNI_VERSION_1_8; + args.nOptions = optsLen; + args.options = opts0; + args.ignoreUnrecognized = 0; + + res = JNI_CreateJavaVM(jvm, reinterpret_cast(env), &args); + + delete[] opts0; + + return res; + } + + void RegisterNatives(JNIEnv* env) { + { + JNINativeMethod methods[5]; + + int idx = 0; + + // TODO: Investigate registering callbacks to get console and logging streams. + + //AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_CONSOLE_WRITE, reinterpret_cast(JniConsoleWrite)); + + //AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_LOGGER_LOG, reinterpret_cast(JniLoggerLog)); + //AddNativeMethod(methods + idx++, M_PLATFORM_CALLBACK_UTILS_LOGGER_IS_LEVEL_ENABLED, reinterpret_cast(JniLoggerIsLevelEnabled)); + + //jint res = env->RegisterNatives(FindClass(env, C_PLATFORM_CALLBACK_UTILS), methods, idx); + + //if (res != JNI_OK) + // throw JvmException(); + } + } + + JniContext::JniContext(JniJvm* jvm, JniHandlers hnds) : jvm(jvm), hnds(hnds) { + // No-op. + } + + JniContext* JniContext::Create(char** opts, int optsLen, JniHandlers hnds) { + return Create(opts, optsLen, hnds, NULL); + } + + void GetJniErrorMessage(std::string& errMsg, jint res) + { + switch (res) + { + case JNI_ERR: + errMsg = "Unknown error (JNI_ERR)."; + break; + + case JNI_EDETACHED: + errMsg = "Thread detached from the JVM."; + break; + + case JNI_EVERSION: + errMsg = "JNI version error."; + break; + + case JNI_ENOMEM: + errMsg = "Could not reserve enough space for object heap. Check Xmx option."; + break; + + case JNI_EEXIST: + errMsg = "JVM already created."; + break; + + case JNI_EINVAL: + errMsg = "Invalid JVM arguments."; + break; + + default: + errMsg = "Unexpected JNI_CreateJavaVM result."; + break; + } + } + + JniContext* JniContext::Create(char** opts, int optsLen, JniHandlers hnds, JniErrorInfo* errInfo) + { + // Acquire global lock to instantiate the JVM. + JVM_LOCK.Enter(); + + // Define local variables. + JavaVM* jvm = NULL; + JNIEnv* env = NULL; + + JniJavaMembers javaMembers; + memset(&javaMembers, 0, sizeof(javaMembers)); + + JniMembers members; + memset(&members, 0, sizeof(members)); + + JniContext* ctx = NULL; + + std::string errClsName; + int errClsNameLen = 0; + std::string errMsg; + int errMsgLen = 0; + std::string stackTrace; + int stackTraceLen = 0; + + try { + if (!JVM.GetJvm()) + { + // 1. Create JVM itself. + jint res = GetOrCreateJvm(opts, optsLen, &jvm, &env); + + if (res == JNI_OK) + { + // 2. Populate members; + javaMembers.Initialize(env); + members.Initialize(env); + + // 3. Register native functions. + RegisterNatives(env); + + // 4. Create JNI JVM. + JVM = JniJvm(jvm, javaMembers, members); + + char* printStack = getenv("IGNITE_CPP_PRINT_STACK"); + PRINT_EXCEPTION = printStack && strcmp("true", printStack) == 0; + } + else + { + GetJniErrorMessage(errMsg, res); + + errMsgLen = static_cast(errMsg.length()); + } + } + + if (JVM.GetJvm()) + ctx = new JniContext(&JVM, hnds); + } + catch (const JvmException&) + { + char* errClsNameChars = NULL; + char* errMsgChars = NULL; + char* stackTraceChars = NULL; + + // Read error info if possible. + javaMembers.WriteErrorInfo(env, &errClsNameChars, &errClsNameLen, &errMsgChars, &errMsgLen, + &stackTraceChars, &stackTraceLen); + + if (errClsNameChars) { + errClsName = errClsNameChars; + + delete[] errClsNameChars; + } + + if (errMsgChars) + { + errMsg = errMsgChars; + + delete[] errMsgChars; + } + + if (stackTraceChars) + { + stackTrace = stackTraceChars; + + delete[] stackTraceChars; + } + + // Destroy mmebers. + if (env) { + members.Destroy(env); + javaMembers.Destroy(env); + } + + // Destroy faulty JVM. + if (jvm) + jvm->DestroyJavaVM(); + } + + // It safe to release the lock at this point. + JVM_LOCK.Leave(); + + // Notify err callback if needed. + if (!ctx) { + if (errInfo) { + JniErrorInfo errInfo0(IGNITE_JNI_ERR_JVM_INIT, errClsName.c_str(), errMsg.c_str()); + + *errInfo = errInfo0; + } + + if (hnds.error) + hnds.error(hnds.target, IGNITE_JNI_ERR_JVM_INIT, errClsName.c_str(), errClsNameLen, + errMsg.c_str(), errMsgLen, stackTrace.c_str(), stackTraceLen, NULL, 0); + } + + return ctx; + } + + int JniContext::Reallocate(int64_t memPtr, int cap) { + JavaVM* jvm = JVM.GetJvm(); + + JNIEnv* env; + + int attachRes = jvm->AttachCurrentThread(reinterpret_cast(&env), NULL); + + if (attachRes == JNI_OK) + AttachHelper::OnThreadAttach(); + else + return -1; + + env->CallStaticVoidMethod(JVM.GetMembers().c_PlatformUtils, JVM.GetMembers().m_PlatformUtils_reallocate, memPtr, cap); + + if (env->ExceptionCheck()) { + env->ExceptionClear(); + + return -1; + } + + return 0; + } + + void JniContext::Detach() { + iocc::Memory::Fence(); + + if (JVM.GetJvm()) { + JNIEnv* env; + + JVM.GetJvm()->GetEnv(reinterpret_cast(&env), JNI_VERSION_1_6); + + if (env) + JVM.GetJvm()->DetachCurrentThread(); + } + } + + jobject JniContext::DocumentDbConnect(const char* connectionString, + JniErrorInfo* errInfo) { + JNIEnv* env = Attach(); + jstring jConnectionString = + env->NewStringUTF(connectionString); + jobject connection = env->CallStaticObjectMethod( + jvm->GetMembers().c_DriverManager, + jvm->GetMembers().m_DriverManagerGetConnection, jConnectionString); + ExceptionCheck(env, errInfo); + return connection; + } + + void JniContext::DocumentDbDisconnect(const jobject connection, JniErrorInfo* errInfo) { + if (!connection) { + return; + } + JNIEnv* env = Attach(); + env->CallVoidMethod(connection, jvm->GetMembers().m_JavaSqlConnectionClose); + ExceptionCheck(env, errInfo); + env->DeleteLocalRef(connection); + } + + int64_t JniContext::TargetInLongOutLong(jobject obj, int opType, int64_t val, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + int64_t res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformTarget_inLongOutLong, opType, val); + + ExceptionCheck(env, err); + + return res; + } + + int64_t JniContext::TargetInStreamOutLong(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + int64_t res = env->CallLongMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutLong, opType, memPtr); + + ExceptionCheck(env, err); + + return res; + } + + void JniContext::TargetInStreamOutStream(jobject obj, int opType, int64_t inMemPtr, int64_t outMemPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutStream, opType, inMemPtr, outMemPtr); + + ExceptionCheck(env, err); + } + + jobject JniContext::TargetInStreamOutObject(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, opType, memPtr); + + ExceptionCheck(env, err); + + return LocalToGlobal(env, res); + } + + jobject JniContext::TargetInObjectStreamOutObjectStream(jobject obj, int opType, void* arg, int64_t inMemPtr, int64_t outMemPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inObjectStreamOutObjectStream, opType, arg, inMemPtr, outMemPtr); + + ExceptionCheck(env, err); + + return LocalToGlobal(env, res); + } + + void JniContext::TargetOutStream(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_outStream, opType, memPtr); + + ExceptionCheck(env, err); + } + + jobject JniContext::TargetOutObject(jobject obj, int opType, JniErrorInfo* err) + { + JNIEnv* env = Attach(); + + jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_outObject, opType); + + ExceptionCheck(env, err); + + return LocalToGlobal(env, res); + } + + void JniContext::TargetInStreamAsync(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + env->CallVoidMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamAsync, opType, memPtr); + + ExceptionCheck(env, err); + } + + jobject JniContext::TargetInStreamOutObjectAsync(jobject obj, int opType, int64_t memPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + jobject res = env->CallObjectMethod(obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObjectAsync, opType, memPtr); + + ExceptionCheck(env, err); + + return LocalToGlobal(env, res); + } + + jobject JniContext::CacheOutOpQueryCursor(jobject obj, int type, int64_t memPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + jobject res = env->CallObjectMethod( + obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, type, memPtr); + + ExceptionCheck(env, err); + + return LocalToGlobal(env, res); + } + + jobject JniContext::CacheOutOpContinuousQuery(jobject obj, int type, int64_t memPtr, JniErrorInfo* err) { + JNIEnv* env = Attach(); + + jobject res = env->CallObjectMethod( + obj, jvm->GetMembers().m_PlatformTarget_inStreamOutObject, type, memPtr); + + ExceptionCheck(env, err); + + return LocalToGlobal(env, res); + } + + jobject JniContext::Acquire(jobject obj) + { + if (obj) { + + JNIEnv* env = Attach(); + + jobject obj0 = env->NewGlobalRef(obj); + + ExceptionCheck(env); + + return obj0; + } + + return NULL; + } + + void JniContext::Release(jobject obj) { + if (obj) + { + JavaVM* jvm = JVM.GetJvm(); + + if (jvm) + { + JNIEnv* env; + + jint attachRes = jvm->AttachCurrentThread(reinterpret_cast(&env), NULL); + + if (attachRes == JNI_OK) + { + AttachHelper::OnThreadAttach(); + + env->DeleteGlobalRef(obj); + } + } + } + } + + void JniContext::SetConsoleHandler(ConsoleWriteHandler consoleHandler) { + if (!consoleHandler) + throw std::invalid_argument("consoleHandler can not be null"); + + CONSOLE_LOCK.Enter(); + + consoleWriteHandlers.push_back(consoleHandler); + + CONSOLE_LOCK.Leave(); + } + + int JniContext::RemoveConsoleHandler(ConsoleWriteHandler consoleHandler) { + if (!consoleHandler) + throw std::invalid_argument("consoleHandler can not be null"); + + CONSOLE_LOCK.Enter(); + + int oldSize = static_cast(consoleWriteHandlers.size()); + + consoleWriteHandlers.erase(remove(consoleWriteHandlers.begin(), consoleWriteHandlers.end(), + consoleHandler), consoleWriteHandlers.end()); + + int removedCnt = oldSize - static_cast(consoleWriteHandlers.size()); + + CONSOLE_LOCK.Leave(); + + return removedCnt; + } + + void JniContext::ThrowToJava(char* msg) { + JNIEnv* env = Attach(); + + env->ThrowNew(jvm->GetMembers().c_IgniteException, msg); + } + + void JniContext::DestroyJvm() { + jvm->GetJvm()->DestroyJavaVM(); + } + + /** + * Attach thread to JVM. + */ + JNIEnv* JniContext::Attach() { + JNIEnv* env; + + jint attachRes = jvm->GetJvm()->AttachCurrentThread(reinterpret_cast(&env), NULL); + + if (attachRes == JNI_OK) + AttachHelper::OnThreadAttach(); + else { + if (hnds.error) + hnds.error(hnds.target, IGNITE_JNI_ERR_JVM_ATTACH, NULL, 0, NULL, 0, NULL, 0, NULL, 0); + } + + return env; + } + + void JniContext::ExceptionCheck(JNIEnv* env) { + ExceptionCheck(env, NULL); + } + + void JniContext::ExceptionCheck(JNIEnv* env, JniErrorInfo* errInfo) + { + if (env->ExceptionCheck()) { + jthrowable err = env->ExceptionOccurred(); + + if (PRINT_EXCEPTION) + env->CallVoidMethod(err, jvm->GetJavaMembers().m_Throwable_printStackTrace); + + env->ExceptionClear(); + + // Get error class name and message. + jclass cls = env->GetObjectClass(err); + + jstring clsName = static_cast(env->CallObjectMethod(cls, jvm->GetJavaMembers().m_Class_getName)); + jstring msg = static_cast(env->CallObjectMethod(err, jvm->GetJavaMembers().m_Throwable_getMessage)); + int traceLen = 0; + std::string trace0 = ""; + if (jvm->GetJavaMembers().c_PlatformUtils + && jvm->GetJavaMembers() + .m_PlatformUtils_getFullStackTrace) { + jstring trace = static_cast< jstring >( + env->CallStaticObjectMethod( + jvm->GetJavaMembers().c_PlatformUtils, + jvm->GetJavaMembers() + .m_PlatformUtils_getFullStackTrace, + err)); + + trace0 = + JavaStringToCString(env, trace, &traceLen); + } + + env->DeleteLocalRef(cls); + + int clsNameLen; + std::string clsName0 = JavaStringToCString(env, clsName, &clsNameLen); + + int msgLen; + std::string msg0 = JavaStringToCString(env, msg, &msgLen); + + if (errInfo) + { + JniErrorInfo errInfo0(IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), msg0.c_str()); + + *errInfo = errInfo0; + } + + // Get error additional data (if any). + jbyteArray errData = nullptr; + if (jvm->GetMembers().c_PlatformUtils + && jvm->GetMembers().m_PlatformUtils_errData) { + errData = static_cast< jbyteArray >( + env->CallStaticObjectMethod( + jvm->GetMembers().c_PlatformUtils, + jvm->GetMembers().m_PlatformUtils_errData, + err)); + } + + if (errData) + { + jbyte* errBytesNative = env->GetByteArrayElements(errData, NULL); + + int errBytesLen = env->GetArrayLength(errData); + + if (hnds.error) + hnds.error(hnds.target, IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), clsNameLen, msg0.c_str(), + msgLen, trace0.c_str(), traceLen, errBytesNative, errBytesLen); + + env->ReleaseByteArrayElements(errData, errBytesNative, JNI_ABORT); + } + else + { + if (hnds.error) + hnds.error(hnds.target, IGNITE_JNI_ERR_GENERIC, clsName0.c_str(), clsNameLen, msg0.c_str(), + msgLen, trace0.c_str(), traceLen, NULL, 0); + } + + env->DeleteLocalRef(err); + } + } + + /** + * Convert local reference to global. + */ + jobject JniContext::LocalToGlobal(JNIEnv* env, jobject localRef) { + if (localRef) { + jobject globalRef = env->NewGlobalRef(localRef); + + env->DeleteLocalRef(localRef); // Clear local ref irrespective of result. + + if (!globalRef) + ExceptionCheck(env); + + return globalRef; + } + else + return NULL; + } + + JNIEXPORT void JNICALL JniConsoleWrite(JNIEnv *env, jclass, jstring str, jboolean isErr) { + CONSOLE_LOCK.Enter(); + + if (consoleWriteHandlers.size() > 0) { + ConsoleWriteHandler consoleWrite = consoleWriteHandlers.at(0); + + const char* strChars = env->GetStringUTFChars(str, 0); + const int strCharsLen = env->GetStringUTFLength(str); + + consoleWrite(strChars, strCharsLen, isErr); + + env->ReleaseStringUTFChars(str, strChars); + } + + CONSOLE_LOCK.Leave(); + } + + JNIEXPORT void JNICALL JniLoggerLog(JNIEnv *env, jclass, jlong envPtr, jint level, jstring message, jstring category, jstring errorInfo, jlong memPtr) { + int messageLen; + char* messageChars = StringToChars(env, message, &messageLen); + + int categoryLen; + char* categoryChars = StringToChars(env, category, &categoryLen); + + int errorInfoLen; + char* errorInfoChars = StringToChars(env, errorInfo, &errorInfoLen); + + IGNITE_SAFE_PROC(env, envPtr, LoggerLogHandler, loggerLog, level, messageChars, messageLen, categoryChars, categoryLen, errorInfoChars, errorInfoLen, memPtr); + + if (messageChars) + delete[] messageChars; + + if (categoryChars) + delete[] categoryChars; + + if (errorInfoChars) + delete[] errorInfoChars; + } + + JNIEXPORT jboolean JNICALL JniLoggerIsLevelEnabled(JNIEnv *env, jclass, jlong envPtr, jint level) { + IGNITE_SAFE_FUNC(env, envPtr, LoggerIsLevelEnabledHandler, loggerIsLevelEnabled, level); + } + + JNIEXPORT jlong JNICALL JniInLongOutLong(JNIEnv *env, jclass, jlong envPtr, jint type, jlong val) { + IGNITE_SAFE_FUNC(env, envPtr, InLongOutLongHandler, inLongOutLong, type, val); + } + + JNIEXPORT jlong JNICALL JniInLongLongLongObjectOutLong(JNIEnv *env, jclass, jlong envPtr, jint type, jlong val1, jlong val2, jlong val3, jobject arg) { + IGNITE_SAFE_FUNC(env, envPtr, InLongLongLongObjectOutLongHandler, inLongLongLongObjectOutLong, type, val1, val2, val3, arg); + } + } // namespace java + } // namespace jni + } // namespace odbc +} // namespace ignite diff --git a/src/odbc/src/jni/os/linux/utils.cpp b/src/odbc/src/jni/os/linux/utils.cpp new file mode 100644 index 000000000..6fd4d6e7a --- /dev/null +++ b/src/odbc/src/jni/os/linux/utils.cpp @@ -0,0 +1,432 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include + +#include +#include +#include +#include +#include + +#include "ignite/common/utils.h" +#include "ignite/common/fixed_size_array.h" + +#include "ignite/odbc/jni/utils.h" +#include "ignite/odbc/jni/java.h" + +using namespace ignite::common; +using namespace ignite::odbc::jni::java; + +namespace ignite +{ + namespace odbc { + namespace jni { + const char* JAVA_HOME = "JAVA_HOME"; + const char* JAVA_DLL1 = "/jre/lib/amd64/server/libjvm.so"; + const char* JAVA_DLL2 = "/lib/server/libjvm.so"; + const char* JAVA_DLL_DARWIN = "libjvm.dylib"; + + const char* DOCUMENTDB_HOME = "DOCUMENTDB_HOME"; + + const char* IGNITE_NATIVE_TEST_CLASSPATH = "IGNITE_NATIVE_TEST_CLASSPATH"; + + /** Excluded modules from test classpath. */ + const char* TEST_EXCLUDED_MODULES[] = {"rest-http"}; + + /** Key indicating that the thread is attached. */ + static pthread_key_t attachKey; + + /** Helper to ensure that attach key is allocated only once. */ + static pthread_once_t attachKeyInit = PTHREAD_ONCE_INIT; + + void DestroyAttachKey(void* key) { + delete reinterpret_cast< AttachHelper* >(key); + } + + void AllocateAttachKey() { + pthread_key_create(&attachKey, DestroyAttachKey); + } + + AttachHelper::~AttachHelper() { + JniContext::Detach(); + } + + void AttachHelper::OnThreadAttach() { + pthread_once(&attachKeyInit, AllocateAttachKey); + + void* val = pthread_getspecific(attachKey); + + if (!val) + pthread_setspecific(attachKey, new AttachHelper()); + } + + /** + * Checks if the path looks like binary release home directory. + * Internally checks for presence of some directories, that are + * @return @c true if the path looks like binary release home directory. + */ + bool LooksLikeBinaryReleaseHome(const std::string& path) { + static const char* PROBE_CORE_LIB = "/libs/ignite-core*.jar"; + + std::string coreLibProbe = path + PROBE_CORE_LIB; + + return FileExists(coreLibProbe); + } + + /** + * Checks if the path looks like source release home directory. + * Internally checks for presence of core source directory. + * @return @c true if the path looks like binary release home directory. + */ + bool LooksLikeSourceReleaseHome(const std::string& path) { + static const char* PROBE_CORE_SOURCE = + "/modules/core/src/main/java/org/apache/ignite"; + + std::string coreSourcePath = path + PROBE_CORE_SOURCE; + + return IsValidDirectory(coreSourcePath); + } + + /** + * Helper function for Ignite home resolution. + * Goes upwards in directory hierarchy and checks whether certain + * folders exist in the path. + * + * @param path Path to evaluate. + * @return res Resolved directory. Empty string if not found. + */ + std::string ResolveIgniteHome0(const std::string& path) { + if (!IsValidDirectory(path)) + return std::string(); + + // Remove trailing slashes, otherwise we will have an infinite loop. + size_t last = path.find_last_not_of("/ "); + + if (last == std::string::npos) + return std::string(); + + std::string path0(path, 0, last + 1); + + if (LooksLikeBinaryReleaseHome(path0) || LooksLikeSourceReleaseHome(path0)) + return path0; + + // Evaluate parent directory. + size_t slashPos = path0.find_last_of("/"); + + if (slashPos == std::string::npos) + return std::string(); + + std::string parent(path0, 0, slashPos); + + return ResolveIgniteHome0(parent); + } + + /** + * Create classpath picking JARs from the given path. + * + * @path Path. + * @return Classpath; + */ + std::string ClasspathJars(const std::string& path) { + std::string res; + + DIR* dir = opendir(path.c_str()); + + if (dir) { + struct dirent* entry; + + while ((entry = readdir(dir)) != NULL) { + char* dot = strrchr(entry->d_name, '.'); + if (dot && !strcmp(dot, ".jar")) { + res.append(path); + res.append("/"); + res.append(entry->d_name); + res.append(":"); + } + } + + closedir(dir); + } + + return res; + } + + /** + * Check if path corresponds to excluded module. + * + * @path Path. + * @return True if path should be excluded. + */ + bool IsExcludedModule(const std::string& path) { + std::string lower_path = path; + std::transform(path.begin(), path.end(), lower_path.begin(), ::tolower); + + for (size_t i = 0; i < sizeof(TEST_EXCLUDED_MODULES) / sizeof(char*); i++) { + if (lower_path.find(TEST_EXCLUDED_MODULES[i]) != std::string::npos) + return true; + } + + return false; + } + + /** + * Create classpath picking compiled classes from the given path. + * + * @path Path. + * @return Classpath; + */ + std::string ClasspathExploded(const std::string& path, bool down) { + std::string res; + + if (FileExists(path) && !IsExcludedModule(path)) { + // 1. Append "target\classes". + std::string classesPath = path + "/target/classes"; + + if (FileExists(classesPath)) { + res += classesPath; + res += ":"; + } + + // 2. Append "target\test-classes" + std::string testClassesPath = path + "/target/test-classes"; + + if (FileExists(testClassesPath)) { + res += testClassesPath; + res += ":"; + } + + // 3. Append "target\libs" + std::string libsPath = path + "/target/libs"; + + if (FileExists(libsPath)) { + std::string libsCp = ClasspathJars(libsPath); + res += libsCp; + } + + // 4. Do the same for child if needed. + if (down) { + DIR* dir = opendir(path.c_str()); + + if (dir) { + struct dirent* entry; + + while ((entry = readdir(dir)) != NULL) { + std::string entryPath = entry->d_name; + + if (entryPath.compare(".") != 0 + && entryPath.compare("..") != 0) { + std::string entryFullPath = path + "/" + entryPath; + + struct stat entryFullStat; + + if (stat(entryFullPath.c_str(), &entryFullStat) != -1 + && S_ISDIR(entryFullStat.st_mode)) { + std::string childCp = + ClasspathExploded(entryFullPath, false); + + res += childCp; + } + } + } + + closedir(dir); + } + } + } + + return res; + } + + std::string CreateDocumentDbHomeClasspath(const std::string& home, bool forceTest) { + std::string res = std::string(); + + // 1. Add exploded test directories. + if (forceTest) { + std::string examplesPath = home + "/examples"; + std::string examplesCp = ClasspathExploded(examplesPath, true); + res.append(examplesCp); + + std::string modulesPath = home + "/modules"; + std::string modulesCp = ClasspathExploded(modulesPath, true); + res.append(modulesCp); + } + + // 2. Add regular jars from "libs" folder excluding "optional". + std::string libsPath = home + "/libs"; + + if (FileExists(libsPath)) { + res.append(ClasspathJars(libsPath)); + + // Append inner directories. + DIR* dir = opendir(libsPath.c_str()); + + if (dir) { + struct dirent* entry; + + while ((entry = readdir(dir)) != NULL) { + std::string entryPath = entry->d_name; + + if (entryPath.compare(".") != 0 && entryPath.compare("..") != 0 + && entryPath.compare("optional") != 0) { + std::string entryFullPath = libsPath; + + entryFullPath.append("/"); + entryFullPath.append(entryPath); + + struct stat entryFullStat; + + if (stat(entryFullPath.c_str(), &entryFullStat) != -1 + && S_ISDIR(entryFullStat.st_mode)) + res.append(ClasspathJars(entryFullPath)); + } + } + + closedir(dir); + } + } + + // 3. Return. + return res; + } + + std::string FindJvmLibrary(const std::string& path) { + #ifdef __APPLE__ + return JAVA_DLL_DARWIN; + #else + // If path is provided explicitly, then check only it. + if (!path.empty() && FileExists(path)) + return path; + + std::string javaEnv = GetEnv(JAVA_HOME); + + if (!javaEnv.empty()) { + std::string javaDll = javaEnv + JAVA_DLL1; + + if (FileExists(javaDll)) + return javaDll; + + javaDll = javaEnv + JAVA_DLL2; + + if (FileExists(javaDll)) + return javaDll; + } + + return std::string(); + #endif + } + + bool LoadJvmLibrary(const std::string& path) { + #ifdef __APPLE__ + return RTLD_DEFAULT; + #else + void* hnd = dlopen(path.c_str(), RTLD_LAZY); + + return hnd != NULL; + #endif + } + + /** + * Create Ignite classpath based on user input and home directory. + * + * @param usrCp User's classpath. + * @param home Ignite home directory. + * @param forceTest Whether test classpath must be used. + * @return Classpath. + */ + std::string CreateIgniteClasspath(const std::string& usrCp, + const std::string* home, bool forceTest) { + // 1. Append user classpath if it exists. + std::string cp; + + if (!usrCp.empty()) { + cp.append(usrCp); + + if (*cp.rbegin() != ';') + cp.push_back(';'); + } + + // 2. Append home classpath if home is defined. + if (home) { + std::string homeCp = CreateDocumentDbHomeClasspath(*home, forceTest); + + cp.append(homeCp); + } + + // 3. Return. + return cp; + } + + /** + * Adds semicolon at the end of the path if needed. + * @param usrCp Classpath provided by user. + * @return Normalized classpath. + */ + std::string NormalizeClasspath(const std::string& usrCp) { + if (usrCp.empty() || *usrCp.rbegin() == ';') + return usrCp; + + return usrCp + ';'; + } + + std::string CreateDocumentDbClasspath(const std::string& usrCp, + const std::string& home) { + // 1. Append user classpath if it exists. + std::string cp = NormalizeClasspath(usrCp); + + // 2. Append home classpath + if (!home.empty()) { + std::string env = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, "false"); + + bool forceTest = ToLower(env) == "true"; + + std::string homeCp = CreateDocumentDbHomeClasspath(home, forceTest); + + cp.append(homeCp); + } + + // 3. Return. + return cp; + } + + std::string ResolveDocumentDbHome(const std::string& path) { + // 1. Check passed argument. + if (IsValidDirectory(path)) + return path; + + // 2. Check environment variable. + std::string home = GetEnv(DOCUMENTDB_HOME); + + if (IsValidDirectory(home)) + return home; + + // 3. Check current work dir. + FixedSizeArray< char > curDir(1024 * 16); + + char* res = getcwd(curDir.GetData(), curDir.GetSize()); + + if (!res) + return std::string(); + + std::string curDirStr(curDir.GetData()); + + return ResolveIgniteHome0(curDirStr); + } + } // namespace jni + } // namespace odbc +} diff --git a/src/odbc/src/jni/os/win/utils.cpp b/src/odbc/src/jni/os/win/utils.cpp new file mode 100644 index 000000000..e41fb56af --- /dev/null +++ b/src/odbc/src/jni/os/win/utils.cpp @@ -0,0 +1,459 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "ignite/common/concurrent.h" +#include "ignite/common/utils.h" +#include "ignite/common/fixed_size_array.h" + +#include "ignite/odbc/jni/utils.h" +#include "ignite/odbc/jni/java.h" + +using namespace ignite::common; +using namespace ignite::common::concurrent; + +using namespace ignite::odbc::jni::java; + +namespace ignite +{ + namespace odbc + { + namespace jni + { + const char* JAVA_HOME = "JAVA_HOME"; + const char* JAVA_DLL1 = "\\jre\\bin\\server\\jvm.dll"; + const char* JAVA_DLL2 = "\\bin\\server\\jvm.dll"; + + const char* DOCUMENTDB_HOME = "DOCUMENTDB_HOME"; + + const char* IGNITE_NATIVE_TEST_CLASSPATH = "IGNITE_NATIVE_TEST_CLASSPATH"; + + /** Excluded modules from test classpath. */ + const char* TEST_EXCLUDED_MODULES[] = { "rest-http" }; + + AttachHelper::~AttachHelper() + { + // No-op. + } + + void AttachHelper::OnThreadAttach() + { + // No-op. + } + + /** + * Checks if the path looks like binary release home directory. + * Internally checks for presence of core library. + * @return @c true if the path looks like binary release home directory. + */ + bool LooksLikeBinaryReleaseHome(const std::string& path) + { + static const char* PROBE_CORE_LIB = "\\libs\\ignite-core*.jar"; + + std::string coreLibProbe = path + PROBE_CORE_LIB; + + return FileExists(coreLibProbe); + } + + /** + * Checks if the path looks like source release home directory. + * Internally checks for presence of core source directory. + * @return @c true if the path looks like binary release home directory. + */ + bool LooksLikeSourceReleaseHome(const std::string& path) + { + static const char* PROBE_CORE_SOURCE = "\\modules\\core\\src\\main\\java\\org\\apache\\ignite"; + + std::string coreSourcePath = path + PROBE_CORE_SOURCE; + + return IsValidDirectory(coreSourcePath); + } + + /** + * Helper function for Ignite home resolution. + * Goes upwards in directory hierarchy and checks whether certain + * folders exist in the path. + * + * @param path Path to evaluate. + * @return res Resolved directory. Empty string if not found. + */ + std::string ResolveIgniteHome0(const std::string& path) + { + if (!IsValidDirectory(path)) + return std::string(); + + // Remove trailing slashes, otherwise we will have an infinite loop. + size_t last = path.find_last_not_of("/\\ "); + + if (last == std::string::npos) + return std::string(); + + std::string path0(path, 0, last + 1); + + if (LooksLikeBinaryReleaseHome(path0) || LooksLikeSourceReleaseHome(path0)) + return path0; + + // Evaluate parent directory. + size_t slashPos = path0.find_last_of("/\\"); + + if (slashPos == std::string::npos) + return std::string(); + + std::string parent(path0, 0, slashPos); + + return ResolveIgniteHome0(parent); + } + + /** + * Create classpath picking JARs from the given path. + * + * @path Path. + * @return Classpath; + */ + std::string ClasspathJars(const std::string& path) + { + std::string searchPath = path + "\\*.jar"; + + WIN32_FIND_DATAA findData; + + HANDLE hnd = FindFirstFileA(searchPath.c_str(), &findData); + + if (hnd == INVALID_HANDLE_VALUE) + return std::string(); + + std::string res; + + do + { + res.append(path); + res.append("\\"); + res.append(findData.cFileName); + res.append(";"); + } while (FindNextFileA(hnd, &findData) != 0); + + FindClose(hnd); + + return res; + } + + /** + * Check if path corresponds to excluded module. + * + * @path Path. + * @return True if path should be excluded. + */ + bool IsExcludedModule(const std::string& path) { + std::string lower_path = path; + std::transform(path.begin(), path.end(), lower_path.begin(), ::tolower); + + for (size_t i = 0; i < sizeof(TEST_EXCLUDED_MODULES) / sizeof(char*); i++) { + if (lower_path.find(TEST_EXCLUDED_MODULES[i]) != std::string::npos) + return true; + } + + return false; + } + + /** + * Create classpath picking compiled classes from the given path. + * + * @path Path. + * @return Classpath; + */ + std::string ClasspathExploded(const std::string& path, bool down) + { + std::string res; + + if (FileExists(path) && !IsExcludedModule(path)) + { + // 1. Append "target\classes". + std::string classesPath = path + "\\target\\classes"; + + if (FileExists(classesPath)) { + res.append(classesPath); + res.append(";"); + } + + // 2. Append "target\test-classes" + std::string testClassesPath = path + "\\target\\test-classes"; + + if (FileExists(testClassesPath)) { + res.append(testClassesPath); + res.append(";"); + } + + // 3. Append "target\libs" + std::string libsPath = path + "\\target\\libs"; + + if (FileExists(libsPath)) { + std::string libsCp = ClasspathJars(libsPath); + res.append(libsCp); + } + + // 4. Do the same for child if needed. + if (down) + { + std::string searchPath = path + "\\*"; + + WIN32_FIND_DATAA findData; + + HANDLE hnd = FindFirstFileA(searchPath.c_str(), &findData); + + if (hnd != INVALID_HANDLE_VALUE) + { + do + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + std::string childPath = findData.cFileName; + + if (childPath.compare(".") != 0 && + childPath.compare("..") != 0) + { + std::string childCp = + ClasspathExploded(path + "\\" + childPath, false); + + res.append(childCp); + } + } + } while (FindNextFileA(hnd, &findData) != 0); + + FindClose(hnd); + } + } + } + + return res; + } + + std::string CreateDocumentDbHomeClasspath(const std::string& home, bool forceTest) + { + std::string res; + + // 1. Add exploded test directories. + if (forceTest) + { + std::string examplesPath = home + "\\examples"; + std::string examplesCp = ClasspathExploded(examplesPath, true); + res.append(examplesCp); + + std::string modulesPath = home + "\\modules"; + std::string modulesCp = ClasspathExploded(modulesPath, true); + res.append(modulesCp); + } + + // 2. Add regular jars from "libs" folder excluding "optional". + std::string libsPath = home + "\\libs"; + + if (FileExists(libsPath)) + { + res.append(ClasspathJars(libsPath)); + + // Append inner directories. + std::string libsSearchPath = libsPath + "\\*"; + + WIN32_FIND_DATAA libsFindData; + + HANDLE libsHnd = FindFirstFileA(libsSearchPath.c_str(), &libsFindData); + + if (libsHnd != INVALID_HANDLE_VALUE) + { + do + { + if (libsFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + std::string libsChildPath = libsFindData.cFileName; + + if (libsChildPath.compare(".") != 0 && + libsChildPath.compare("..") != 0 && + libsChildPath.compare("optional") != 0) { + std::string libsFolder = libsPath + "\\" + libsChildPath; + + res.append(ClasspathJars(libsFolder)); + } + } + } while (FindNextFileA(libsHnd, &libsFindData) != 0); + + FindClose(libsHnd); + } + } + + // 3. Return. + return res; + } + + std::string FindJvmLibrary(const std::string& path) + { + // If path is provided explicitly, then check only it. + if (!path.empty() && FileExists(path)) + return path; + + std::string javaEnv = GetEnv(JAVA_HOME); + + if (!javaEnv.empty()) + { + std::string javaDll = javaEnv + JAVA_DLL1; + + if (FileExists(javaDll)) + return javaDll; + + javaDll = javaEnv + JAVA_DLL2; + + if (FileExists(javaDll)) + return javaDll; + } + + return std::string(); + } + + bool LoadJvmLibrary(const std::string& path) + { + HMODULE mod = LoadLibraryA(path.c_str()); + + return mod != NULL; + } + + /** + * Create Ignite classpath based on user input and home directory. + * + * @param usrCp User's classpath. + * @param home Ignite home directory. + * @param forceTest Whether test classpath must be used. + * @return Classpath. + */ + std::string CreateIgniteClasspath(const std::string& usrCp, const std::string* home, bool forceTest) + { + // 1. Append user classpath if it exists. + std::string cp; + + if (!usrCp.empty()) + { + cp.append(usrCp); + + if (*cp.rbegin() != ';') + cp.push_back(';'); + } + + // 2. Append home classpath if home is defined. + if (home) + { + std::string homeCp = CreateDocumentDbHomeClasspath(*home, forceTest); + + cp.append(homeCp); + } + + // 3. Return. + return cp; + } + + /** + * Adds semicolon at the end of the path if needed. + * @param usrCp Classpath provided by user. + * @return Normalized classpath. + */ + std::string NormalizeClasspath(const std::string& usrCp) + { + if (usrCp.empty() || *usrCp.rbegin() == ';') + return usrCp; + + return usrCp + ';'; + } + + std::string CreateDocumentDbClasspath(const std::string& usrCp, const std::string& home) + { + // 1. Append user classpath if it exists. + std::string cp = NormalizeClasspath(usrCp); + + // 2. Append home classpath + if (!home.empty()) + { + std::string env = GetEnv(IGNITE_NATIVE_TEST_CLASSPATH, "false"); + + bool forceTest = ToLower(env) == "true"; + + std::string homeCp = CreateDocumentDbHomeClasspath(home, forceTest); + + cp.append(homeCp); + } + + // 3. Return. + return cp; + } + + std::string ResolveDocumentDbHome(const std::string& path) + { + // 1. Check passed argument. + if (IsValidDirectory(path)) + return path; + + // 2. Check environment variable. + std::string home = GetEnv(DOCUMENTDB_HOME); + + if (IsValidDirectory(home)) + return home; + + // 3. Check current work dir. + DWORD curDirLen = GetCurrentDirectoryA(0, NULL); + + if (!curDirLen) + return std::string(); + + FixedSizeArray curDir(curDirLen); + + curDirLen = GetCurrentDirectoryA(curDir.GetSize(), curDir.GetData()); + + if (!curDirLen) + return std::string(); + + std::string curDirStr(curDir.GetData()); + + return ResolveIgniteHome0(curDirStr); + } + } // jni + } // odbc +} // ignite + +BOOL WINAPI DllMain(_In_ HINSTANCE hinstDLL, _In_ DWORD fdwReason, _In_ LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + if (!ThreadLocal::OnProcessAttach()) + return FALSE; + + break; + + case DLL_THREAD_DETACH: + ThreadLocal::OnThreadDetach(); + + JniContext::Detach(); + + break; + + case DLL_PROCESS_DETACH: + ThreadLocal::OnProcessDetach(); + + break; + + default: + break; + } + + return TRUE; +} \ No newline at end of file diff --git a/src/odbc/src/log.cpp b/src/odbc/src/log.cpp index 755798f48..80f0b8b88 100644 --- a/src/odbc/src/log.cpp +++ b/src/odbc/src/log.cpp @@ -67,7 +67,7 @@ namespace ignite { if (IsEnabled()) { - ignite::common::concurrent::CsLockGuard guard(mutex); + common::concurrent::CsLockGuard guard(mutex); stream << message << std::endl; } } diff --git a/src/odbc/src/protocol_version.cpp b/src/odbc/src/protocol_version.cpp index a073ab26c..f196b33e7 100644 --- a/src/odbc/src/protocol_version.cpp +++ b/src/odbc/src/protocol_version.cpp @@ -17,7 +17,7 @@ #include -#include +#include #include "ignite/odbc/protocol_version.h" #include "ignite/odbc/utility.h" diff --git a/src/odbc/src/ssl_mode.cpp b/src/odbc/src/ssl_mode.cpp index 70fd05891..0f5aba861 100644 --- a/src/odbc/src/ssl_mode.cpp +++ b/src/odbc/src/ssl_mode.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -#include +#include #include "ignite/odbc/ssl_mode.h" diff --git a/src/odbc/src/utility.cpp b/src/odbc/src/utility.cpp index c060a0ada..8ac9221f7 100644 --- a/src/odbc/src/utility.cpp +++ b/src/odbc/src/utility.cpp @@ -67,7 +67,7 @@ namespace ignite writer.WriteString(str.data(), static_cast(str.size())); } - void ReadDecimal(ignite::impl::binary::BinaryReaderImpl& reader, common::Decimal& decimal) + void ReadDecimal(ignite::impl::binary::BinaryReaderImpl& reader, odbc::common::Decimal& decimal) { int8_t hdr = reader.ReadInt8(); @@ -94,20 +94,20 @@ namespace ignite sign = -1; } - common::Decimal res(mag.data(), static_cast(mag.size()), scale, sign); + odbc::common::Decimal res(mag.data(), static_cast(mag.size()), scale, sign); decimal.Swap(res); } - void WriteDecimal(ignite::impl::binary::BinaryWriterImpl& writer, const common::Decimal& decimal) + void WriteDecimal(ignite::impl::binary::BinaryWriterImpl& writer, const odbc::common::Decimal& decimal) { writer.WriteInt8(ignite::impl::binary::IGNITE_TYPE_DECIMAL); - const common::BigInteger &unscaled = decimal.GetUnscaledValue(); + const odbc::common::BigInteger &unscaled = decimal.GetUnscaledValue(); writer.WriteInt32(decimal.GetScale()); - common::FixedSizeArray magnitude; + odbc::common::FixedSizeArray magnitude; unscaled.MagnitudeToBytes(magnitude); From e9ed8f533dd9acaafb0447428cad7f7ca4ec00db Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 27 Jan 2022 12:04:09 -0800 Subject: [PATCH 089/100] [AD-522] resolve errors after merging develop branch * GetAddresses() is deprecated, replaced it with GetHostname() and GetTcpPort() to get hostname and port number, respectively. * replaced GetSchema() with GetSchemaName() * removed commented out code * refactor with dsn_configuration_window.cpp --- .../system/ui/dsn_configuration_window.cpp | 4 +- src/odbc/src/connection.cpp | 48 ++----------------- 2 files changed, 5 insertions(+), 47 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 06b77c3b3..ec6086aa6 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -221,7 +221,7 @@ namespace ignite int DsnConfigurationWindow::CreateSshSettingsGroup(int posX, int posY, int sizeX) { - enum { LABEL_WIDTH = 120 }; + enum { LABEL_WIDTH = 120 }; int labelPosX = posX + INTERVAL; @@ -417,8 +417,6 @@ namespace ignite int DsnConfigurationWindow::CreateAdditionalSettingsGroup(int posX, int posY, int sizeX) { enum { LABEL_WIDTH = 120 }; // same as SSH settings - //enum { LABEL_WIDTH = 130 }; // -AL- different definition from above. I can also - // change it to the same int labelPosX = posX + INTERVAL; diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index 4bdc511f7..8367669e0 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -522,24 +522,6 @@ namespace ignite SqlResult::Type Connection::MakeRequestHandshake() { - /* ProtocolVersion protocolVersion = config.GetProtocolVersion(); - - if (!protocolVersion.IsSupported()) - { - AddStatusRecord(SqlState::S01S00_INVALID_CONNECTION_STRING_ATTRIBUTE, - "Protocol version is not supported: " + protocolVersion.ToString()); - - return SqlResult::AI_ERROR; - } - - if (protocolVersion < ProtocolVersion::VERSION_2_5_0 && !config.GetUser().empty()) - { - AddStatusRecord(SqlState::S01S00_INVALID_CONNECTION_STRING_ATTRIBUTE, - "Authentication is not allowed for protocol version below 2.5.0"); - - return SqlResult::AI_ERROR; - } - */ HandshakeRequest req(config); HandshakeResponse rsp; @@ -582,13 +564,6 @@ namespace ignite if (!rsp.GetError().empty()) constructor << "Additional info: " << rsp.GetError() << " "; - /* constructor - << "Current version of the protocol, used by the server " - "node is " - << rsp.GetCurrentVer().ToString() << ", " - << "driver protocol version introduced in version " - << protocolVersion.ToString() << "."; */ - AddStatusRecord(SqlState::S08004_CONNECTION_REJECTED, constructor.str()); return SqlResult::AI_ERROR; @@ -667,9 +642,9 @@ namespace ignite std::string Connection::FormatJdbcConnectionString() const { std::string host = "localhost"; std::string port = "27017"; - if (!config.GetAddresses().empty()) { - host = config.GetAddresses()[0].host; - port = std::to_string(config.GetAddresses()[0].port); + if (!config.GetHostname().empty()) { + host = config.GetHostname(); + port = std::to_string(config.GetTcpPort()); } std::string jdbConnectionString; @@ -678,7 +653,7 @@ namespace ignite jdbConnectionString.append(":" + config.GetPassword()); jdbConnectionString.append("@" + host); jdbConnectionString.append(":" + port); - jdbConnectionString.append("/" + config.GetSchema()); + jdbConnectionString.append("/" + config.GetSchemaName()); jdbConnectionString.append("?tlsAllowInvalidHostnames=true"); // Check if internal SSH tunnel should be enabled. @@ -778,21 +753,6 @@ namespace ignite LOG_MSG("'Address' is not set. Using legacy connection method."); endPoints.push_back(EndPoint(cfg.GetHostname(), cfg.GetTcpPort())); return; - - /*if (!cfg.IsAddressesSet()) - { - LOG_MSG("'Address' is not set. Using legacy connection method."); - - endPoints.push_back(EndPoint(cfg.GetHostname(), cfg.GetTcpPort())); - - return; - } - - endPoints = cfg.GetAddresses(); - - - std::random_shuffle(endPoints.begin(), endPoints.end()); - */ } int32_t Connection::RetrieveTimeout(void* value) From 4fa885174a501a4a674e60d781f5995e27ee798c Mon Sep 17 00:00:00 2001 From: Bruce Irschick Date: Thu, 27 Jan 2022 13:32:28 -0800 Subject: [PATCH 090/100] [AD-512] Resolve issue with missing include file. --- src/odbc/include/ignite/odbc/connection.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/odbc/include/ignite/odbc/connection.h b/src/odbc/include/ignite/odbc/connection.h index 0a917a50d..f5175f04a 100644 --- a/src/odbc/include/ignite/odbc/connection.h +++ b/src/odbc/include/ignite/odbc/connection.h @@ -28,6 +28,7 @@ #include "ignite/odbc/config/connection_info.h" #include "ignite/odbc/config/configuration.h" #include "ignite/odbc/diagnostic/diagnosable_adapter.h" +#include "ignite/odbc/end_point.h" #include "ignite/odbc/streaming/streaming_context.h" #include "ignite/odbc/odbc_error.h" #include "ignite/odbc/jni/java.h" @@ -511,7 +512,7 @@ namespace ignite * @param cfg Configuration. * @param endPoints End points. */ - static void CollectAddresses(const config::Configuration& cfg, std::vector& endPoints); + static void CollectAddresses(const config::Configuration& cfg, std::vector< EndPoint >& endPoints); /** * Retrieve timeout from parameter. From 66333de102af2d3d6724f400d3cba71ff2dc6a75 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 27 Jan 2022 15:32:57 -0800 Subject: [PATCH 091/100] [AD-522] make BoolParseResult recognizable --- src/odbc/include/ignite/odbc/config/connection_string_parser.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index eb0d1fede..41b115af0 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -183,7 +183,7 @@ namespace ignite */ struct BoolParseResult { - enum class Type + enum Type { AI_FALSE, From 9e639d1c4c5b4950d43b9e726cae454d826adc8d Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 27 Jan 2022 15:35:52 -0800 Subject: [PATCH 092/100] [AD-522] fix build errors after develop branch merge * update schema checkbox string * make edit row height single * update SetTcpPort to SetPort etc * define default value for sshEnable --- .../include/ignite/odbc/config/configuration.h | 2 +- .../win/src/system/ui/dsn_configuration_window.cpp | 14 ++++++-------- src/odbc/src/connection.cpp | 1 - 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/configuration.h b/src/odbc/include/ignite/odbc/config/configuration.h index 605820a8c..640e89388 100644 --- a/src/odbc/include/ignite/odbc/config/configuration.h +++ b/src/odbc/include/ignite/odbc/config/configuration.h @@ -775,7 +775,7 @@ namespace ignite SettableValue tlsCaFile = DefaultValue::tlsCaFile; /** The SSH enable option for the internal SSH tunnel. */ - SettableValue sshEnable; + SettableValue sshEnable = DefaultValue::sshEnable; /** The SSH host username for the internal SSH tunnel. */ SettableValue sshUser = DefaultValue::sshUser; diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index ec6086aa6..2f35dbdef 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -50,7 +50,6 @@ namespace ignite schemaLabel(), schemaEdit(), refreshSchemaCheckBox(), - // internal SSH tunnel vars sshEnableCheckBox(), sshUserLabel(), sshUserEdit(), @@ -63,7 +62,6 @@ namespace ignite sshStrictHostKeyCheckingCheckBox(), sshKnownHostsFileLabel(), sshKnownHostsFileEdit(), - // end of SSH vars appNameLabel(), appNameEdit(), readPreferenceLabel(), @@ -179,7 +177,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - std::string tmp = common::LexicalCast(config.GetTcpPort()); + std::string tmp = common::LexicalCast(config.GetPort()); val = tmp.c_str(); portLabel = CreateLabel( labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, @@ -263,9 +261,9 @@ namespace ignite val = config.GetSshPrivateKeyPassphrase().c_str(); // ssh private key passphrase label requires double the row height due to the long label. sshPrivateKeyPassphraseLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT * 2, - "SSH Private Key Passphrase:", ChildId::SSH_PRIVATE_KEY_PASSPHRASE_LABEL); + "SSH Private Key File Passphrase:", ChildId::SSH_PRIVATE_KEY_PASSPHRASE_LABEL); sshPrivateKeyPassphraseEdit = CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT * 2, val, ChildId::SSH_PRIVATE_KEY_PASSPHRASE_EDIT); + ROW_HEIGHT, val, ChildId::SSH_PRIVATE_KEY_PASSPHRASE_EDIT); rowPos += INTERVAL + ROW_HEIGHT * 2; @@ -394,7 +392,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; refreshSchemaCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Refresh Schema", ChildId::REFRESH_SCHEMA_CHECK_BOX, config.IsRefreshSchema()); + "Refresh Schema (Caution: use only when necessary to update schema)", ChildId::REFRESH_SCHEMA_CHECK_BOX, config.IsRefreshSchema()); rowPos += INTERVAL + ROW_HEIGHT; @@ -693,7 +691,7 @@ namespace ignite int16_t port = common::LexicalCast< int16_t >(portStr); if (port <= 0) - port = config.GetTcpPort(); + port = config.GetPort(); LOG_MSG("Retrieving arguments:"); LOG_MSG("DSN: " << dsnStr); @@ -704,7 +702,7 @@ namespace ignite // username and password intentionally not logged for security reasons cfg.SetDsn(dsnStr); - cfg.SetTcpPort(port); + cfg.SetPort(port); cfg.SetHostname(hostnameStr); cfg.SetDatabase(databaseStr); cfg.SetUser(userStr); diff --git a/src/odbc/src/connection.cpp b/src/odbc/src/connection.cpp index 8586df08c..db1a0fec2 100644 --- a/src/odbc/src/connection.cpp +++ b/src/odbc/src/connection.cpp @@ -27,7 +27,6 @@ #include "ignite/odbc/log.h" #include "ignite/odbc/utility.h" #include "ignite/odbc/environment.h" -#include "ignite/odbc/end_point.h" #include "ignite/odbc/statement.h" #include "ignite/odbc/connection.h" #include "ignite/odbc/message.h" From d27b4918a3869b044d8881fe29c83ae3c516b21a Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Fri, 28 Jan 2022 11:50:15 -0800 Subject: [PATCH 093/100] [AD-522] enable encrypt password for ssh private key passphrase * modify refresh schema checkbox string to fit better * remove log message for ssh private key passphrase to increase security --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 2f35dbdef..69fa90482 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -263,7 +263,7 @@ namespace ignite sshPrivateKeyPassphraseLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT * 2, "SSH Private Key File Passphrase:", ChildId::SSH_PRIVATE_KEY_PASSPHRASE_LABEL); sshPrivateKeyPassphraseEdit = CreateEdit(editPosX, rowPos, editSizeX, - ROW_HEIGHT, val, ChildId::SSH_PRIVATE_KEY_PASSPHRASE_EDIT); + ROW_HEIGHT, val, ChildId::SSH_PRIVATE_KEY_PASSPHRASE_EDIT, ES_PASSWORD); rowPos += INTERVAL + ROW_HEIGHT * 2; @@ -392,7 +392,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; refreshSchemaCheckBox = CreateCheckBox(labelPosX, rowPos, checkBoxSize, ROW_HEIGHT, - "Refresh Schema (Caution: use only when necessary to update schema)", ChildId::REFRESH_SCHEMA_CHECK_BOX, config.IsRefreshSchema()); + "Refresh Schema (Caution: use temporarily to update schema)", ChildId::REFRESH_SCHEMA_CHECK_BOX, config.IsRefreshSchema()); rowPos += INTERVAL + ROW_HEIGHT; @@ -731,7 +731,6 @@ namespace ignite LOG_MSG("SSH user: " << sshUserStr); LOG_MSG("SSH host: " << sshHostStr); LOG_MSG("SSH private key file: " << sshPrivateKeyFileStr); - LOG_MSG("SSH private key passphrase: " << sshPrivateKeyPassphraseStr); LOG_MSG("SSH strict host key checking: " << (sshStrictHostKeyChecking ? "true" : "false")); LOG_MSG("SSH known hosts file: " << sshKnownHostsFileStr); From 48405a3d678d34f5866d710f8bb6efaea895f7d2 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Fri, 28 Jan 2022 14:26:17 -0800 Subject: [PATCH 094/100] [AD-509] update readMe to include directions about saving Java bin and server directories. * reason: ODBC JNI calls have a dependency on `jvm.dll`, as a result, the ODBC driver cannot operate properly unless the Java bin and server directories are included in the path. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cb1308e83..06f382dad 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ 1. Ensure to add path to WiX executables (e.g. `C:\Program Files (x86)\WiX Toolset v3.11\bin`) 4. Java **JDK** (version 8+ - 17 recommended) 1. Ensure to set `JAVA_HOME`. + 2. Ensure to save Java `\bin` and `\server` directories to the User `PATH` variable. 5. Boost Test Framework 1. Install via [VCPKG](https://vcpkg.io/en/getting-started.html) using `.\vcpkg install openssl:x64-windows boost-test:x64-windows boost-asio:x64-windows boost-chrono:x64-windows boost-interprocess:x64-windows boost-regex:x64-windows boost-system:x64-windows boost-thread:x64-windows` 6. Run one of the build scripts to create an initial compilation. @@ -37,7 +38,8 @@ 4. `brew install boost` 5. Install Java **JDK** (version 8+ - 17 recommended) - This can be done through Homebrew using `brew install --cask temurin`. - - Ensure to set `JAVA_HOME`. + - Ensure to set `JAVA_HOME`. + - Ensure to save Java `/bin` and `/server` directories to the User `PATH` variable. 6. If creating a debug build (`./build_mac_debug64.sh`), LLVM is required. - If you only have XCode Command Line Tools, use the LLVM included with XCode by modifying the PATH with `export PATH=/Library/Developer/CommandLineTools/usr/bin/:$PATH`. Ensure this XCode path comes first in $PATH. If error occurs, check that clang and llvm are under folder Library/Developer/CommandLineTools/usr/bin. - If you have XCode application, to ensure LLVM and CMake are compatible, use the LLVM included with XCode by modifying the PATH with `export PATH=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/:$PATH`. From a663492f9dd8c24834b7bf9da6a5efc867524340 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Fri, 28 Jan 2022 14:43:30 -0800 Subject: [PATCH 095/100] [AD-522] reduce space between ssh private key passphrase and the checkbox below --- src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 69fa90482..764e012c2 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -265,7 +265,7 @@ namespace ignite sshPrivateKeyPassphraseEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SSH_PRIVATE_KEY_PASSPHRASE_EDIT, ES_PASSWORD); - rowPos += INTERVAL + ROW_HEIGHT * 2; + rowPos += INTERVAL + ROW_HEIGHT; // SSH Strict Host Key Check check box needs to have editSizeX as size because the string is long sshStrictHostKeyCheckingCheckBox = CreateCheckBox( From d41e02713bca7a86f35ef999d72d54c1a282a985 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Mon, 31 Jan 2022 11:00:42 -0800 Subject: [PATCH 096/100] [AD-521] integrate code review feedback from Andie * refactors with comment changes and log changes --- .../os/win/src/system/ui/dsn_configuration_window.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 764e012c2..4092e36b4 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -34,7 +34,7 @@ namespace ignite namespace ui { DsnConfigurationWindow::DsnConfigurationWindow(Window* parent, config::Configuration& config): - CustomWindow(parent, "IgniteConfigureDsn", "Configure Amazon DocumentDB DSN Latest"), + CustomWindow(parent, "IgniteConfigureDsn", "Configure Amazon DocumentDB DSN"), width(730), height(515), connectionSettingsGroupBox(), @@ -546,7 +546,7 @@ namespace ignite case ChildId::USER_EDIT: case ChildId::PASSWORD_EDIT: { - // if window has been created. Check + // Check if window has been created. if (created) { okButton->SetEnabled( nameEdit->HasText() @@ -752,8 +752,8 @@ namespace ignite tlsCaFileEdit->GetText(tlsCaStr); LOG_MSG("TLS/SSL Encryption: " << (tls ? "true" : "false")); - LOG_MSG("tls Allow Invalid Hostnames: " << (tlsAllowInvalidHostnames ? "true" : "false")); - LOG_MSG("TLS CA (Certificate Authority) File name: " << tlsCaStr); + LOG_MSG("TLS Allow Invalid Hostnames: " << (tlsAllowInvalidHostnames ? "true" : "false")); + LOG_MSG("TLS CA (Certificate Authority) File: " << tlsCaStr); cfg.SetTls(tls); cfg.SetTlsAllowInvalidHostnames(tlsAllowInvalidHostnames); From 2355e5c60e367d8d456d49dc9d28fc069bf09d2e Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 1 Feb 2022 11:43:43 -0800 Subject: [PATCH 097/100] [AD-522] remove space and add new line at the end of enum types --- src/odbc/include/ignite/odbc/read_preference.h | 11 +++-------- src/odbc/include/ignite/odbc/scan_method.h | 10 +++------- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/odbc/include/ignite/odbc/read_preference.h b/src/odbc/include/ignite/odbc/read_preference.h index 5053c3ba5..b355335ac 100644 --- a/src/odbc/include/ignite/odbc/read_preference.h +++ b/src/odbc/include/ignite/odbc/read_preference.h @@ -29,15 +29,10 @@ namespace ignite enum Type { PRIMARY, - PRIMARY_PREFERRED, - - SECONDARY, - + SECONDARY, SECONDARY_PREFERRED, - - NEAREST, - + NEAREST, UNKNOWN }; @@ -62,4 +57,4 @@ namespace ignite } } -#endif //_IGNITE_ODBC_READ_PREFERENCE \ No newline at end of file +#endif //_IGNITE_ODBC_READ_PREFERENCE diff --git a/src/odbc/include/ignite/odbc/scan_method.h b/src/odbc/include/ignite/odbc/scan_method.h index 0260fba6a..d81df80ff 100644 --- a/src/odbc/include/ignite/odbc/scan_method.h +++ b/src/odbc/include/ignite/odbc/scan_method.h @@ -29,13 +29,9 @@ namespace ignite enum Type { RANDOM, - ID_FORWARD, - - ID_REVERSE, - - ALL, - + ID_REVERSE, + ALL, UNKNOWN }; @@ -59,4 +55,4 @@ namespace ignite }; } } // namespace ignite -#endif //_IGNITE_ODBC_SCAN_METHOD \ No newline at end of file +#endif //_IGNITE_ODBC_SCAN_METHOD From 55132cf8e0f46bcd78bb13583152f6db2f8c3e1d Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Tue, 1 Feb 2022 11:45:52 -0800 Subject: [PATCH 098/100] [AD-522] add new lines at the end of Enum type files --- src/odbc/include/ignite/odbc/read_preference.h | 1 + src/odbc/include/ignite/odbc/scan_method.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/odbc/include/ignite/odbc/read_preference.h b/src/odbc/include/ignite/odbc/read_preference.h index b355335ac..a05916eab 100644 --- a/src/odbc/include/ignite/odbc/read_preference.h +++ b/src/odbc/include/ignite/odbc/read_preference.h @@ -58,3 +58,4 @@ namespace ignite } #endif //_IGNITE_ODBC_READ_PREFERENCE + diff --git a/src/odbc/include/ignite/odbc/scan_method.h b/src/odbc/include/ignite/odbc/scan_method.h index d81df80ff..70b24b835 100644 --- a/src/odbc/include/ignite/odbc/scan_method.h +++ b/src/odbc/include/ignite/odbc/scan_method.h @@ -56,3 +56,4 @@ namespace ignite } } // namespace ignite #endif //_IGNITE_ODBC_SCAN_METHOD + From 136d98399f83c6a0a16a2a09076486200584fcc6 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 3 Feb 2022 14:31:23 -0800 Subject: [PATCH 099/100] [AD-522] resolve build errors after merge * fix bug for schema name not correctly loaded on the config window * removed unnecessary headers --- .../odbc/system/ui/dsn_configuration_window.h | 4 ---- .../src/system/ui/dsn_configuration_window.cpp | 2 +- src/odbc/src/config/configuration.cpp | 1 + .../src/config/connection_string_parser.cpp | 18 ++++++++---------- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h index 0e554314b..787e34a1b 100644 --- a/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h +++ b/src/odbc/include/ignite/odbc/system/ui/dsn_configuration_window.h @@ -20,10 +20,6 @@ #include "ignite/odbc/config/configuration.h" #include "ignite/odbc/system/ui/custom_window.h" -// TODO: Removed these from configuration.h since no longer used. Moved here since they are still referenced. Remove when no longer needed. -#include "ignite/odbc/nested_tx_mode.h" -#include "ignite/odbc/protocol_version.h" -#include "ignite/odbc/ssl_mode.h" namespace ignite { diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 4092e36b4..89d595b2f 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -384,7 +384,7 @@ namespace ignite rowPos += INTERVAL + ROW_HEIGHT; - val = config.GetDatabase().c_str(); + val = config.GetSchemaName().c_str(); schemaLabel = CreateLabel(labelPosX, rowPos, LABEL_WIDTH, ROW_HEIGHT, "Schema Name:", ChildId::SCHEMA_LABEL); schemaEdit = CreateEdit(editPosX, rowPos, editSizeX, ROW_HEIGHT, val, ChildId::SCHEMA_EDIT); diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 041636851..2ee47fd9b 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -52,6 +52,7 @@ namespace ignite const bool Configuration::DefaultValue::refreshSchema = false; // Internal SSH Tunnel options + const bool Configuration::DefaultValue::sshEnable = false; const std::string Configuration::DefaultValue::sshUser = ""; const std::string Configuration::DefaultValue::sshHost = ""; const std::string Configuration::DefaultValue::sshPrivateKeyFile = ""; diff --git a/src/odbc/src/config/connection_string_parser.cpp b/src/odbc/src/config/connection_string_parser.cpp index d3b5ef831..7c1df403d 100644 --- a/src/odbc/src/config/connection_string_parser.cpp +++ b/src/odbc/src/config/connection_string_parser.cpp @@ -338,23 +338,21 @@ namespace ignite } else if (lKey == Key::sshEnable) { - BoolParseResult::Type res = StringToBool(value); - if (res == BoolParseResult::AI_UNRECOGNIZED) { - if (diag) { - diag->AddStatusRecord( - SqlState::S01S02_OPTION_VALUE_CHANGED, - MakeErrorMessage("Unrecognized bool value. " - "Using default value.", - key, value)); + if (res == BoolParseResult::Type::AI_UNRECOGNIZED) + { + if (diag) + { + diag->AddStatusRecord(SqlState::S01S02_OPTION_VALUE_CHANGED, + MakeErrorMessage("Unrecognized bool value. Using default value.", key, value)); } return; } - cfg.SetSshEnable(res == BoolParseResult::AI_TRUE); - } + cfg.SetSshEnable(res == BoolParseResult::Type::AI_TRUE); + } else if (lKey == Key::sshUser) { cfg.SetSshUser(value); From e8288bfaf15aafeb4a48b7701da9f8ffcc5ac711 Mon Sep 17 00:00:00 2001 From: "Alina (Xi) Li" Date: Thu, 3 Feb 2022 15:12:37 -0800 Subject: [PATCH 100/100] [AD-522] address code review comments * change to enum class type for read_preference.h and scan_method.h * change the way enum class objects are read * add static cast to enum types so SetSelection function can work with it * refactor - removed unnecessary comments * refactor - changes code doc in connection_string_parser.h --- .../ignite/odbc/config/connection_string_parser.h | 4 ++-- src/odbc/include/ignite/odbc/read_preference.h | 2 +- src/odbc/include/ignite/odbc/scan_method.h | 2 +- .../win/src/system/ui/dsn_configuration_window.cpp | 14 +++++++------- src/odbc/src/config/configuration.cpp | 2 -- 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/odbc/include/ignite/odbc/config/connection_string_parser.h b/src/odbc/include/ignite/odbc/config/connection_string_parser.h index a7702f185..4ee17f403 100644 --- a/src/odbc/include/ignite/odbc/config/connection_string_parser.h +++ b/src/odbc/include/ignite/odbc/config/connection_string_parser.h @@ -83,10 +83,10 @@ namespace ignite /** Connection attribute keyword for tlsCaFile attribute. */ static const std::string tlsCaFile; - /** Connection attribute keyword for ssh enable attribute. */ + /** Connection attribute keyword for sshEnable attribute. */ static const std::string sshEnable; - /** Connection attribute keyword for password attribute. */ + /** Connection attribute keyword for sshUser attribute. */ static const std::string sshUser; /** Connection attribute keyword for sshHost attribute. */ diff --git a/src/odbc/include/ignite/odbc/read_preference.h b/src/odbc/include/ignite/odbc/read_preference.h index a05916eab..8b71b8f4f 100644 --- a/src/odbc/include/ignite/odbc/read_preference.h +++ b/src/odbc/include/ignite/odbc/read_preference.h @@ -26,7 +26,7 @@ namespace ignite /** Read Preference enum. */ struct ReadPreference { - enum Type + enum class Type { PRIMARY, PRIMARY_PREFERRED, diff --git a/src/odbc/include/ignite/odbc/scan_method.h b/src/odbc/include/ignite/odbc/scan_method.h index 70b24b835..a7c73c52e 100644 --- a/src/odbc/include/ignite/odbc/scan_method.h +++ b/src/odbc/include/ignite/odbc/scan_method.h @@ -26,7 +26,7 @@ namespace ignite /** Scan method enum. */ struct ScanMethod { - enum Type + enum class Type { RANDOM, ID_FORWARD, diff --git a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp index 89d595b2f..55627a66d 100644 --- a/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp +++ b/src/odbc/os/win/src/system/ui/dsn_configuration_window.cpp @@ -369,7 +369,7 @@ namespace ignite scanMethodComboBox->AddString("ID Reverse"); scanMethodComboBox->AddString("All"); - scanMethodComboBox->SetSelection(scanMethod); // set default + scanMethodComboBox->SetSelection(static_cast(scanMethod)); // set default rowPos += INTERVAL + ROW_HEIGHT; @@ -402,8 +402,8 @@ namespace ignite std::string scanMethodStr; scanMethodComboBox->GetText(scanMethodStr); if (ScanMethod::FromString(scanMethodStr, - ScanMethod::UNKNOWN) - == ScanMethod::ALL) { + ScanMethod::Type::UNKNOWN) + == ScanMethod::Type::ALL) { scanLimitEdit->SetEnabled(false); } else { scanLimitEdit->SetEnabled(true); @@ -447,7 +447,7 @@ namespace ignite readPreferenceComboBox->AddString("Secondary Preferred"); readPreferenceComboBox->AddString("Nearest"); - readPreferenceComboBox->SetSelection(readPreference); // set default + readPreferenceComboBox->SetSelection(static_cast(readPreference)); // set default rowPos += INTERVAL + ROW_HEIGHT; @@ -613,8 +613,8 @@ namespace ignite std::string scanMethodStr; scanMethodComboBox->GetText(scanMethodStr); if (ScanMethod::FromString( - scanMethodStr, ScanMethod::UNKNOWN) - == ScanMethod::ALL) + scanMethodStr, ScanMethod::Type::UNKNOWN) + == ScanMethod::Type::ALL) { scanLimitEdit->SetEnabled(false); } @@ -783,7 +783,7 @@ namespace ignite LOG_MSG("Refresh schema: " << (refreshSchema ? "true" : "false")); ScanMethod::Type scanMethod = - ScanMethod::FromString(scanMethodStr, ScanMethod::UNKNOWN); + ScanMethod::FromString(scanMethodStr, ScanMethod::Type::UNKNOWN); cfg.SetScanMethod(scanMethod); cfg.SetSchemaName(schemaStr); diff --git a/src/odbc/src/config/configuration.cpp b/src/odbc/src/config/configuration.cpp index 2ee47fd9b..37275eb9c 100644 --- a/src/odbc/src/config/configuration.cpp +++ b/src/odbc/src/config/configuration.cpp @@ -14,7 +14,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -// configures for what is defined in .h .h has a lot of setable values, replaces with DocumentDB properties. #include #include #include @@ -33,7 +32,6 @@ namespace ignite // Connection Settings const std::string Configuration::DefaultValue::dsn = "DocumentDB DSN"; const std::string Configuration::DefaultValue::driver = "Amazon DocumentDB ODBC Driver"; - // driver does not need to be added in config window since it is chosen at the Data Source Administrator const std::string Configuration::DefaultValue::database = ""; const std::string Configuration::DefaultValue::hostname = ""; const uint16_t Configuration::DefaultValue::port = 27017;